[BACK]Return to filecore_vfsops.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / filecorefs

Annotation of src/sys/filecorefs/filecore_vfsops.c, Revision 1.14

1.14    ! mrg         1: /*     $NetBSD: filecore_vfsops.c,v 1.13 2001/01/22 13:32:23 jdolecek Exp $    */
1.1       mark        2:
                      3: /*-
                      4:  * Copyright (c) 1998 Andrew McMurry
                      5:  * Copyright (c) 1994 The Regents of the University of California.
                      6:  * All rights reserved.
                      7:  *
                      8:  * Redistribution and use in source and binary forms, with or without
                      9:  * modification, are permitted provided that the following conditions
                     10:  * are met:
                     11:  * 1. Redistributions of source code must retain the above copyright
                     12:  *    notice, this list of conditions and the following disclaimer.
                     13:  * 2. Redistributions in binary form must reproduce the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer in the
                     15:  *    documentation and/or other materials provided with the distribution.
                     16:  * 3. All advertising materials mentioning features or use of this software
                     17:  *    must display the following acknowledgement:
                     18:  *     This product includes software developed by the University of
                     19:  *     California, Berkeley and its contributors.
                     20:  * 4. Neither the name of the University nor the names of its contributors
                     21:  *    may be used to endorse or promote products derived from this software
                     22:  *    without specific prior written permission.
                     23:  *
                     24:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     25:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     26:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     27:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     28:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     29:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     30:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     31:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     32:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     33:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     34:  * SUCH DAMAGE.
                     35:  *
                     36:  *     filecore_vfsops.c       1.1     1998/6/26
                     37:  */
1.5       drochner   38:
1.14    ! mrg        39: #if defined(_KERNEL_OPT)
1.5       drochner   40: #include "opt_compat_netbsd.h"
                     41: #endif
1.1       mark       42:
                     43: #include <sys/param.h>
                     44: #include <sys/systm.h>
                     45: #include <sys/namei.h>
                     46: #include <sys/proc.h>
                     47: #include <sys/vnode.h>
                     48: #include <miscfs/specfs/specdev.h>
                     49: #include <sys/mount.h>
                     50: #include <sys/buf.h>
                     51: #include <sys/file.h>
                     52: #include <sys/device.h>
                     53: #include <sys/errno.h>
                     54: #include <sys/malloc.h>
1.3       thorpej    55: #include <sys/pool.h>
1.1       mark       56:
                     57: #include <filecorefs/filecore.h>
                     58: #include <filecorefs/filecore_extern.h>
                     59: #include <filecorefs/filecore_node.h>
                     60: #include <filecorefs/filecore_mount.h>
                     61:
