Annotation of kernel/bsd/ufs/lfs/lfs_vfsops.c, revision 1.1.1.2

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;
1.1.1.2 ! root      380: #if QUOTA
1.1       root      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));
1.1.1.2 ! root      468: #if QUOTA
1.1       root      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: }

unix.superglobalmegacorp.com

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