Annotation of sys/xfs/xfs_vfsops-bsd.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-bsd.c,v 1.72 2002/12/19 10:30:17 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_vfsops.h>
48: #include <xfs/xfs_vfsops-bsd.h>
49: #include <xfs/xfs_vnodeops.h>
50:
51: int
52: xfs_mount_caddr(struct mount *mp,
53: const char *user_path,
54: caddr_t user_data,
55: struct nameidata *ndp,
56: d_thread_t *p)
57: {
58: return xfs_mount_common(mp, user_path, user_data, ndp, p);
59: }
60:
61: int
62: xfs_start(struct mount * mp, int flags, d_thread_t * p)
63: {
64: NNPFSDEB(XDEBVFOPS, ("xfs_start mp = %lx, flags = %d, proc = %lx\n",
65: (unsigned long)mp, flags, (unsigned long)p));
66: return 0;
67: }
68:
69:
70: int
71: xfs_unmount(struct mount * mp, int mntflags, d_thread_t *p)
72: {
73: NNPFSDEB(XDEBVFOPS, ("xfs_umount: mp = %lx, mntflags = %d, proc = %lx\n",
74: (unsigned long)mp, mntflags, (unsigned long)p));
75: return xfs_unmount_common(mp, mntflags);
76: }
77:
78: int
79: xfs_root(struct mount *mp, struct vnode **vpp)
80: {
81: NNPFSDEB(XDEBVFOPS, ("xfs_root mp = %lx\n", (unsigned long)mp));
82: #ifdef HAVE_FREEBSD_THREAD
83: return xfs_root_common(mp, vpp, xfs_curthread(), xfs_curthread()->td_proc->p_ucred);
84: #else
85: return xfs_root_common(mp, vpp, xfs_curproc(), xfs_curproc()->p_ucred);
86: #endif
87: }
88:
89: int
90: xfs_quotactl(struct mount *mp, int cmd, uid_t uid, caddr_t arg, d_thread_t *p)
91: {
92: NNPFSDEB(XDEBVFOPS, ("xfs_quotactl: mp = %lx, cmd = %d, uid = %u, "
93: "arg = %lx, proc = %lx\n",
94: (unsigned long)mp, cmd, uid,
95: (unsigned long)arg, (unsigned long)p));
96: return EOPNOTSUPP;
97: }
98:
99: int
100: xfs_statfs(struct mount *mp, struct statfs *sbp, d_thread_t *p)
101: {
102: NNPFSDEB(XDEBVFOPS, ("xfs_statfs: mp = %lx, sbp = %lx, proc = %lx\n",
103: (unsigned long)mp,
104: (unsigned long)sbp,
105: (unsigned long)p));
106: bcopy(&mp->mnt_stat, sbp, sizeof(*sbp));
107: return 0;
108: }
109:
110: int
111: xfs_sync(struct mount *mp, int waitfor, struct ucred *cred, d_thread_t *p)
112: {
113: NNPFSDEB(XDEBVFOPS, ("xfs_sync: mp = %lx, waitfor = %d, "
114: "cred = %lx, proc = %lx\n",
115: (unsigned long)mp,
116: waitfor,
117: (unsigned long)cred,
118: (unsigned long)p));
119: return 0;
120: }
121:
122: int
123: xfs_vget(struct mount * mp,
124: #ifdef __APPLE__
125: void *ino,
126: #else
127: ino_t ino,
128: #endif
129: struct vnode ** vpp)
130: {
131: NNPFSDEB(XDEBVFOPS, ("xfs_vget\n"));
132: return EOPNOTSUPP;
133: }
134:
135: static int
136: common_fhtovp(struct mount * mp,
137: struct fid * fhp,
138: struct vnode ** vpp)
139: {
140: #ifdef ARLA_KNFS
141: struct netcred *np = NULL;
142: struct xfs_node *xn;
143: struct vnode *vp;
144: xfs_handle handle;
145: int error;
146:
147: NNPFSDEB(XDEBVFOPS, ("xfs_fhtovp\n"));
148:
149: if (fhp->fid_len != 16) {
150: printf("xfs_fhtovp: *PANIC* got a invalid length of a fid\n");
151: return EINVAL;
152: }
153:
154: memcpy(&handle, fhp->fid_data, sizeof(handle));
155: NNPFSDEB(XDEBVFOPS, ("xfs_fhtovp: fid: %d.%d.%d.%d\n",
156: handle.a, handle.d, handle.c, handle.d));
157:
158: NNPFSDEB(XDEBVFOPS, ("xfs_fhtovp: xfs_vnode_find\n"));
159: xn = xfs_node_find(&xfs[0].nodehead, &handle);
160:
161: if (xn == NULL) {
162: struct xfs_message_getattr msg;
163:
164: error = xfs_getnewvnode(xfs[0].mp, &vp, &handle);
165: if (error)
166: return error;
167:
168: xfs_do_vget(vp, 0, curproc);
169:
170: } else {
171: /* XXX access ? */
172: vp = XNODE_TO_VNODE(xn);
173:
174: /* XXX wrong ? (we tell arla below) */
175: if (vp->v_usecount <= 0)
176: xfs_do_vget(vp, 0, curproc);
177: else
178: VREF(vp);
179: error = 0;
180: }
181:
182: *vpp = vp;
183:
184: if (error == 0) {
185: NNPFSDEB(XDEBVFOPS, ("xfs_fhtovp done\n"));
186:
187: /*
188: * XXX tell arla about this node is hold by nfsd.
189: * There need to be code in xfs_write too.
190: */
191: } else
192: NNPFSDEB(XDEBVFOPS, ("xfs_fhtovp failed (%d)\n", error));
193:
194: return error;
195: #else /* !ARLA_KNFS */
196: return EOPNOTSUPP;
197: #endif /* !ARLA_KNFS */
198: }
199:
200: /* new style fhtovp */
201:
202: #ifdef HAVE_STRUCT_VFSOPS_VFS_CHECKEXP
203: int
204: xfs_fhtovp(struct mount * mp,
205: struct fid * fhp,
206: struct vnode ** vpp)
207: {
208: return common_fhtovp (mp, fhp, vpp);
209: }
210:
211: #else /* !HAVE_STRUCT_VFSOPS_VFS_CHECKEXP */
212:
213: /* old style fhtovp */
214:
215: int
216: xfs_fhtovp(struct mount * mp,
217: struct fid * fhp,
218: struct mbuf * nam,
219: struct vnode ** vpp,
220: int *exflagsp,
221: struct ucred ** credanonp)
222: {
223: static struct ucred fhtovpcred;
224: int error;
225:
226: /* XXX: Should see if we is exported to this client */
227: #if 0
228: np = vfs_export_lookup(mp, &ump->um_export, nam);
229: if (np == NULL)
230: return EACCES;
231: #endif
232: error = common_fhtovp(mp, fhp, vpp);
233: if (error == 0) {
234: fhtovpcred.cr_uid = 0;
235: fhtovpcred.cr_gid = 0;
236: fhtovpcred.cr_ngroups = 0;
237:
238: #ifdef MNT_EXPUBLIC
239: *exflagsp = MNT_EXPUBLIC;
240: #else
241: *exflagsp = 0;
242: #endif
243: *credanonp = &fhtovpcred;
244: }
245: return error;
246: }
247: #endif /* !HAVE_STRUCT_VFSOPS_VFS_CHECKEXP */
248:
249: int
250: xfs_checkexp (struct mount *mp,
251: #ifdef __FreeBSD__
252: struct sockaddr *nam,
253: #else
254: struct mbuf *nam,
255: #endif
256: int *exflagsp,
257: struct ucred **credanonp)
258: {
259: NNPFSDEB(XDEBVFOPS, ("xfs_checkexp\n"));
260:
261: #if 0
262: np = vfs_export_lookup(mp, &ump->um_export, nam);
263: if (np == NULL)
264: return EACCES;
265: #endif
266: return 0;
267: }
268:
269: int
270: xfs_vptofh(struct vnode * vp,
271: struct fid * fhp)
272: {
273: #ifdef ARLA_KNFS
274: struct xfs_node *xn;
275: NNPFSDEB(XDEBVFOPS, ("xfs_vptofh\n"));
276:
277: if (MAXFIDSZ < 16)
278: return EOPNOTSUPP;
279:
280: xn = VNODE_TO_XNODE(vp);
281:
282: if (xn == NULL)
283: return EINVAL;
284:
285: fhp->fid_len = 16;
286: memcpy(fhp->fid_data, &xn->handle, 16);
287:
288: return 0;
289: #else
290: NNPFSDEB(XDEBVFOPS, ("xfs_vptofh\n"));
291: return EOPNOTSUPP;
292: #endif
293: }
294:
295: /*
296: * xfs complete dead vnodes implementation.
297: *
298: * this is because the dead_vnodeops_p is _not_ filesystem, but rather
299: * a part of the vfs-layer.
300: */
301:
302: int
303: xfs_dead_lookup(struct vop_lookup_args * ap)
304: /* struct vop_lookup_args {
305: struct vnodeop_desc *a_desc;
306: struct vnode *a_dvp;
307: struct vnode **a_vpp;
308: struct componentname *a_cnp;
309: }; */
310: {
311: *ap->a_vpp = NULL;
312: return ENOTDIR;
313: }
314:
315: /*
316: * Given `fsid', `fileid', and `gen', return in `vpp' a locked and
317: * ref'ed vnode from that file system with that id and generation.
318: * All is done in the context of `proc'. Returns 0 if successful, and
319: * error otherwise.
320: */
321:
322: int
323: xfs_fhlookup (d_thread_t *proc,
324: struct xfs_fhandle_t *fhp,
325: struct vnode **vpp)
326: {
327: int error;
328: struct mount *mp;
329: #if !(defined(HAVE_GETFH) && defined(HAVE_FHOPEN))
330: struct ucred *cred = proc->p_ucred;
331: struct vattr vattr;
332: fsid_t fsid;
333: struct xfs_fh_args *fh_args = (struct xfs_fh_args *)fhp->fhdata;
334:
335: NNPFSDEB(XDEBVFOPS, ("xfs_fhlookup (xfs)\n"));
336:
337: error = xfs_suser (proc);
338: if (error)
339: return EPERM;
340:
341: if (fhp->len < sizeof(struct xfs_fh_args))
342: return EINVAL;
343:
344: fsid = SCARG(fh_args, fsid);
345:
346: mp = xfs_vfs_getvfs (&fsid);
347: if (mp == NULL)
348: return ENXIO;
349:
350: #ifdef __APPLE__
351: {
352: uint32_t ino = SCARG(fh_args, fileid);
353: error = VFS_VGET(mp, &ino, vpp);
354: }
355: #else
356: error = VFS_VGET(mp, SCARG(fh_args, fileid), vpp);
357: #endif
358:
359: if (error)
360: return error;
361:
362: if (*vpp == NULL)
363: return ENOENT;
364:
365: error = VOP_GETATTR(*vpp, &vattr, cred, proc);
366: if (error) {
367: vput(*vpp);
368: return error;
369: }
370:
371: if (vattr.va_gen != SCARG(fh_args, gen)) {
372: vput(*vpp);
373: return ENOENT;
374: }
375: #else /* HAVE_GETFH && HAVE_FHOPEN */
376: {
377: fhandle_t *fh = (fhandle_t *) fhp;
378:
379: NNPFSDEB(XDEBVFOPS, ("xfs_fhlookup (native)\n"));
380:
381: mp = xfs_vfs_getvfs (&fh->fh_fsid);
382: if (mp == NULL)
383: return ESTALE;
384:
385: if ((error = VFS_FHTOVP(mp, &fh->fh_fid, vpp)) != 0) {
386: *vpp = NULL;
387: return error;
388: }
389: }
390: #endif /* HAVE_GETFH && HAVE_FHOPEN */
391:
392: #ifdef HAVE_KERNEL_VFS_OBJECT_CREATE
393: if ((*vpp)->v_type == VREG && (*vpp)->v_object == NULL)
394: #ifdef HAVE_FREEBSD_THREAD
395: xfs_vfs_object_create (*vpp, proc, proc->td_proc->p_ucred);
396: #else
397: xfs_vfs_object_create (*vpp, proc, proc->p_ucred);
398: #endif
399: #elif __APPLE__
400: if ((*vpp)->v_type == VREG && (!UBCINFOEXISTS(*vpp))) {
401: ubc_info_init(*vpp);
402: }
403: ubc_hold(*vpp);
404: #endif
405: return 0;
406: }
407:
408:
409:
410: /*
411: * Perform an open operation on the vnode identified by a `xfs_fhandle_t'
412: * (see xfs_fhlookup) with flags `user_flags'. Returns 0 or
413: * error. If successful, the file descriptor is returned in `retval'.
414: */
415:
416: extern struct fileops vnops; /* sometimes declared in <file.h> */
417:
418: int
419: xfs_fhopen (d_thread_t *proc,
420: struct xfs_fhandle_t *fhp,
421: int user_flags,
422: register_t *retval)
423: {
424: int error;
425: struct vnode *vp;
426: #ifdef HAVE_FREEBSD_THREAD
427: struct ucred *cred = proc->td_proc->p_ucred;
428: #else
429: struct ucred *cred = proc->p_ucred;
430: #endif
431: int flags = FFLAGS(user_flags);
432: int index;
433: struct file *fp;
434: int mode;
435: struct xfs_fhandle_t fh;
436:
437: NNPFSDEB(XDEBVFOPS, ("xfs_fhopen: flags = %d\n", user_flags));
438:
439: error = copyin (fhp, &fh, sizeof(fh));
440: if (error)
441: return error;
442:
443: error = xfs_fhlookup (proc, &fh, &vp);
444: NNPFSDEB(XDEBVFOPS, ("xfs_fhlookup returned %d\n", error));
445: if (error)
446: return error;
447:
448: switch (vp->v_type) {
449: case VDIR :
450: case VREG :
451: break;
452: case VLNK :
453: error = EMLINK;
454: goto out;
455: default :
456: error = EOPNOTSUPP;
457: goto out;
458: }
459:
460: mode = 0;
461: if (flags & FWRITE) {
462: switch (vp->v_type) {
463: case VREG :
464: break;
465: case VDIR :
466: error = EISDIR;
467: goto out;
468: default :
469: error = EOPNOTSUPP;
470: goto out;
471: }
472:
473: error = vn_writechk (vp);
474: if (error)
475: goto out;
476:
477: mode |= VWRITE;
478: }
479: if (flags & FREAD)
480: mode |= VREAD;
481:
482: if (mode) {
483: error = VOP_ACCESS(vp, mode, cred, proc);
484: if (error)
485: goto out;
486: }
487:
488: error = VOP_OPEN(vp, flags, cred, proc);
489: if (error)
490: goto out;
491:
492: error = falloc(proc, &fp, &index);
493: if (error)
494: goto out;
495:
496: if (flags & FWRITE)
497: vp->v_writecount++;
498:
499: #if defined(__FreeBSD_version) && __FreeBSD_version >= 300000
500: if (vp->v_type == VREG) {
501: #ifdef HAVE_FREEBSD_THREAD
502: error = xfs_vfs_object_create(vp, proc, proc->td_proc->p_ucred);
503: #else
504: error = xfs_vfs_object_create(vp, proc, proc->p_ucred);
505: #endif
506: if (error)
507: goto out;
508: }
509: #endif
510:
511: fp->f_flag = flags & FMASK;
512: fp->f_type = DTYPE_VNODE;
513: fp->f_ops = &vnops;
514: fp->f_data = (caddr_t)vp;
515: xfs_vfs_unlock(vp, proc);
516: *retval = index;
517: #ifdef FILE_UNUSE
518: FILE_UNUSE(fp, proc);
519: #endif
520: #ifdef __APPLE__
521: *fdflags(proc, index) &= ~UF_RESERVED;
522: #endif
523: return 0;
524: out:
525: NNPFSDEB(XDEBVFOPS, ("xfs_fhopen: error = %d\n", error));
526: vput(vp);
527: return error;
528: }
CVSweb