1.13      jdolecek   62: extern const struct vnodeopv_desc filecore_vnodeop_opv_desc;
1.1       mark       63:
1.13      jdolecek   64: const struct vnodeopv_desc * const filecore_vnodeopv_descs[] = {
1.1       mark       65:        &filecore_vnodeop_opv_desc,
                     66:        NULL,
                     67: };
                     68:
                     69: struct vfsops filecore_vfsops = {
                     70:        MOUNT_FILECORE,
                     71:        filecore_mount,
                     72:        filecore_start,
                     73:        filecore_unmount,
                     74:        filecore_root,
                     75:        filecore_quotactl,
                     76:        filecore_statfs,
                     77:        filecore_sync,
                     78:        filecore_vget,
                     79:        filecore_fhtovp,
                     80:        filecore_vptofh,
                     81:        filecore_init,
1.11      jdolecek   82:        filecore_done,
1.1       mark       83:        filecore_sysctl,
                     84:        NULL,                           /* filecore_mountroot */
1.6       wrstuden   85:        filecore_checkexp,
1.1       mark       86:        filecore_vnodeopv_descs,
                     87: };
                     88:
                     89: /*
                     90:  * Called by vfs_mountroot when iso is going to be mounted as root.
                     91:  *
                     92:  * Name is updated by mount(8) after booting.
                     93:  */
                     94:
                     95: static int filecore_mountfs __P((struct vnode *devvp, struct mount *mp,
                     96:                struct proc *p, struct filecore_args *argp));
                     97:
                     98: #if 0
                     99: int
                    100: filecore_mountroot()
                    101: {
                    102:        struct mount *mp;
                    103:        extern struct vnode *rootvp;
                    104:        struct proc *p = curproc;       /* XXX */
                    105:        int error;
                    106:        struct filecore_args args;
                    107:
                    108:        if (root_device->dv_class != DV_DISK)
                    109:                return (ENODEV);
                    110:
                    111:        /*
                    112:         * Get vnodes for swapdev and rootdev.
                    113:         */
                    114:        if (bdevvp(rootdev, &rootvp))
                    115:                panic("filecore_mountroot: can't setup rootvp");
                    116:
                    117:        if ((error = vfs_rootmountalloc(MOUNT_FILECORE, "root_device", &mp)) != 0)
                    118:                return (error);
                    119:
                    120:        args.flags = FILECOREMNT_ROOT;
                    121:        if ((error = filecore_mountfs(rootvp, mp, p, &args)) != 0) {
                    122:                mp->mnt_op->vfs_refcount--;
                    123:                vfs_unbusy(mp);
                    124:                free(mp, M_MOUNT);
                    125:                return (error);
                    126:        }
                    127:        simple_lock(&mountlist_slock);
                    128:        CIRCLEQ_INSERT_TAIL(&mountlist, mp, mnt_list);
                    129:        simple_unlock(&mountlist_slock);
                    130:        (void)filecore_statfs(mp, &mp->mnt_stat, p);
                    131:        vfs_unbusy(mp);
                    132:        return (0);
                    133: }
                    134: #endif
                    135:
                    136: /*
                    137:  * VFS Operations.
                    138:  *
                    139:  * mount system call
                    140:  */
                    141: int
                    142: filecore_mount(mp, path, data, ndp, p)
                    143:        struct mount *mp;
                    144:        const char *path;
                    145:        void *data;
                    146:        struct nameidata *ndp;
                    147:        struct proc *p;
                    148: {
                    149:        struct vnode *devvp;
                    150:        struct filecore_args args;
                    151:        size_t size;
                    152:        int error;
                    153:        struct filecore_mnt *fcmp = NULL;
                    154:
                    155:        error = copyin(data, (caddr_t)&args, sizeof (struct filecore_args));
                    156:        if (error)
                    157:                return (error);
                    158:
                    159:        if ((mp->mnt_flag & MNT_RDONLY) == 0)
                    160:                return (EROFS);
                    161:
                    162:        /*
                    163:         * If updating, check whether changing from read-only to
                    164:         * read/write; if there is no device name, that's all we do.
                    165:         */
                    166:        if (mp->mnt_flag & MNT_UPDATE) {
                    167:                fcmp = VFSTOFILECORE(mp);
                    168:                if (args.fspec == 0)
                    169:                        return (vfs_export(mp, &fcmp->fc_export, &args.export));
                    170:        }
                    171:        /*
                    172:         * Not an update, or updating the name: look up the name
                    173:         * and verify that it refers to a sensible block device.
                    174:         */
                    175:        NDINIT(ndp, LOOKUP, FOLLOW, UIO_USERSPACE, args.fspec, p);
                    176:        if ((error = namei(ndp)) != 0)
                    177:                return (error);
                    178:        devvp = ndp->ni_vp;
                    179:
                    180:        if (devvp->v_type != VBLK) {
                    181:                vrele(devvp);
                    182:                return ENOTBLK;
                    183:        }
                    184:        if (major(devvp->v_rdev) >= nblkdev) {
                    185:                vrele(devvp);
                    186:                return ENXIO;
1.4       mycroft   187:        }
                    188:        /*
                    189:         * If mount by non-root, then verify that user has necessary
                    190:         * permissions on the device.
                    191:         */
                    192:        if (p->p_ucred->cr_uid != 0) {
                    193:                vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
                    194:                error = VOP_ACCESS(devvp, VREAD, p->p_ucred, p);
                    195:                VOP_UNLOCK(devvp, 0);
                    196:                if (error) {
                    197:                        vrele(devvp);
                    198:                        return (error);
                    199:                }
1.1       mark      200:        }
                    201:        if ((mp->mnt_flag & MNT_UPDATE) == 0)
                    202:                error = filecore_mountfs(devvp, mp, p, &args);
                    203:        else {
                    204:                if (devvp != fcmp->fc_devvp)
                    205:                        error = EINVAL; /* needs translation */
                    206:                else
                    207:                        vrele(devvp);
                    208:        }
                    209:        if (error) {
                    210:                vrele(devvp);
                    211:                return error;
                    212:        }
                    213:        fcmp = VFSTOFILECORE(mp);
                    214:        (void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size);
                    215:        memset(mp->mnt_stat.f_mntonname + size, 0, MNAMELEN - size);
                    216:        (void) copyinstr(args.fspec, mp->mnt_stat.f_mntfromname, MNAMELEN - 1,
                    217:            &size);
                    218:        memset(mp->mnt_stat.f_mntfromname + size, 0, MNAMELEN - size);
                    219:        return 0;
                    220: }
                    221:
                    222: /*
                    223:  * Common code for mount and mountroot
                    224:  */
                    225: static int
                    226: filecore_mountfs(devvp, mp, p, argp)
