|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. ! 3: * ! 4: * @APPLE_LICENSE_HEADER_START@ ! 5: * ! 6: * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights ! 7: * Reserved. This file contains Original Code and/or Modifications of ! 8: * Original Code as defined in and that are subject to the Apple Public ! 9: * Source License Version 1.1 (the "License"). You may not use this file ! 10: * except in compliance with the License. Please obtain a copy of the ! 11: * License at http://www.apple.com/publicsource and read it before using ! 12: * this file. ! 13: * ! 14: * The Original Code and all software distributed under the License are ! 15: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER ! 16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, ! 17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, ! 18: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the ! 19: * License for the specific language governing rights and limitations ! 20: * under the License. ! 21: * ! 22: * @APPLE_LICENSE_HEADER_END@ ! 23: */ ! 24: ! 25: /* $NetBSD: lfs_vfsops.c,v 1.8 1995/03/09 12:06:10 mycroft Exp $ */ ! 26: ! 27: /* ! 28: * Copyright (c) 1989, 1991, 1993, 1994 ! 29: * The Regents of the University of California. All rights reserved. ! 30: * ! 31: * Redistribution and use in source and binary forms, with or without ! 32: * modification, are permitted provided that the following conditions ! 33: * are met: ! 34: * 1. Redistributions of source code must retain the above copyright ! 35: * notice, this list of conditions and the following disclaimer. ! 36: * 2. Redistributions in binary form must reproduce the above copyright ! 37: * notice, this list of conditions and the following disclaimer in the ! 38: * documentation and/or other materials provided with the distribution. ! 39: * 3. All advertising materials mentioning features or use of this software ! 40: * must display the following acknowledgement: ! 41: * This product includes software developed by the University of ! 42: * California, Berkeley and its contributors. ! 43: * 4. Neither the name of the University nor the names of its contributors ! 44: * may be used to endorse or promote products derived from this software ! 45: * without specific prior written permission. ! 46: * ! 47: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ! 48: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ! 49: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ! 50: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE ! 51: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ! 52: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ! 53: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ! 54: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ! 55: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ! 56: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ! 57: * SUCH DAMAGE. ! 58: * ! 59: * @(#)lfs_vfsops.c 8.10 (Berkeley) 11/21/94 ! 60: */ ! 61: ! 62: #include <sys/param.h> ! 63: #include <sys/systm.h> ! 64: #include <sys/namei.h> ! 65: #include <sys/proc.h> ! 66: #include <sys/kernel.h> ! 67: #include <sys/vnode.h> ! 68: #include <sys/mount.h> ! 69: #include <sys/buf.h> ! 70: #include <sys/mbuf.h> ! 71: #include <sys/file.h> ! 72: #include <sys/disklabel.h> ! 73: #include <sys/ioctl.h> ! 74: #include <sys/errno.h> ! 75: #include <sys/malloc.h> ! 76: #include <sys/socket.h> ! 77: ! 78: #include <miscfs/specfs/specdev.h> ! 79: ! 80: #include <ufs/ufs/quota.h> ! 81: #include <ufs/ufs/inode.h> ! 82: #include <ufs/ufs/ufsmount.h> ! 83: #include <ufs/ufs/ufs_extern.h> ! 84: ! 85: #include <ufs/lfs/lfs.h> ! 86: #include <ufs/lfs/lfs_extern.h> ! 87: ! 88: int lfs_mountfs __P((struct vnode *, struct mount *, struct proc *)); ! 89: ! 90: struct vfsops lfs_vfsops = { ! 91: MOUNT_LFS, ! 92: lfs_mount, ! 93: ufs_start, ! 94: lfs_unmount, ! 95: ufs_root, ! 96: ufs_quotactl, ! 97: lfs_statfs, ! 98: lfs_sync, ! 99: lfs_vget, ! 100: lfs_fhtovp, ! 101: lfs_vptofh, ! 102: lfs_init, ! 103: }; ! 104: ! 105: int ! 106: lfs_mountroot() ! 107: { ! 108: panic("lfs_mountroot"); /* XXX -- implement */ ! 109: } ! 110: ! 111: /* ! 112: * VFS Operations. ! 113: * ! 114: * mount system call ! 115: */ ! 116: lfs_mount(mp, path, data, ndp, p) ! 117: register struct mount *mp; ! 118: char *path; ! 119: caddr_t data; ! 120: struct nameidata *ndp; ! 121: struct proc *p; ! 122: { ! 123: struct vnode *devvp; ! 124: struct ufs_args args; ! 125: struct ufsmount *ump; ! 126: register struct lfs *fs; /* LFS */ ! 127: size_t size; ! 128: int error; ! 129: mode_t accessmode; ! 130: ! 131: if (error = copyin(data, (caddr_t)&args, sizeof (struct ufs_args))) ! 132: return (error); ! 133: ! 134: /* Until LFS can do NFS right. XXX */ ! 135: if (args.export.ex_flags & MNT_EXPORTED) ! 136: return (EINVAL); ! 137: ! 138: /* ! 139: * If updating, check whether changing from read-only to ! 140: * read/write; if there is no device name, that's all we do. ! 141: */ ! 142: if (mp->mnt_flag & MNT_UPDATE) { ! 143: ump = VFSTOUFS(mp); ! 144: if (fs->lfs_ronly && (mp->mnt_flag & MNT_WANTRDWR)) { ! 145: /* ! 146: * If upgrade to read-write by non-root, then verify ! 147: * that user has necessary permissions on the device. ! 148: */ ! 149: if (p->p_ucred->cr_uid != 0) { ! 150: VOP_LOCK(ump->um_devvp); ! 151: if (error = VOP_ACCESS(ump->um_devvp, ! 152: VREAD | VWRITE, p->p_ucred, p)) { ! 153: VOP_UNLOCK(ump->um_devvp); ! 154: return (error); ! 155: } ! 156: VOP_UNLOCK(ump->um_devvp); ! 157: } ! 158: fs->lfs_ronly = 0; ! 159: } ! 160: if (args.fspec == 0) { ! 161: /* ! 162: * Process export requests. ! 163: */ ! 164: return (vfs_export(mp, &ump->um_export, &args.export)); ! 165: } ! 166: } ! 167: /* ! 168: * Not an update, or updating the name: look up the name ! 169: * and verify that it refers to a sensible block device. ! 170: */ ! 171: NDINIT(ndp, LOOKUP, FOLLOW, UIO_USERSPACE, args.fspec, p); ! 172: if (error = namei(ndp)) ! 173: return (error); ! 174: devvp = ndp->ni_vp; ! 175: if (devvp->v_type != VBLK) { ! 176: vrele(devvp); ! 177: return (ENOTBLK); ! 178: } ! 179: if (major(devvp->v_rdev) >= nblkdev) { ! 180: vrele(devvp); ! 181: return (ENXIO); ! 182: } ! 183: /* ! 184: * If mount by non-root, then verify that user has necessary ! 185: * permissions on the device. ! 186: */ ! 187: if (p->p_ucred->cr_uid != 0) { ! 188: accessmode = VREAD; ! 189: if ((mp->mnt_flag & MNT_RDONLY) == 0) ! 190: accessmode |= VWRITE; ! 191: VOP_LOCK(devvp); ! 192: if (error = VOP_ACCESS(devvp, accessmode, p->p_ucred, p)) { ! 193: vput(devvp); ! 194: return (error); ! 195: } ! 196: VOP_UNLOCK(devvp); ! 197: } ! 198: if ((mp->mnt_flag & MNT_UPDATE) == 0) ! 199: error = lfs_mountfs(devvp, mp, p); /* LFS */ ! 200: else { ! 201: if (devvp != ump->um_devvp) ! 202: error = EINVAL; /* needs translation */ ! 203: else ! 204: vrele(devvp); ! 205: } ! 206: if (error) { ! 207: vrele(devvp); ! 208: return (error); ! 209: } ! 210: ump = VFSTOUFS(mp); ! 211: fs = ump->um_lfs; /* LFS */ ! 212: #ifdef NOTLFS /* LFS */ ! 213: (void) copyinstr(path, fs->fs_fsmnt, sizeof(fs->fs_fsmnt) - 1, &size); ! 214: bzero(fs->fs_fsmnt + size, sizeof(fs->fs_fsmnt) - size); ! 215: bcopy(fs->fs_fsmnt, mp->mnt_stat.f_mntonname, MNAMELEN); ! 216: #else ! 217: (void)copyinstr(path, fs->lfs_fsmnt, sizeof(fs->lfs_fsmnt) - 1, &size); ! 218: bzero(fs->lfs_fsmnt + size, sizeof(fs->lfs_fsmnt) - size); ! 219: bcopy(fs->lfs_fsmnt, mp->mnt_stat.f_mntonname, MNAMELEN); ! 220: #endif ! 221: (void) copyinstr(args.fspec, mp->mnt_stat.f_mntfromname, MNAMELEN - 1, ! 222: &size); ! 223: bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size); ! 224: return (0); ! 225: } ! 226: ! 227: /* ! 228: * Common code for mount and mountroot ! 229: * LFS specific ! 230: */ ! 231: int ! 232: lfs_mountfs(devvp, mp, p) ! 233: register struct vnode *devvp; ! 234: struct mount *mp; ! 235: struct proc *p; ! 236: { ! 237: extern struct vnode *rootvp; ! 238: register struct lfs *fs; ! 239: register struct ufsmount *ump; ! 240: struct vnode *vp; ! 241: struct buf *bp; ! 242: struct partinfo dpart; ! 243: dev_t dev; ! 244: int error, i, ronly, size; ! 245: struct ucred *cred; ! 246: ! 247: cred = p ? p->p_ucred : NOCRED; ! 248: /* ! 249: * Disallow multiple mounts of the same device. ! 250: * Disallow mounting of a device that is currently in use ! 251: * (except for root, which might share swap device for miniroot). ! 252: * Flush out any old buffers remaining from a previous use. ! 253: */ ! 254: if (error = vfs_mountedon(devvp)) ! 255: return (error); ! 256: if (vcount(devvp) > 1 && devvp != rootvp) ! 257: return (EBUSY); ! 258: if (error = vinvalbuf(devvp, V_SAVE, cred, p, 0, 0)) ! 259: return (error); ! 260: ! 261: ronly = (mp->mnt_flag & MNT_RDONLY) != 0; ! 262: if (error = VOP_OPEN(devvp, ronly ? FREAD : FREAD|FWRITE, FSCRED, p)) ! 263: return (error); ! 264: ! 265: if (VOP_IOCTL(devvp, DIOCGPART, (caddr_t)&dpart, FREAD, cred, p) != 0) ! 266: size = DEV_BSIZE; ! 267: else { ! 268: size = dpart.disklab->d_secsize; ! 269: #ifdef NEVER_USED ! 270: dpart.part->p_fstype = FS_LFS; ! 271: dpart.part->p_fsize = fs->lfs_fsize; /* frag size */ ! 272: dpart.part->p_frag = fs->lfs_frag; /* frags per block */ ! 273: dpart.part->p_cpg = fs->lfs_segshift; /* segment shift */ ! 274: #endif ! 275: } ! 276: ! 277: /* Don't free random space on error. */ ! 278: bp = NULL; ! 279: ump = NULL; ! 280: ! 281: /* Read in the superblock. */ ! 282: if (error = bread(devvp, LFS_LABELPAD / size, LFS_SBPAD, cred, &bp)) ! 283: goto out; ! 284: fs = (struct lfs *)bp->b_data; ! 285: ! 286: /* Check the basics. */ ! 287: if (fs->lfs_magic != LFS_MAGIC || fs->lfs_bsize > MAXBSIZE || ! 288: fs->lfs_bsize < sizeof(struct lfs)) { ! 289: error = EINVAL; /* XXX needs translation */ ! 290: goto out; ! 291: } ! 292: ! 293: /* Allocate the mount structure, copy the superblock into it. */ ! 294: // ump = (struct ufsmount *)malloc(sizeof *ump, M_UFSMNT, M_WAITOK); ! 295: // fs = ump->um_lfs = malloc(sizeof(struct lfs), M_UFSMNT, M_WAITOK); ! 296: MALLOC(ump, struct ufsmount *, sizeof(struct ufsmount), M_UFSMNT, M_WAITOK); ! 297: MALLOC(ump->um_lfs, struct lfs *, sizeof(struct lfs), M_UFSMNT, M_WAITOK); ! 298: fs = ump->um_lfs; ! 299: bcopy(bp->b_data, fs, sizeof(struct lfs)); ! 300: if (sizeof(struct lfs) < LFS_SBPAD) /* XXX why? */ ! 301: bp->b_flags |= B_INVAL; ! 302: brelse(bp); ! 303: bp = NULL; ! 304: ! 305: /* Set up the I/O information */ ! 306: fs->lfs_iocount = 0; ! 307: ! 308: /* Set up the ifile and lock aflags */ ! 309: fs->lfs_doifile = 0; ! 310: fs->lfs_writer = 0; ! 311: fs->lfs_dirops = 0; ! 312: fs->lfs_seglock = 0; ! 313: ! 314: /* Set the file system readonly/modify bits. */ ! 315: fs->lfs_ronly = ronly; ! 316: if (ronly == 0) ! 317: fs->lfs_fmod = 1; ! 318: ! 319: /* Initialize the mount structure. */ ! 320: dev = devvp->v_rdev; ! 321: mp->mnt_data = (qaddr_t)ump; ! 322: mp->mnt_stat.f_fsid.val[0] = (long)dev; ! 323: mp->mnt_stat.f_fsid.val[1] = makefstype(MOUNT_LFS); ! 324: mp->mnt_maxsymlinklen = fs->lfs_maxsymlinklen; ! 325: mp->mnt_flag |= MNT_LOCAL; ! 326: ump->um_mountp = mp; ! 327: ump->um_dev = dev; ! 328: ump->um_devvp = devvp; ! 329: ump->um_bptrtodb = 0; ! 330: ump->um_seqinc = 1 << fs->lfs_fsbtodb; ! 331: ump->um_nindir = fs->lfs_nindir; ! 332: for (i = 0; i < MAXQUOTAS; i++) ! 333: ump->um_quotas[i] = NULLVP; ! 334: devvp->v_specflags |= SI_MOUNTEDON; ! 335: ! 336: /* ! 337: * We use the ifile vnode for almost every operation. Instead of ! 338: * retrieving it from the hash table each time we retrieve it here, ! 339: * artificially increment the reference count and keep a pointer ! 340: * to it in the incore copy of the superblock. ! 341: */ ! 342: if (error = VFS_VGET(mp, LFS_IFILE_INUM, &vp)) ! 343: goto out; ! 344: fs->lfs_ivnode = vp; ! 345: VREF(vp); ! 346: vput(vp); ! 347: ! 348: return (0); ! 349: out: ! 350: if (bp) ! 351: brelse(bp); ! 352: (void)VOP_CLOSE(devvp, ronly ? FREAD : FREAD|FWRITE, cred, p); ! 353: if (ump) { ! 354: free(ump->um_lfs, M_UFSMNT); ! 355: free(ump, M_UFSMNT); ! 356: mp->mnt_data = (qaddr_t)0; ! 357: } ! 358: return (error); ! 359: } ! 360: ! 361: /* ! 362: * unmount system call ! 363: */ ! 364: lfs_unmount(mp, mntflags, p) ! 365: struct mount *mp; ! 366: int mntflags; ! 367: struct proc *p; ! 368: { ! 369: extern int doforce; ! 370: register struct ufsmount *ump; ! 371: register struct lfs *fs; ! 372: int i, error, flags, ronly; ! 373: ! 374: flags = 0; ! 375: if (mntflags & MNT_FORCE) ! 376: flags |= FORCECLOSE; ! 377: ! 378: ump = VFSTOUFS(mp); ! 379: fs = ump->um_lfs; ! 380: #ifdef QUOTA ! 381: if (mp->mnt_flag & MNT_QUOTA) { ! 382: if (error = vflush(mp, fs->lfs_ivnode, SKIPSYSTEM|flags)) ! 383: return (error); ! 384: for (i = 0; i < MAXQUOTAS; i++) { ! 385: if (ump->um_quotas[i] == NULLVP) ! 386: continue; ! 387: quotaoff(p, mp, i); ! 388: } ! 389: /* ! 390: * Here we fall through to vflush again to ensure ! 391: * that we have gotten rid of all the system vnodes. ! 392: */ ! 393: } ! 394: #endif ! 395: if (error = vflush(mp, fs->lfs_ivnode, flags)) ! 396: return (error); ! 397: fs->lfs_clean = 1; ! 398: if (error = VFS_SYNC(mp, 1, p->p_ucred, p)) ! 399: return (error); ! 400: if (fs->lfs_ivnode->v_dirtyblkhd.lh_first) ! 401: panic("lfs_unmount: still dirty blocks on ifile vnode\n"); ! 402: vrele(fs->lfs_ivnode); ! 403: vgone(fs->lfs_ivnode); ! 404: ! 405: ronly = !fs->lfs_ronly; ! 406: ump->um_devvp->v_specflags &= ~SI_MOUNTEDON; ! 407: error = VOP_CLOSE(ump->um_devvp, ! 408: ronly ? FREAD : FREAD|FWRITE, NOCRED, p); ! 409: vrele(ump->um_devvp); ! 410: free(fs, M_UFSMNT); ! 411: free(ump, M_UFSMNT); ! 412: mp->mnt_data = (qaddr_t)0; ! 413: mp->mnt_flag &= ~MNT_LOCAL; ! 414: return (error); ! 415: } ! 416: ! 417: /* ! 418: * Get file system statistics. ! 419: */ ! 420: lfs_statfs(mp, sbp, p) ! 421: struct mount *mp; ! 422: register struct statfs *sbp; ! 423: struct proc *p; ! 424: { ! 425: register struct lfs *fs; ! 426: register struct ufsmount *ump; ! 427: ! 428: ump = VFSTOUFS(mp); ! 429: fs = ump->um_lfs; ! 430: if (fs->lfs_magic != LFS_MAGIC) ! 431: panic("lfs_statfs: magic"); ! 432: sbp->f_type = 0; ! 433: sbp->f_bsize = fs->lfs_bsize; ! 434: sbp->f_iosize = fs->lfs_bsize; ! 435: sbp->f_blocks = dbtofsb(fs,fs->lfs_dsize); ! 436: sbp->f_bfree = dbtofsb(fs, fs->lfs_bfree); ! 437: sbp->f_bavail = (fs->lfs_dsize * (100 - fs->lfs_minfree) / 100) - ! 438: (fs->lfs_dsize - fs->lfs_bfree); ! 439: sbp->f_bavail = dbtofsb(fs, sbp->f_bavail); ! 440: sbp->f_files = fs->lfs_nfiles; ! 441: sbp->f_ffree = sbp->f_bfree * INOPB(fs); ! 442: if (sbp != &mp->mnt_stat) { ! 443: bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN); ! 444: bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN); ! 445: } ! 446: strncpy(sbp->f_fstypename, mp->mnt_op->vfs_name, MFSNAMELEN); ! 447: sbp->f_fstypename[MFSNAMELEN] = '\0'; ! 448: return (0); ! 449: } ! 450: ! 451: /* ! 452: * Go through the disk queues to initiate sandbagged IO; ! 453: * go through the inodes to write those that have been modified; ! 454: * initiate the writing of the super block if it has been modified. ! 455: * ! 456: * Note: we are always called with the filesystem marked `MPBUSY'. ! 457: */ ! 458: lfs_sync(mp, waitfor, cred, p) ! 459: struct mount *mp; ! 460: int waitfor; ! 461: struct ucred *cred; ! 462: struct proc *p; ! 463: { ! 464: int error; ! 465: ! 466: /* All syncs must be checkpoints until roll-forward is implemented. */ ! 467: error = lfs_segwrite(mp, SEGM_CKP | (waitfor ? SEGM_SYNC : 0)); ! 468: #ifdef QUOTA ! 469: qsync(mp); ! 470: #endif ! 471: return (error); ! 472: } ! 473: ! 474: /* ! 475: * Look up an LFS dinode number to find its incore vnode. If not already ! 476: * in core, read it in from the specified device. Return the inode locked. ! 477: * Detection and handling of mount points must be done by the calling routine. ! 478: */ ! 479: int ! 480: lfs_vget(mp, ino, vpp) ! 481: struct mount *mp; ! 482: ino_t ino; ! 483: struct vnode **vpp; ! 484: { ! 485: register struct lfs *fs; ! 486: register struct inode *ip; ! 487: struct buf *bp; ! 488: struct ifile *ifp; ! 489: struct vnode *vp; ! 490: struct ufsmount *ump; ! 491: daddr_t daddr; ! 492: dev_t dev; ! 493: int error; ! 494: ! 495: ump = VFSTOUFS(mp); ! 496: dev = ump->um_dev; ! 497: if ((*vpp = ufs_ihashget(dev, ino)) != NULL) ! 498: return (0); ! 499: ! 500: /* Translate the inode number to a disk address. */ ! 501: fs = ump->um_lfs; ! 502: if (ino == LFS_IFILE_INUM) ! 503: daddr = fs->lfs_idaddr; ! 504: else { ! 505: LFS_IENTRY(ifp, fs, ino, bp); ! 506: daddr = ifp->if_daddr; ! 507: brelse(bp); ! 508: if (daddr == LFS_UNUSED_DADDR) ! 509: return (ENOENT); ! 510: } ! 511: ! 512: /* Allocate new vnode/inode. */ ! 513: if (error = lfs_vcreate(mp, ino, &vp)) { ! 514: *vpp = NULL; ! 515: return (error); ! 516: } ! 517: ! 518: /* ! 519: * Put it onto its hash chain and lock it so that other requests for ! 520: * this inode will block if they arrive while we are sleeping waiting ! 521: * for old data structures to be purged or for the contents of the ! 522: * disk portion of this inode to be read. ! 523: */ ! 524: ip = VTOI(vp); ! 525: ufs_ihashins(ip); ! 526: ! 527: /* ! 528: * XXX ! 529: * This may not need to be here, logically it should go down with ! 530: * the i_devvp initialization. ! 531: * Ask Kirk. ! 532: */ ! 533: ip->i_lfs = ump->um_lfs; ! 534: ! 535: /* Read in the disk contents for the inode, copy into the inode. */ ! 536: if (error = ! 537: bread(ump->um_devvp, daddr, (int)fs->lfs_bsize, NOCRED, &bp)) { ! 538: /* ! 539: * The inode does not contain anything useful, so it would ! 540: * be misleading to leave it on its hash chain. With mode ! 541: * still zero, it will be unlinked and returned to the free ! 542: * list by vput(). ! 543: */ ! 544: vput(vp); ! 545: brelse(bp); ! 546: *vpp = NULL; ! 547: return (error); ! 548: } ! 549: ip->i_din = *lfs_ifind(fs, ino, (struct dinode *)bp->b_data); ! 550: brelse(bp); ! 551: ! 552: /* ! 553: * Initialize the vnode from the inode, check for aliases. In all ! 554: * cases re-init ip, the underlying vnode/inode may have changed. ! 555: */ ! 556: if (error = ufs_vinit(mp, lfs_specop_p, LFS_FIFOOPS, &vp)) { ! 557: vput(vp); ! 558: *vpp = NULL; ! 559: return (error); ! 560: } ! 561: /* ! 562: * Finish inode initialization now that aliasing has been resolved. ! 563: */ ! 564: ip->i_devvp = ump->um_devvp; ! 565: VREF(ip->i_devvp); ! 566: *vpp = vp; ! 567: return (0); ! 568: } ! 569: ! 570: /* ! 571: * File handle to vnode ! 572: * ! 573: * Have to be really careful about stale file handles: ! 574: * - check that the inode number is valid ! 575: * - call lfs_vget() to get the locked inode ! 576: * - check for an unallocated inode (i_mode == 0) ! 577: * - check that the given client host has export rights and return ! 578: * those rights via. exflagsp and credanonp ! 579: * ! 580: * XXX ! 581: * use ifile to see if inode is allocated instead of reading off disk ! 582: * what is the relationship between my generational number and the NFS ! 583: * generational number. ! 584: */ ! 585: int ! 586: lfs_fhtovp(mp, fhp, nam, vpp, exflagsp, credanonp) ! 587: register struct mount *mp; ! 588: struct fid *fhp; ! 589: struct mbuf *nam; ! 590: struct vnode **vpp; ! 591: int *exflagsp; ! 592: struct ucred **credanonp; ! 593: { ! 594: register struct ufid *ufhp; ! 595: ! 596: ufhp = (struct ufid *)fhp; ! 597: if (ufhp->ufid_ino < ROOTINO) ! 598: return (ESTALE); ! 599: return (ufs_check_export(mp, ufhp, nam, vpp, exflagsp, credanonp)); ! 600: } ! 601: ! 602: /* ! 603: * Vnode pointer to File handle ! 604: */ ! 605: /* ARGSUSED */ ! 606: lfs_vptofh(vp, fhp) ! 607: struct vnode *vp; ! 608: struct fid *fhp; ! 609: { ! 610: register struct inode *ip; ! 611: register struct ufid *ufhp; ! 612: ! 613: ip = VTOI(vp); ! 614: ufhp = (struct ufid *)fhp; ! 615: ufhp->ufid_len = sizeof(struct ufid); ! 616: ufhp->ufid_ino = ip->i_number; ! 617: ufhp->ufid_gen = ip->i_gen; ! 618: return (0); ! 619: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.