Annotation of sys/xfs/xfs_vfsops-common.c, Revision 1.1.1.1
1.1 nbrk 1: /*
2: * Copyright (c) 1995 - 2002 Kungliga Tekniska Högskolan
3: * (Royal Institute of Technology, Stockholm, Sweden).
4: * All rights reserved.
5: *
6: * Redistribution and use in source and binary forms, with or without
7: * modification, are permitted provided that the following conditions
8: * are met:
9: *
10: * 1. Redistributions of source code must retain the above copyright
11: * notice, this list of conditions and the following disclaimer.
12: *
13: * 2. Redistributions in binary form must reproduce the above copyright
14: * notice, this list of conditions and the following disclaimer in the
15: * documentation and/or other materials provided with the distribution.
16: *
17: * 3. Neither the name of the Institute nor the names of its contributors
18: * may be used to endorse or promote products derived from this software
19: * without specific prior written permission.
20: *
21: * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24: * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31: * SUCH DAMAGE.
32: */
33:
34: #include <xfs/xfs_locl.h>
35:
36: RCSID("$arla: xfs_vfsops-common.c,v 1.40 2003/06/02 18:26:40 lha Exp $");
37:
38: /*
39: * NNPFS vfs operations.
40: */
41:
42: #include <xfs/xfs_common.h>
43: #include <xfs/xfs_message.h>
44: #include <xfs/xfs_fs.h>
45: #include <xfs/xfs_dev.h>
46: #include <xfs/xfs_deb.h>
47: #include <xfs/xfs_syscalls.h>
48: #include <xfs/xfs_vfsops.h>
49:
50: #ifdef HAVE_KERNEL_UDEV2DEV
51: #define VA_RDEV_TO_DEV(x) udev2dev(x, 0) /* XXX what is the 0 */
52: #else
53: #define VA_RDEV_TO_DEV(x) x
54: #endif
55:
56:
57: struct xfs xfs[NNNPFS];
58:
59: /*
60: * path and data is in system memory
61: */
62:
63: int
64: xfs_mount_common_sys(struct mount *mp,
65: const char *path,
66: void *data,
67: struct nameidata *ndp,
68: d_thread_t *p)
69: {
70: struct vnode *devvp;
71: dev_t dev;
72: int error;
73: struct vattr vat;
74:
75: NNPFSDEB(XDEBVFOPS, ("xfs_mount: "
76: "struct mount mp = %lx path = '%s' data = '%s'\n",
77: (unsigned long)mp, path, (char *)data));
78:
79: #ifdef ARLA_KNFS
80: NNPFSDEB(XDEBVFOPS, ("xfs_mount: mount flags = %x\n", mp->mnt_flag));
81:
82: /*
83: * mountd(8) flushes all export entries when it starts
84: * right now we ignore it (but should not)
85: */
86:
87: if (mp->mnt_flag & MNT_UPDATE ||
88: mp->mnt_flag & MNT_DELEXPORT) {
89:
90: NNPFSDEB(XDEBVFOPS,
91: ("xfs_mount: ignoreing MNT_UPDATE or MNT_DELEXPORT\n"));
92: return 0;
93: }
94: #endif
95:
96: NDINIT(ndp, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, data, p);
97: error = namei(ndp);
98: if (error) {
99: NNPFSDEB(XDEBVFOPS, ("namei failed, errno = %d\n", error));
100: return error;
101: }
102:
103: devvp = ndp->ni_vp;
104:
105: if (devvp->v_type != VCHR) {
106: vput(devvp);
107: NNPFSDEB(XDEBVFOPS, ("not VCHR (%d)\n", devvp->v_type));
108: return ENXIO;
109: }
110: #if defined(__osf__)
111: VOP_GETATTR(devvp, &vat, ndp->ni_cred, error);
112: #elif defined(HAVE_FREEBSD_THREAD)
113: error = VOP_GETATTR(devvp, &vat, p->td_proc->p_ucred, p);
114: #else
115: error = VOP_GETATTR(devvp, &vat, p->p_ucred, p);
116: #endif
117: vput(devvp);
118: if (error) {
119: NNPFSDEB(XDEBVFOPS, ("VOP_GETATTR failed, error = %d\n", error));
120: return error;
121: }
122:
123: dev = VA_RDEV_TO_DEV(vat.va_rdev);
124:
125: NNPFSDEB(XDEBVFOPS, ("dev = %d.%d\n", major(dev), minor(dev)));
126:
127: if (!xfs_is_xfs_dev (dev)) {
128: NNPFSDEB(XDEBVFOPS, ("%s is not a xfs device\n", (char *)data));
129: return ENXIO;
130: }
131:
132: if (xfs[minor(dev)].status & NNPFS_MOUNTED)
133: return EBUSY;
134:
135: xfs[minor(dev)].status = NNPFS_MOUNTED;
136: xfs[minor(dev)].mp = mp;
137: xfs[minor(dev)].root = 0;
138: xfs[minor(dev)].nnodes = 0;
139: xfs[minor(dev)].fd = minor(dev);
140:
141: nnfs_init_head(&xfs[minor(dev)].nodehead);
142:
143: VFS_TO_NNPFS(mp) = &xfs[minor(dev)];
144: #if defined(HAVE_KERNEL_VFS_GETNEWFSID)
145: #if defined(HAVE_TWO_ARGUMENT_VFS_GETNEWFSID)
146: vfs_getnewfsid(mp, MOUNT_AFS);
147: #else
148: vfs_getnewfsid(mp);
149: #endif /* HAVE_TWO_ARGUMENT_VFS_GETNEWFSID */
150: #endif /* HAVE_KERNEL_VFS_GETNEWFSID */
151:
152: mp->mnt_stat.f_bsize = DEV_BSIZE;
153: #ifndef __osf__
154: mp->mnt_stat.f_iosize = DEV_BSIZE;
155: mp->mnt_stat.f_owner = 0;
156: #endif
157: mp->mnt_stat.f_blocks = 4711 * 4711;
158: mp->mnt_stat.f_bfree = 4711 * 4711;
159: mp->mnt_stat.f_bavail = 4711 * 4711;
160: mp->mnt_stat.f_files = 4711;
161: mp->mnt_stat.f_ffree = 4711;
162: mp->mnt_stat.f_flags = mp->mnt_flag;
163:
164: #ifdef __osf__
165: mp->mnt_stat.f_fsid.val[0] = dev;
166: mp->mnt_stat.f_fsid.val[1] = MOUNT_NNPFS;
167:
168: MALLOC(mp->m_stat.f_mntonname, char *, strlen(path) + 1,
169: M_PATHNAME, M_WAITOK);
170: strcpy(mp->m_stat.f_mntonname, path);
171:
172: MALLOC(mp->m_stat.f_mntfromname, char *, sizeof("arla"),
173: M_PATHNAME, M_WAITOK);
174: strcpy(mp->m_stat.f_mntfromname, "arla");
175: #else /* __osf__ */
176: strncpy(mp->mnt_stat.f_mntonname,
177: path,
178: sizeof(mp->mnt_stat.f_mntonname));
179:
180: strncpy(mp->mnt_stat.f_mntfromname,
181: data,
182: sizeof(mp->mnt_stat.f_mntfromname));
183:
184: strncpy(mp->mnt_stat.f_fstypename,
185: "xfs",
186: sizeof(mp->mnt_stat.f_fstypename));
187: #endif /* __osf__ */
188:
189: return 0;
190: }
191:
192: int
193: xfs_mount_common(struct mount *mp,
194: const char *user_path,
195: void *user_data,
196: struct nameidata *ndp,
197: d_thread_t *p)
198: {
199: char *path = NULL;
200: char *data = NULL;
201: size_t count;
202: int error = 0;
203:
204: data = malloc(MAXPATHLEN, M_TEMP, M_WAITOK);
205: if (data == NULL) {
206: error = ENOMEM;
207: goto done;
208: }
209: path = malloc(MAXPATHLEN, M_TEMP, M_WAITOK);
210: if (path == NULL) {
211: error = ENOMEM;
212: goto done;
213: }
214:
215: error = copyinstr(user_path, path, MAXPATHLEN, &count);
216: if (error)
217: goto done;
218:
219: error = copyinstr(user_data, data, MAXPATHLEN, &count);
220: if (error)
221: goto done;
222: error = xfs_mount_common_sys (mp, path, data, ndp, p);
223: done:
224: free(data, M_TEMP);
225: free(path, M_TEMP);
226: return(error);
227: }
228:
229: #ifdef HAVE_KERNEL_DOFORCE
230: extern int doforce;
231: #endif
232:
233: int
234: xfs_unmount_common(struct mount *mp, int mntflags)
235: {
236: struct xfs *xfsp = VFS_TO_NNPFS(mp);
237: int flags = 0;
238: int error;
239:
240: if (mntflags & MNT_FORCE) {
241: #ifdef HAVE_KERNEL_DOFORCE
242: if (!doforce)
243: return EINVAL;
244: #endif
245: flags |= FORCECLOSE;
246: }
247:
248: error = free_all_xfs_nodes(xfsp, flags, 1);
249: if (error)
250: return error;
251:
252: xfsp->status = 0;
253: NNPFS_TO_VFS(xfsp) = NULL;
254: return 0;
255: }
256:
257: int
258: xfs_root_common(struct mount *mp, struct vnode **vpp,
259: d_thread_t *proc, struct ucred *cred)
260: {
261: struct xfs *xfsp = VFS_TO_NNPFS(mp);
262: struct xfs_message_getroot msg;
263: int error;
264:
265: do {
266: if (xfsp->root != NULL) {
267: *vpp = XNODE_TO_VNODE(xfsp->root);
268: xfs_do_vget(*vpp, LK_EXCLUSIVE, proc);
269: return 0;
270: }
271: msg.header.opcode = NNPFS_MSG_GETROOT;
272: msg.cred.uid = cred->cr_uid;
273: msg.cred.pag = xfs_get_pag(cred);
274: error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg), proc);
275: if (error == 0)
276: error = ((struct xfs_message_wakeup *) & msg)->error;
277: } while (error == 0);
278: /*
279: * Failed to get message through, need to pretend that all went well
280: * and return a fake dead vnode to be able to unmount.
281: */
282:
283: if ((error = xfs_make_dead_vnode(mp, vpp)))
284: return error;
285:
286: NNPFS_MAKE_VROOT(*vpp);
287: return 0;
288: }
CVSweb