1.2       mark      227:        struct vnode *devvp;
1.1       mark      228:        struct mount *mp;
                    229:        struct proc *p;
                    230:        struct filecore_args *argp;
                    231: {
1.2       mark      232:        struct filecore_mnt *fcmp = (struct filecore_mnt *)0;
1.1       mark      233:        struct buf *bp = NULL;
                    234:        dev_t dev = devvp->v_rdev;
                    235:        int error = EINVAL;
                    236:        int ronly = (mp->mnt_flag & MNT_RDONLY) != 0;
                    237:        extern struct vnode *rootvp;
                    238:        struct filecore_disc_record *fcdr;
                    239:        unsigned map;
                    240:        unsigned log2secsize;
                    241:
                    242:        if (!ronly)
                    243:                return EROFS;
                    244:
                    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)) != 0)
                    252:                return error;
                    253:        if (vcount(devvp) > 1 && devvp != rootvp)
                    254:                return EBUSY;
                    255:        if ((error = vinvalbuf(devvp, V_SAVE, p->p_ucred, p, 0, 0)) != 0)
                    256:                return (error);
                    257:
                    258:        error = VOP_OPEN(devvp, ronly ? FREAD : FREAD|FWRITE, FSCRED, p);
                    259:        if (error)
                    260:                return error;
                    261:
                    262:        /* Read the filecore boot block to check FS validity and to find the map */
                    263:        error = bread(devvp, FILECORE_BOOTBLOCK_BLKN,
                    264:                           FILECORE_BOOTBLOCK_SIZE, NOCRED, &bp);
                    265: #ifdef FILECORE_DEBUG_BR
1.2       mark      266:                printf("bread(%p, %x, %d, CRED, %p)=%d\n", devvp,
1.1       mark      267:                       FILECORE_BOOTBLOCK_BLKN, FILECORE_BOOTBLOCK_SIZE,
                    268:                       bp, error);
                    269: #endif
                    270:        if (error != 0)
                    271:                goto out;
                    272:        if (filecore_bbchecksum(bp->b_data) != 0) {
                    273:                error = EINVAL;
                    274:                goto out;
                    275:        }
                    276:        fcdr = (struct filecore_disc_record *)(bp->b_data+FILECORE_BB_DISCREC);
1.2       mark      277:        map = ((((8 << fcdr->log2secsize) - fcdr->zone_spare)
                    278:            * (fcdr->nzones / 2) - 8 * FILECORE_DISCREC_SIZE)
                    279:            << fcdr->log2bpmb) >> fcdr->log2secsize;
1.1       mark      280:        log2secsize = fcdr->log2secsize;
                    281:        bp->b_flags |= B_AGE;
                    282: #ifdef FILECORE_DEBUG_BR
1.2       mark      283:        printf("brelse(%p) vf1\n", bp);
1.1       mark      284: #endif
                    285:        brelse(bp);
                    286:        bp = NULL;
                    287:
                    288:        /* Read the bootblock in the map */
1.2       mark      289:        error = bread(devvp, map, 1 << log2secsize, NOCRED, &bp);
1.1       mark      290: #ifdef FILECORE_DEBUG_BR
1.2       mark      291:                printf("bread(%p, %x, %d, CRED, %p)=%d\n", devvp,
                    292:                       map, 1 << log2secsize, bp, error);
1.1       mark      293: #endif
                    294:        if (error != 0)
                    295:                goto out;
