Annotation of XNU/bsd/ufs/lfs/lfs_vfsops.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.