Annotation of sys/xfs/xfs_vfsops-bsd.c, Revision 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