1.2       mark      296:                fcdr = (struct filecore_disc_record *)(bp->b_data + 4);
1.1       mark      297:        fcmp = malloc(sizeof *fcmp, M_FILECOREMNT, M_WAITOK);
                    298:        memset((caddr_t)fcmp, 0, sizeof *fcmp);
                    299:        if (fcdr->log2bpmb > fcdr->log2secsize)
                    300:                fcmp->log2bsize = fcdr->log2bpmb;
                    301:        else    fcmp->log2bsize = fcdr->log2secsize;
1.2       mark      302:        fcmp->blksize = 1 << fcmp->log2bsize;
1.1       mark      303:        memcpy((caddr_t)&fcmp->drec, (caddr_t)fcdr, sizeof(*fcdr));
1.2       mark      304:        fcmp->map = map;
                    305:        fcmp->idspz = ((8 << fcdr->log2secsize) - fcdr->zone_spare)
                    306:            / (fcdr->idlen + 1);
                    307:        fcmp->mask = (1 << fcdr->idlen) - 1;
1.1       mark      308:        if (fcdr->big_flag & 1) {
1.2       mark      309:                fcmp->nblks = ((((u_int64_t)fcdr->disc_size_2) << 32)
                    310:                    + fcdr->disc_size) / fcmp->blksize;
1.1       mark      311:        } else {
1.2       mark      312:                fcmp->nblks=fcdr->disc_size / fcmp->blksize;
1.1       mark      313:        }
                    314:
                    315:        bp->b_flags |= B_AGE;
                    316: #ifdef FILECORE_DEBUG_BR
1.2       mark      317:        printf("brelse(%p) vf2\n", bp);
1.1       mark      318: #endif
                    319:        brelse(bp);
                    320:        bp = NULL;
                    321:
                    322:        mp->mnt_data = (qaddr_t)fcmp;
                    323:        mp->mnt_stat.f_fsid.val[0] = (long)dev;
                    324:        mp->mnt_stat.f_fsid.val[1] = makefstype(MOUNT_FILECORE);
                    325:        mp->mnt_maxsymlinklen = 0;
                    326:        mp->mnt_flag |= MNT_LOCAL;
1.12      chs       327:        mp->mnt_dev_bshift = fcdr->log2secsize;
                    328:        mp->mnt_fs_bshift = fcmp->log2bsize;
                    329:
1.1       mark      330:        fcmp->fc_mountp = mp;
                    331:        fcmp->fc_dev = dev;
                    332:        fcmp->fc_devvp = devvp;
                    333:        fcmp->fc_mntflags = argp->flags;
                    334:        if (argp->flags & FILECOREMNT_USEUID) {
1.2       mark      335:                fcmp->fc_uid = p->p_cred->p_ruid;
                    336:                fcmp->fc_gid = p->p_cred->p_rgid;
1.1       mark      337:        } else {
1.2       mark      338:                fcmp->fc_uid = argp->uid;
                    339:                fcmp->fc_gid = argp->gid;
1.1       mark      340:        }
                    341:
                    342:        return 0;
                    343: out:
                    344:        if (bp) {
                    345: #ifdef FILECORE_DEBUG_BR
1.2       mark      346:                printf("brelse(%p) vf3\n", bp);
1.1       mark      347: #endif
                    348:                brelse(bp);
                    349:        }
