Annotation of Net2/isofs/isofs_vfsops.c, revision 1.1.1.1

1.1       root        1: #include "param.h"
                      2: #include "systm.h"
                      3: #include "namei.h"
                      4: #include "proc.h"
                      5: #include "kernel.h"
                      6: #include "vnode.h"
                      7: #include "specdev.h"
                      8: #include "mount.h"
                      9: #include "buf.h"
                     10: #include "file.h"
                     11: #include "dkbad.h"
                     12: #include "disklabel.h"
                     13: #include "ioctl.h"
                     14: #include "errno.h"
                     15: #include "malloc.h"
                     16: 
                     17: #include "iso.h"
                     18: #include "isofs_node.h"
                     19: 
                     20: extern int enodev ();
                     21: 
                     22: struct vfsops isofs_vfsops = {
                     23:        isofs_mount,
                     24:        isofs_start,
                     25:        isofs_unmount,
                     26:        isofs_root,
                     27:        (void *)enodev, /* quotactl */
                     28:        isofs_statfs,
                     29:        isofs_sync,
                     30:        isofs_fhtovp,
                     31:        isofs_vptofh,
                     32:        isofs_init
                     33: };
                     34: 
                     35: /*
                     36:  * Called by vfs_mountroot when ufs is going to be mounted as root.
                     37:  *
                     38:  * Name is updated by mount(8) after booting.
                     39:  */
                     40: #define ROOTNAME       "root_device"
                     41: 
                     42: isofs_mountroot()
                     43: {
                     44:        register struct mount *mp;
                     45:        extern struct vnode *rootvp;
                     46:        struct proc *p = curproc;       /* XXX */
                     47:        struct iso_mnt *imp;
                     48:        register struct fs *fs;
                     49:        u_int size;
                     50:        int error;
                     51: 
                     52:        mp = (struct mount *)malloc((u_long)sizeof(struct mount),
                     53:                M_MOUNT, M_WAITOK);
                     54:        mp->mnt_op = &isofs_vfsops;
                     55:        mp->mnt_flag = MNT_RDONLY;
                     56:        mp->mnt_exroot = 0;
                     57:        mp->mnt_mounth = NULLVP;
                     58:        error = iso_mountfs(rootvp, mp, p);
                     59:        if (error) {
                     60:                free((caddr_t)mp, M_MOUNT);
                     61:                return (error);
                     62:        }
                     63:        if (error = vfs_lock(mp)) {
                     64:                (void)isofs_unmount(mp, 0, p);
                     65:                free((caddr_t)mp, M_MOUNT);
                     66:                return (error);
                     67:        }
                     68:        rootfs = mp;
                     69:        mp->mnt_next = mp;
                     70:        mp->mnt_prev = mp;
                     71:        mp->mnt_vnodecovered = NULLVP;
                     72:        imp = VFSTOISOFS(mp);
                     73:        bzero(imp->im_fsmnt, sizeof(imp->im_fsmnt));
                     74:        imp->im_fsmnt[0] = '/';
                     75:        bcopy((caddr_t)imp->im_fsmnt, (caddr_t)mp->mnt_stat.f_mntonname,
                     76:            MNAMELEN);
                     77:        (void) copystr(ROOTNAME, mp->mnt_stat.f_mntfromname, MNAMELEN - 1,
                     78:            &size);
                     79:        bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size);
                     80:        (void) isofs_statfs(mp, &mp->mnt_stat, p);
                     81:        vfs_unlock(mp);
                     82:        return (0);
                     83: }
                     84: 
                     85: /*
                     86:  * Flag to allow forcible unmounting.
                     87:  */
                     88: int iso_doforce = 1;
                     89: 
                     90: /*
                     91:  * VFS Operations.
                     92:  *
                     93:  * mount system call
                     94:  */
                     95: isofs_mount(mp, path, data, ndp, p)
                     96:        register struct mount *mp;
                     97:        char *path;
                     98:        caddr_t data;
                     99:        struct nameidata *ndp;
                    100:        struct proc *p;
                    101: {
                    102:        struct vnode *devvp;
                    103:        struct ufs_args args;
                    104:        u_int size;
                    105:        int error;
                    106:        struct iso_mnt *imp;
                    107: 
                    108:        if (error = copyin(data, (caddr_t)&args, sizeof (struct ufs_args)))
                    109:                return (error);
                    110: 
                    111:        if ((mp->mnt_flag & MNT_RDONLY) == 0)
                    112:                return (EROFS);
                    113: 
                    114:        /*
                    115:         * Process export requests.
                    116:         */
                    117:        if ((args.exflags & MNT_EXPORTED) || (mp->mnt_flag & MNT_EXPORTED)) {
                    118:                if (args.exflags & MNT_EXPORTED)
                    119:                        mp->mnt_flag |= MNT_EXPORTED;
                    120:                else
                    121:                        mp->mnt_flag &= ~MNT_EXPORTED;
                    122:                if (args.exflags & MNT_EXRDONLY)
                    123:                        mp->mnt_flag |= MNT_EXRDONLY;
                    124:                else
                    125:                        mp->mnt_flag &= ~MNT_EXRDONLY;
                    126:                mp->mnt_exroot = args.exroot;
                    127:        }
                    128:        /*
                    129:         * If updating, check whether changing from read-only to
                    130:         * read/write; if there is no device name, that's all we do.
                    131:         */
                    132:        if (mp->mnt_flag & MNT_UPDATE) {
                    133:                imp = VFSTOISOFS(mp);
                    134:                if (args.fspec == 0)
                    135:                        return (0);
                    136:        }
                    137:        /*
                    138:         * Not an update, or updating the name: look up the name
                    139:         * and verify that it refers to a sensible block device.
                    140:         */
                    141:        ndp->ni_nameiop = LOOKUP | FOLLOW;
                    142:        ndp->ni_segflg = UIO_USERSPACE;
                    143:        ndp->ni_dirp = args.fspec;
                    144:        if (error = namei(ndp, p))
                    145:                return (error);
                    146:        devvp = ndp->ni_vp;
                    147:        if (devvp->v_type != VBLK) {
                    148:                vrele(devvp);
                    149:                return (ENOTBLK);
                    150:        }
                    151:        if (major(devvp->v_rdev) >= nblkdev) {
                    152:                vrele(devvp);
                    153:                return (ENXIO);
                    154:        }
                    155: 
                    156:        if ((mp->mnt_flag & MNT_UPDATE) == 0)
                    157:                error = iso_mountfs(devvp, mp, p);
                    158:        else {
                    159:                if (devvp != imp->im_devvp)
                    160:                        error = EINVAL; /* needs translation */
                    161:                else
                    162:                        vrele(devvp);
                    163:        }
                    164:        if (error) {
                    165:                vrele(devvp);
                    166:                return (error);
                    167:        }
                    168:        imp = VFSTOISOFS(mp);
                    169:        (void) copyinstr(path, imp->im_fsmnt, sizeof(imp->im_fsmnt)-1, &size);
                    170:        bzero(imp->im_fsmnt + size, sizeof(imp->im_fsmnt) - size);
                    171:        bcopy((caddr_t)imp->im_fsmnt, (caddr_t)mp->mnt_stat.f_mntonname,
                    172:            MNAMELEN);
                    173:        (void) copyinstr(args.fspec, mp->mnt_stat.f_mntfromname, MNAMELEN - 1, 
                    174:            &size);
                    175:        bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size);
                    176:        (void) isofs_statfs(mp, &mp->mnt_stat, p);
                    177:        return (0);
                    178: }
                    179: 
                    180: /*
                    181:  * Common code for mount and mountroot
                    182:  */
                    183: iso_mountfs(devvp, mp, p)
                    184:        register struct vnode *devvp;
                    185:        struct mount *mp;
                    186:        struct proc *p;
                    187: {
                    188:        register struct iso_mnt *isomp = (struct iso_mnt *)0;
                    189:        struct buf *bp = NULL;
                    190:        dev_t dev = devvp->v_rdev;
                    191:        caddr_t base, space;
                    192:        int havepart = 0, blks;
                    193:        int error = EINVAL, i, size;
                    194:        int needclose = 0;
                    195:        int ronly = (mp->mnt_flag & MNT_RDONLY) != 0;
                    196:        extern struct vnode *rootvp;
                    197:        int j;
                    198:        int iso_bsize;
                    199:        int iso_blknum;
                    200:        struct iso_volume_descriptor *vdp;
                    201:        struct iso_primary_descriptor *pri;
                    202:        struct iso_directory_record *rootp;
                    203:        int logical_block_size;
                    204: 
                    205:        if (!ronly)
                    206:                return (EROFS);
                    207: 
                    208:        /*
                    209:         * Disallow multiple mounts of the same device.
                    210:         * Disallow mounting of a device that is currently in use
                    211:         * (except for root, which might share swap device for miniroot).
                    212:         * Flush out any old buffers remaining from a previous use.
                    213:         */
                    214:        if (error = iso_mountedon(devvp))
                    215:                return (error);
                    216:        if (vcount(devvp) > 1 && devvp != rootvp)
                    217:                return (EBUSY);
                    218:        vinvalbuf(devvp, 1);
                    219:        if (error = VOP_OPEN(devvp, ronly ? FREAD : FREAD|FWRITE, NOCRED, p))
                    220:                return (error);
                    221:        needclose = 1;
                    222: 
                    223:        /* This is the "logical sector size".  The standard says this
                    224:         * should be 2048 or the physical sector size on the device,
                    225:         * whichever is greater.  For now, we'll just use a constant.
                    226:         */
                    227:        iso_bsize = 2048;
                    228: 
                    229:        for (iso_blknum = 16; iso_blknum < 100; iso_blknum++) {
                    230:                if (error = bread (devvp, iso_blknum * iso_bsize / DEV_BSIZE,
                    231:                                   iso_bsize, NOCRED, &bp))
                    232:                        goto out;
                    233: 
                    234:                vdp = (struct iso_volume_descriptor *)bp->b_un.b_addr;
                    235:                if (bcmp (vdp->id, ISO_STANDARD_ID, sizeof vdp->id) != 0) {
                    236:                        error = EINVAL;
                    237:                        goto out;
                    238:                }
                    239: 
                    240:                if (isonum_711 (vdp->type) == ISO_VD_END) {
                    241:                        error = EINVAL;
                    242:                        goto out;
                    243:                }
                    244: 
                    245:                if (isonum_711 (vdp->type) == ISO_VD_PRIMARY)
                    246:                        break;
                    247:                brelse(bp);
                    248:        }
                    249: 
                    250:        if (isonum_711 (vdp->type) != ISO_VD_PRIMARY) {
                    251:                error = EINVAL;
                    252:                goto out;
                    253:        }
                    254:        
                    255:        pri = (struct iso_primary_descriptor *)vdp;
                    256: 
                    257:        logical_block_size = isonum_723 (pri->logical_block_size);
                    258: 
                    259:        if (logical_block_size < DEV_BSIZE
                    260:            || logical_block_size >= MAXBSIZE
                    261:            || (logical_block_size & (logical_block_size - 1)) != 0) {
                    262:                error = EINVAL;
                    263:                goto out;
                    264:        }
                    265: 
                    266:        rootp = (struct iso_directory_record *)pri->root_directory_record;
                    267: 
                    268:        isomp = (struct iso_mnt *)malloc(sizeof *isomp,M_UFSMNT,M_WAITOK);
                    269:        isomp->logical_block_size = logical_block_size;
                    270:        isomp->volume_space_size = isonum_733 (pri->volume_space_size);
                    271:        bcopy (rootp, isomp->root, sizeof isomp->root);
                    272:        isomp->root_extent = isonum_733 (rootp->extent);
                    273:        isomp->root_size = isonum_733 (rootp->size);
                    274: 
                    275:        isomp->im_bsize = logical_block_size;
                    276:        isomp->im_bmask = ~(isomp->im_bsize - 1);
                    277:        isomp->im_bshift = 0;
                    278:        while ((1 << isomp->im_bshift) < isomp->im_bsize)
                    279:                isomp->im_bshift++;
                    280: 
                    281:        bp->b_flags |= B_INVAL;
                    282:        brelse(bp);
                    283:        bp = NULL;
                    284: 
                    285:        isomp->im_ronly = ronly;
                    286:        if (ronly == 0)
                    287:                isomp->im_fmod = 1;
                    288: 
                    289:        mp->mnt_data = (qaddr_t)isomp;
                    290:        mp->mnt_stat.f_fsid.val[0] = (long)dev;
                    291:        mp->mnt_stat.f_fsid.val[1] = MOUNT_ISOFS;
                    292:        mp->mnt_flag |= MNT_LOCAL;
                    293:        isomp->im_mountp = mp;
                    294:        isomp->im_dev = dev;
                    295:        isomp->im_devvp = devvp;
                    296: 
                    297:        devvp->v_specflags |= SI_MOUNTEDON;
                    298: 
                    299:        return (0);
                    300: out:
                    301:        if (bp)
                    302:                brelse(bp);
                    303:        if (needclose)
                    304:                (void)VOP_CLOSE(devvp, ronly ? FREAD : FREAD|FWRITE, NOCRED, p);
                    305:        if (isomp) {
                    306:                free((caddr_t)isomp, M_UFSMNT);
                    307:                mp->mnt_data = (qaddr_t)0;
                    308:        }
                    309:        return (error);
                    310: }
                    311: 
                    312: /*
                    313:  * Make a filesystem operational.
                    314:  * Nothing to do at the moment.
                    315:  */
                    316: /* ARGSUSED */
                    317: isofs_start(mp, flags, p)
                    318:        struct mount *mp;
                    319:        int flags;
                    320:        struct proc *p;
                    321: {
                    322: 
                    323:        return (0);
                    324: }
                    325: 
                    326: /*
                    327:  * unmount system call
                    328:  */
                    329: isofs_unmount(mp, mntflags, p)
                    330:        struct mount *mp;
                    331:        int mntflags;
                    332:        struct proc *p;
                    333: {
                    334:        register struct iso_mnt *isomp;
                    335:        int i, error, ronly, flags = 0;
                    336: 
                    337:        if (mntflags & MNT_FORCE) {
                    338:                if (!iso_doforce || mp == rootfs)
                    339:                        return (EINVAL);
                    340:                flags |= FORCECLOSE;
                    341:        }
                    342:        mntflushbuf(mp, 0);
                    343:        if (mntinvalbuf(mp))
                    344:                return (EBUSY);
                    345:        isomp = VFSTOISOFS(mp);
                    346: 
                    347:        if (error = vflush(mp, NULLVP, flags))
                    348:                return (error);
                    349:        ronly = !isomp->im_ronly;
                    350:        isomp->im_devvp->v_specflags &= ~SI_MOUNTEDON;
                    351:        error = VOP_CLOSE(isomp->im_devvp, ronly ? FREAD : FREAD|FWRITE,
                    352:                NOCRED, p);
                    353:        vrele(isomp->im_devvp);
                    354:        free((caddr_t)isomp, M_UFSMNT);
                    355:        mp->mnt_data = (qaddr_t)0;
                    356:        mp->mnt_flag &= ~MNT_LOCAL;
                    357:        return (error);
                    358: }
                    359: 
                    360: /*
                    361:  * Check to see if a filesystem is mounted on a block device.
                    362:  */
                    363: iso_mountedon(vp)
                    364:        register struct vnode *vp;
                    365: {
                    366:        register struct vnode *vq;
                    367: 
                    368:        if (vp->v_specflags & SI_MOUNTEDON)
                    369:                return (EBUSY);
                    370:        if (vp->v_flag & VALIASED) {
                    371:                for (vq = *vp->v_hashchain; vq; vq = vq->v_specnext) {
                    372:                        if (vq->v_rdev != vp->v_rdev ||
                    373:                            vq->v_type != vp->v_type)
                    374:                                continue;
                    375:                        if (vq->v_specflags & SI_MOUNTEDON)
                    376:                                return (EBUSY);
                    377:                }
                    378:        }
                    379:        return (0);
                    380: }
                    381: 
                    382: /*
                    383:  * Return root of a filesystem
                    384:  */
                    385: isofs_root(mp, vpp)
                    386:        struct mount *mp;
                    387:        struct vnode **vpp;
                    388: {
                    389:        register struct iso_node *ip;
                    390:        struct iso_node *nip;
                    391:        struct vnode tvp;
                    392:        int error;
                    393:        struct iso_mnt *imp = VFSTOISOFS (mp);
                    394: 
                    395:        tvp.v_mount = mp;
                    396:        ip = VTOI(&tvp);
                    397:        ip->i_vnode = &tvp;
                    398:        ip->i_dev = imp->im_dev;
                    399:        error = iso_iget(ip, imp->root_extent, &nip,
                    400:                         (struct iso_directory_record *) imp->root);
                    401:        if (error)
                    402:                return (error);
                    403:        *vpp = ITOV(nip);
                    404:        return (0);
                    405: }
                    406: 
                    407: /*
                    408:  * Get file system statistics.
                    409:  */
                    410: isofs_statfs(mp, sbp, p)
                    411:        struct mount *mp;
                    412:        register struct statfs *sbp;
                    413:        struct proc *p;
                    414: {
                    415:        register struct iso_mnt *isomp;
                    416:        register struct fs *fs;
                    417: 
                    418:        isomp = VFSTOISOFS(mp);
                    419: 
                    420:        sbp->f_type = MOUNT_ISOFS;
                    421:        sbp->f_fsize = isomp->logical_block_size;
                    422:        sbp->f_bsize = sbp->f_fsize;
                    423:        sbp->f_blocks = isomp->volume_space_size;
                    424:        sbp->f_bfree = 0; /* total free blocks */
                    425:        sbp->f_bavail = 0; /* blocks free for non superuser */
                    426:        sbp->f_files =  0; /* total files */
                    427:        sbp->f_ffree = 0; /* free file nodes */
                    428:        if (sbp != &mp->mnt_stat) {
                    429:                bcopy((caddr_t)mp->mnt_stat.f_mntonname,
                    430:                        (caddr_t)&sbp->f_mntonname[0], MNAMELEN);
                    431:                bcopy((caddr_t)mp->mnt_stat.f_mntfromname,
                    432:                        (caddr_t)&sbp->f_mntfromname[0], MNAMELEN);
                    433:        }
                    434:        return (0);
                    435: }
                    436: 
                    437: isofs_sync(mp, waitfor)
                    438:        struct mount *mp;
                    439:        int waitfor;
                    440: {
                    441:        return (0);
                    442: }
                    443: 
                    444: /*
                    445:  * File handle to vnode
                    446:  *
                    447:  * Have to be really careful about stale file handles:
                    448:  * - check that the inode number is in range
                    449:  * - call iget() to get the locked inode
                    450:  * - check for an unallocated inode (i_mode == 0)
                    451:  * - check that the generation number matches
                    452:  */
                    453: isofs_fhtovp(mp, fhp, vpp)
                    454:        register struct mount *mp;
                    455:        struct fid *fhp;
                    456:        struct vnode **vpp;
                    457: {
                    458:        return (EINVAL);
                    459: #if 0
                    460:        /* here's a guess at what we need here */
                    461:        struct vnode tvp;
                    462:        int error;
                    463: 
                    464:        ifhp = (struct ifid *)fhp;
                    465:        imp = VFSTOISOFS (mp);
                    466: 
                    467:        if (ifhp->ifid_lbn >= imp->volume_space_size)
                    468:                return (EINVAL);
                    469: 
                    470:        if (ifhp->ifid_offset + sizeof (struct iso_directory_record)
                    471:            >= imp->im_bsize)
                    472:                return (EINVAL);
                    473: 
                    474:        bread (isomp->im_devvp, ifhp->ifid_lbn, imp->im_bsize, NOCRED, &bp);
                    475: 
                    476:        dirp = bp->b_un.b_addr + ifhp->ifid_offset;
                    477: 
                    478:        if (ifhp->ifid_offset + isonum_711 (dirp) >= imp->im_bsize) {
                    479:                brelse (bp);
                    480:                return (EINVAL);
                    481:        }
                    482: 
                    483:        tvp.v_mount = mp;
                    484:        ip = VTOI(&tvp);
                    485:        ip->i_vnode = &tvp;
                    486:        ip->i_dev = imp->im_dev;
                    487:        if (error = iso_iget(ip, ifhp->ifid_ino, &nip, dirp)) {
                    488:                *vpp = NULLVP;
                    489:                brelse (bp);
                    490:                return (error);
                    491:        }
                    492:        ip = nip;
                    493:        *vpp = ITOV(ip);
                    494:        brelse (bp);
                    495:        return (0);
                    496: #endif
                    497: }
                    498: 
                    499: /*
                    500:  * Vnode pointer to File handle
                    501:  */
                    502: /* ARGSUSED */
                    503: isofs_vptofh(vp, fhp)
                    504:        struct vnode *vp;
                    505:        struct fid *fhp;
                    506: {
                    507:        return (EINVAL);
                    508: #if 0
                    509:        register struct inode *ip = VTOI(vp);
                    510:        register struct ufid *ufhp;
                    511: 
                    512:        ufhp = (struct ufid *)fhp;
                    513:        ufhp->ufid_len = sizeof(struct ufid);
                    514:        ufhp->ufid_ino = ip->i_number;
                    515:        ufhp->ufid_gen = ip->i_gen;
                    516:        return (0);
                    517: #endif
                    518: }

unix.superglobalmegacorp.com

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