1.8       wrstuden  350:        vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
1.1       mark      351:        (void)VOP_CLOSE(devvp, ronly ? FREAD : FREAD|FWRITE, NOCRED, p);
1.8       wrstuden  352:        VOP_UNLOCK(devvp, 0);
1.1       mark      353:        if (fcmp) {
                    354:                free((caddr_t)fcmp, M_FILECOREMNT);
                    355:                mp->mnt_data = (qaddr_t)0;
                    356:        }
                    357:        return error;
                    358: }
                    359:
                    360: /*
                    361:  * Make a filesystem operational.
                    362:  * Nothing to do at the moment.
                    363:  */
                    364: /* ARGSUSED */
                    365: int
                    366: filecore_start(mp, flags, p)
                    367:        struct mount *mp;
                    368:        int flags;
                    369:        struct proc *p;
                    370: {
                    371:        return 0;
                    372: }
                    373:
                    374: /*
                    375:  * unmount system call
                    376:  */
                    377: int
                    378: filecore_unmount(mp, mntflags, p)
                    379:        struct mount *mp;
                    380:        int mntflags;
                    381:        struct proc *p;
                    382: {
1.2       mark      383:        struct filecore_mnt *fcmp;
1.1       mark      384:        int error, flags = 0;
                    385:
                    386:        if (mntflags & MNT_FORCE)
                    387:                flags |= FORCECLOSE;
                    388: #if 0
                    389:        mntflushbuf(mp, 0);
                    390:        if (mntinvalbuf(mp))
                    391:                return EBUSY;
                    392: #endif
                    393:        if ((error = vflush(mp, NULLVP, flags)) != 0)
                    394:                return (error);
                    395:
                    396:        fcmp = VFSTOFILECORE(mp);
                    397:
1.9       enami     398:        if (fcmp->fc_devvp->v_type != VBAD)
1.10      fvdl      399:                fcmp->fc_devvp->v_specmountpoint = NULL;
1.8       wrstuden  400:        vn_lock(fcmp->fc_devvp, LK_EXCLUSIVE | LK_RETRY);
1.1       mark      401:        error = VOP_CLOSE(fcmp->fc_devvp, FREAD, NOCRED, p);
1.8       wrstuden  402:        vput(fcmp->fc_devvp);
1.1       mark      403:        free((caddr_t)fcmp, M_FILECOREMNT);
                    404:        mp->mnt_data = (qaddr_t)0;
                    405:        mp->mnt_flag &= ~MNT_LOCAL;
                    406:        return (error);
                    407: }
                    408:
                    409: /*
                    410:  * Return root of a filesystem
                    411:  */
                    412: int
                    413: filecore_root(mp, vpp)
                    414:        struct mount *mp;
                    415:        struct vnode **vpp;
                    416: {
                    417:        struct vnode *nvp;
                    418:         int error;
                    419:
                    420:         if ((error = VFS_VGET(mp, FILECORE_ROOTINO, &nvp)) != 0)
                    421:                 return (error);
                    422:         *vpp = nvp;
                    423:         return (0);
                    424: }
                    425:
                    426: /*
                    427:  * Do operations associated with quotas, not supported
                    428:  */
                    429: /* ARGSUSED */
                    430: int
                    431: filecore_quotactl(mp, cmd, uid, arg, p)
                    432:        struct mount *mp;
                    433:        int cmd;
                    434:        uid_t uid;
                    435:        caddr_t arg;
                    436:        struct proc *p;
                    437: {
                    438:
                    439:        return (EOPNOTSUPP);
                    440: }
                    441:
                    442: /*
                    443:  * Get file system statistics.
                    444:  */
                    445: int
                    446: filecore_statfs(mp, sbp, p)
                    447:        struct mount *mp;
1.2       mark      448:        struct statfs *sbp;
1.1       mark      449:        struct proc *p;
                    450: {
1.2       mark      451:        struct filecore_mnt *fcmp = VFSTOFILECORE(mp);
1.1       mark      452:
                    453: #ifdef COMPAT_09
                    454:        sbp->f_type = 255;
                    455: #else
                    456:        sbp->f_type = 0;
                    457: #endif
                    458:        sbp->f_bsize = fcmp->blksize;
                    459:        sbp->f_iosize = sbp->f_bsize;   /* XXX */
                    460:        sbp->f_blocks = fcmp->nblks;
                    461:        sbp->f_bfree = 0; /* total free blocks */
                    462:        sbp->f_bavail = 0; /* blocks free for non superuser */
                    463:        sbp->f_files =  0; /* total files */
                    464:        sbp->f_ffree = 0; /* free file nodes */
                    465:        if (sbp != &mp->mnt_stat) {
                    466:                memcpy(sbp->f_mntonname, mp->mnt_stat.f_mntonname, MNAMELEN);
                    467:                memcpy(sbp->f_mntfromname, mp->mnt_stat.f_mntfromname, MNAMELEN);
                    468:        }
                    469:        strncpy(sbp->f_fstypename, mp->mnt_op->vfs_name, MFSNAMELEN);
                    470:        return 0;
                    471: }
                    472:
                    473: /* ARGSUSED */
                    474: int
                    475: filecore_sync(mp, waitfor, cred, p)
                    476:        struct mount *mp;
                    477:        int waitfor;
                    478:        struct ucred *cred;
                    479:        struct proc *p;
                    480: {
                    481:        return (0);
                    482: }
                    483:
                    484: /*
                    485:  * File handle to vnode
                    486:  *
                    487:  * Have to be really careful about stale file handles:
                    488:  * - check that the inode number is in range
                    489:  * - call iget() to get the locked inode
                    490:  * - check for an unallocated inode (i_mode == 0)
                    491:  * - check that the generation number matches
                    492:  */
                    493:
                    494: struct ifid {
                    495:        ushort          ifid_len;
                    496:        ushort          ifid_pad;
                    497:        u_int32_t       ifid_ino;
                    498: };
                    499:
                    500: /* ARGSUSED */
                    501: int
1.6       wrstuden  502: filecore_fhtovp(mp, fhp, vpp)
1.2       mark      503:        struct mount *mp;
1.1       mark      504:        struct fid *fhp;
                    505:        struct vnode **vpp;
                    506: {
                    507:        struct ifid *ifhp = (struct ifid *)fhp;
                    508:        struct vnode *nvp;
                    509:        struct filecore_node *ip;
                    510:        int error;
                    511:
                    512:        if ((error = VFS_VGET(mp, ifhp->ifid_ino, &nvp)) != 0) {
                    513:                *vpp = NULLVP;
                    514:                return (error);
                    515:        }
                    516:         ip = VTOI(nvp);
                    517:         if (filecore_staleinode(ip)) {
                    518:                 vput(nvp);
                    519:                 *vpp = NULLVP;
                    520:                 return (ESTALE);
1.6       wrstuden  521:         }
                    522:        *vpp = nvp;
                    523:        return (0);
                    524: }
                    525:
                    526: /* ARGSUSED */
                    527: int
                    528: filecore_checkexp(mp, nam, exflagsp, credanonp)
                    529:        struct mount *mp;
                    530:        struct mbuf *nam;
                    531:        int *exflagsp;
                    532:        struct ucred **credanonp;
                    533: {
                    534:        struct filecore_mnt *fcmp = VFSTOFILECORE(mp);
                    535:        struct netcred *np;
                    536:
                    537:        /*
                    538:         * Get the export permission structure for this <mp, client> tuple.
                    539:         */
                    540:        np = vfs_export_lookup(mp, &fcmp->fc_export, nam);
                    541:        if (np == NULL)
                    542:                return (EACCES);
                    543:
1.1       mark      544:        *exflagsp = np->netc_exflags;
                    545:        *credanonp = &np->netc_anon;
                    546:        return (0);
                    547: }
                    548:
                    549: /* This looks complicated. Look at other vgets as well as the iso9660 one.
1.2       mark      550:  *
                    551:  * The filecore inode number is made up of 1 byte directory entry index and
                    552:  * 3 bytes of the internal disc address of the directory. On a read-only
                    553:  * filesystem this is unique. For a read-write version we may not be able to
                    554:  * do vget, see msdosfs.
                    555:  */
1.1       mark      556:
                    557: int
                    558: filecore_vget(mp, ino, vpp)
                    559:        struct mount *mp;
                    560:        ino_t ino;
                    561:        struct vnode **vpp;
                    562: {
1.2       mark      563:        struct filecore_mnt *fcmp;
1.1       mark      564:        struct filecore_node *ip;
                    565:        struct buf *bp;
                    566:        struct vnode *vp;
                    567:        dev_t dev;
                    568:        int error;
                    569:
                    570:        fcmp = VFSTOFILECORE(mp);
                    571:        dev = fcmp->fc_dev;
                    572:        if ((*vpp = filecore_ihashget(dev, ino)) != NULLVP)
                    573:                return (0);
                    574:
                    575:        /* Allocate a new vnode/filecore_node. */
1.2       mark      576:        if ((error = getnewvnode(VT_FILECORE, mp, filecore_vnodeop_p, &vp))
                    577:            != 0) {
1.1       mark      578:                *vpp = NULLVP;
                    579:                return (error);
                    580:        }
1.3       thorpej   581:        ip = pool_get(&filecore_node_pool, PR_WAITOK);
1.1       mark      582:        memset((caddr_t)ip, 0, sizeof(struct filecore_node));
                    583:        vp->v_data = ip;
                    584:        ip->i_vnode = vp;
                    585:        ip->i_dev = dev;
                    586:        ip->i_number = ino;
                    587:        ip->i_block = -1;
                    588:        ip->i_parent = -2;
                    589:
                    590:        /*
                    591:         * Put it onto its hash chain and lock it so that other requests for
                    592:         * this inode will block if they arrive while we are sleeping waiting
                    593:         * for old data structures to be purged or for the contents of the
                    594:         * disk portion of this inode to be read.
                    595:         */
                    596:        filecore_ihashins(ip);
                    597:
1.2       mark      598:        if (ino == FILECORE_ROOTINO) {
1.1       mark      599:                /* Here we need to construct a root directory inode */
1.2       mark      600:                memcpy((caddr_t)ip->i_dirent.name, (caddr_t)"root", 4);
                    601:                ip->i_dirent.load = 0;
                    602:                ip->i_dirent.exec = 0;
                    603:                ip->i_dirent.len = FILECORE_DIR_SIZE;
                    604:                ip->i_dirent.addr = fcmp->drec.root;
                    605:                ip->i_dirent.attr = FILECORE_ATTR_DIR | FILECORE_ATTR_READ;
1.1       mark      606:
                    607:        } else {
                    608:                /* Read in Data from Directory Entry */
1.2       mark      609:                if ((error = filecore_bread(fcmp, ino & FILECORE_INO_MASK,
                    610:                    FILECORE_DIR_SIZE, NOCRED, &bp)) != 0) {
1.1       mark      611:                        vput(vp);
                    612: #ifdef FILECORE_DEBUG_BR
1.2       mark      613:                        printf("brelse(%p) vf4\n", bp);
1.1       mark      614: #endif
                    615:                        brelse(bp);
                    616:                        *vpp = NULL;
                    617:                        return (error);
                    618:                }
                    619:
                    620:                memcpy((caddr_t)&ip->i_dirent,
1.2       mark      621:                    (caddr_t)fcdirentry(bp->b_data, ino >> FILECORE_INO_INDEX),
1.1       mark      622:                    sizeof(struct filecore_direntry));
                    623: #ifdef FILECORE_DEBUG_BR
1.2       mark      624:                printf("brelse(%p) vf5\n", bp);
1.1       mark      625: #endif
                    626:                brelse(bp);
                    627:        }
                    628:
                    629:        ip->i_mnt = fcmp;
                    630:        ip->i_devvp = fcmp->fc_devvp;
                    631:        ip->i_diroff = 0;
                    632:        VREF(ip->i_devvp);
                    633:
                    634:        /*
                    635:         * Setup type
                    636:         */
                    637:        vp->v_type = VREG;
1.2       mark      638:        if (ip->i_dirent.attr & FILECORE_ATTR_DIR)
                    639:                vp->v_type = VDIR;
1.1       mark      640:
                    641:        /*
                    642:         * Initialize the associated vnode
                    643:         */
                    644:        switch (vp->v_type) {
                    645:        case VFIFO:
                    646:        case VCHR:
                    647:        case VBLK:
                    648:                /*
                    649:                 * Devices not supported.
                    650:                 */
                    651:                vput(vp);
                    652:                return (EOPNOTSUPP);
                    653:        case VLNK:
                    654:        case VNON:
                    655:        case VSOCK:
                    656:        case VDIR:
                    657:        case VBAD:
                    658:        case VREG:
                    659:                break;
                    660:        }
                    661:
                    662:        if (ino == FILECORE_ROOTINO)
                    663:                vp->v_flag |= VROOT;
                    664:
                    665:        /*
                    666:         * XXX need generation number?
                    667:         */
                    668:
                    669:        *vpp = vp;
                    670:        return (0);
                    671: }
                    672:
                    673: /*
                    674:  * Vnode pointer to File handle
                    675:  */
                    676: /* ARGSUSED */
                    677: int
                    678: filecore_vptofh(vp, fhp)
                    679:        struct vnode *vp;
                    680:        struct fid *fhp;
                    681: {
1.2       mark      682:        struct filecore_node *ip = VTOI(vp);
                    683:        struct ifid *ifhp;
1.1       mark      684:
                    685:        ifhp = (struct ifid *)fhp;
                    686:        ifhp->ifid_len = sizeof(struct ifid);
                    687:        ifhp->ifid_ino = ip->i_number;
                    688:                return 0;
                    689: }
                    690:
                    691: int
                    692: filecore_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
                    693:        int *name;
                    694:        u_int namelen;
                    695:        void *oldp;
                    696:        size_t *oldlenp;
                    697:        void *newp;
                    698:        size_t newlen;
                    699:        struct proc *p;
                    700: {
                    701:        return (EOPNOTSUPP);
                    702: }

CVSweb <webmaster@jp.NetBSD.org>