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

Annotation of src/sys/adosfs/advfsops.c, Revision 1.42

1.42    ! jdolecek    1: /*     $NetBSD: advfsops.c,v 1.41 1999/11/15 20:55:48 tron Exp $       */
1.4       cgd         2:
1.1       chopps      3: /*
                      4:  * Copyright (c) 1994 Christian E. Hopps
1.17      mhitch      5:  * Copyright (c) 1996 Matthias Scheler
1.1       chopps      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 Christian E. Hopps.
                     19:  * 4. The name of the author may not be used to endorse or promote products
                     20:  *    derived from this software without specific prior written permission
                     21:  *
                     22:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     23:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
                     24:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
                     25:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
                     26:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
                     27:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
                     28:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
                     29:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
                     30:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
                     31:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     32:  */
1.29      jonathan   33:
                     34: #if defined(_KERNEL) && !defined(_LKM)
                     35: #include "opt_compat_netbsd.h"
                     36: #endif
                     37:
1.1       chopps     38: #include <sys/param.h>
                     39: #include <sys/systm.h>
                     40: #include <sys/vnode.h>
                     41: #include <sys/mount.h>
1.2       chopps     42: #include <sys/proc.h>
1.1       chopps     43: #include <sys/time.h>
                     44: #include <sys/malloc.h>
1.31      thorpej    45: #include <sys/pool.h>
1.1       chopps     46: #include <sys/disklabel.h>
                     47: #include <miscfs/specfs/specdev.h> /* XXX */
                     48: #include <sys/fcntl.h>
                     49: #include <sys/namei.h>
                     50: #include <sys/ioctl.h>
                     51: #include <sys/queue.h>
                     52: #include <sys/buf.h>
                     53: #include <adosfs/adosfs.h>
                     54:
1.16      christos   55: void adosfs_init __P((void));
1.42    ! jdolecek   56: void adosfs_done __P((void));
1.24      cgd        57: int adosfs_mount __P((struct mount *, const char *, void *, struct nameidata *,
1.16      christos   58:                      struct proc *));
                     59: int adosfs_start __P((struct mount *, int, struct proc *));
                     60: int adosfs_unmount __P((struct mount *, int, struct proc *));
                     61: int adosfs_root __P((struct mount *, struct vnode **));
                     62: int adosfs_quotactl __P((struct mount *, int, uid_t, caddr_t, struct proc *));
                     63: int adosfs_statfs __P((struct mount *, struct statfs *, struct proc *));
                     64: int adosfs_sync __P((struct mount *, int, struct ucred *, struct proc *));
                     65: int adosfs_vget __P((struct mount *, ino_t, struct vnode **));
1.35      wrstuden   66: int adosfs_fhtovp __P((struct mount *, struct fid *, struct vnode **));
                     67: int adosfs_checkexp __P((struct mount *, struct mbuf *, int *,
                     68:                       struct ucred **));
1.16      christos   69: int adosfs_vptofh __P((struct vnode *, struct fid *));
                     70:
                     71: int adosfs_mountfs __P((struct vnode *, struct mount *, struct proc *));
1.17      mhitch     72: int adosfs_loadbitmap __P((struct adosfsmount *));
1.28      fvdl       73: int adosfs_sysctl __P((int *, u_int, void *, size_t *, void *, size_t,
                     74:                        struct proc *));
                     75:
                     76: struct simplelock adosfs_hashlock;
1.16      christos   77:
1.31      thorpej    78: struct pool adosfs_node_pool;
                     79:
1.1       chopps     80: int
                     81: adosfs_mount(mp, path, data, ndp, p)
                     82:        struct mount *mp;
1.24      cgd        83:        const char *path;
                     84:        void *data;
1.1       chopps     85:        struct nameidata *ndp;
                     86:        struct proc *p;
                     87: {
1.9       mycroft    88:        struct vnode *devvp;
1.1       chopps     89:        struct adosfs_args args;
1.9       mycroft    90:        struct adosfsmount *amp;
1.12      mycroft    91:        size_t size;
1.1       chopps     92:        int error;
1.9       mycroft    93:        mode_t accessmode;
1.1       chopps     94:
1.16      christos   95:        error = copyin(data, (caddr_t)&args, sizeof(struct adosfs_args));
                     96:        if (error)
1.1       chopps     97:                return(error);
                     98:
1.14      chopps     99: #if 0
1.1       chopps    100:        if (mp->mnt_flag & MNT_UPDATE)
1.9       mycroft   101:                return (EOPNOTSUPP);
1.14      chopps    102: #endif
1.9       mycroft   103:        if ((mp->mnt_flag & MNT_RDONLY) == 0)
                    104:                return (EROFS);
                    105:        /*
1.14      chopps    106:         * If updating, check whether changing from read-only to
                    107:         * read/write; if there is no device name, that's all we do.
                    108:         */
                    109:        if (mp->mnt_flag & MNT_UPDATE) {
                    110:                amp = VFSTOADOSFS(mp);
                    111:                if (args.fspec == 0)
                    112:                        return (vfs_export(mp, &amp->export, &args.export));
                    113:        }
                    114:        /*
1.9       mycroft   115:         * Not an update, or updating the name: look up the name
                    116:         * and verify that it refers to a sensible block device.
1.1       chopps    117:         */
1.2       chopps    118:        NDINIT(ndp, LOOKUP, FOLLOW, UIO_USERSPACE, args.fspec, p);
1.16      christos  119:        if ((error = namei(ndp)) != 0)
1.2       chopps    120:                return (error);
1.9       mycroft   121:        devvp = ndp->ni_vp;
1.2       chopps    122:
1.9       mycroft   123:        if (devvp->v_type != VBLK) {
                    124:                vrele(devvp);
1.2       chopps    125:                return (ENOTBLK);
1.1       chopps    126:        }
1.9       mycroft   127:        if (major(devvp->v_rdev) >= nblkdev) {
                    128:                vrele(devvp);
1.2       chopps    129:                return (ENXIO);
1.1       chopps    130:        }
1.9       mycroft   131:        /*
                    132:         * If mount by non-root, then verify that user has necessary
                    133:         * permissions on the device.
                    134:         */
                    135:        if (p->p_ucred->cr_uid != 0) {
                    136:                accessmode = VREAD;
                    137:                if ((mp->mnt_flag & MNT_RDONLY) == 0)
                    138:                        accessmode |= VWRITE;
1.28      fvdl      139:                vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
1.16      christos  140:                error = VOP_ACCESS(devvp, accessmode, p->p_ucred, p);
                    141:                if (error) {
1.9       mycroft   142:                        vput(devvp);
                    143:                        return (error);
                    144:                }
1.28      fvdl      145:                VOP_UNLOCK(devvp, 0);
1.9       mycroft   146:        }
1.14      chopps    147: /* MNT_UPDATE? */
1.16      christos  148:        if ((error = adosfs_mountfs(devvp, mp, p)) != 0) {
1.9       mycroft   149:                vrele(devvp);
                    150:                return (error);
                    151:        }
                    152:        amp = VFSTOADOSFS(mp);
                    153:        amp->uid = args.uid;
                    154:        amp->gid = args.gid;
                    155:        amp->mask = args.mask;
                    156:        (void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size);
1.30      perry     157:        memset(mp->mnt_stat.f_mntonname + size, 0, MNAMELEN - size);
1.9       mycroft   158:        (void) copyinstr(args.fspec, mp->mnt_stat.f_mntfromname, MNAMELEN - 1,
                    159:            &size);
1.30      perry     160:        memset(mp->mnt_stat.f_mntfromname + size, 0, MNAMELEN - size);
1.9       mycroft   161:        return (0);
1.1       chopps    162: }
                    163:
                    164: int
1.9       mycroft   165: adosfs_mountfs(devvp, mp, p)
                    166:        struct vnode *devvp;
1.1       chopps    167:        struct mount *mp;
                    168:        struct proc *p;
                    169: {
                    170:        struct disklabel dl;
                    171:        struct partition *parp;
1.10      mycroft   172:        struct adosfsmount *amp;
1.17      mhitch    173:        struct buf *bp;
1.2       chopps    174:        struct vnode *rvp;
1.11      cgd       175:        int error, part, i;
1.1       chopps    176:
1.9       mycroft   177:        part = DISKPART(devvp->v_rdev);
1.2       chopps    178:        amp = NULL;
1.9       mycroft   179:
1.1       chopps    180:        /*
1.9       mycroft   181:         * Disallow multiple mounts of the same device.
                    182:         * Disallow mounting of a device that is currently in use
                    183:         * (except for root, which might share swap device for miniroot).
                    184:         * Flush out any old buffers remaining from a previous use.
1.1       chopps    185:         */
1.16      christos  186:        if ((error = vfs_mountedon(devvp)) != 0)
1.2       chopps    187:                return (error);
1.9       mycroft   188:        if (vcount(devvp) > 1 && devvp != rootvp)
1.2       chopps    189:                return (EBUSY);
1.16      christos  190:        if ((error = vinvalbuf(devvp, V_SAVE, p->p_ucred, p, 0, 0)) != 0)
1.2       chopps    191:                return (error);
1.1       chopps    192:
                    193:        /*
1.2       chopps    194:         * open blkdev and read root block
1.1       chopps    195:         */
1.16      christos  196:        if ((error = VOP_OPEN(devvp, FREAD, NOCRED, p)) != 0)
1.2       chopps    197:                return (error);
1.16      christos  198:        error = VOP_IOCTL(devvp, DIOCGDINFO,(caddr_t)&dl, FREAD, NOCRED, p);
                    199:        if (error)
1.1       chopps    200:                goto fail;
                    201:
                    202:        parp = &dl.d_partitions[part];
1.10      mycroft   203:        amp = malloc(sizeof(struct adosfsmount), M_ADOSFSMNT, M_WAITOK);
1.30      perry     204:        memset((char *)amp, 0, (u_long)sizeof(struct adosfsmount));
1.1       chopps    205:        amp->mp = mp;
1.17      mhitch    206:        if (dl.d_type == DTYPE_FLOPPY) {
                    207:                amp->bsize = dl.d_secsize;
                    208:                amp->secsperblk = 1;
                    209:        }
                    210:        else {
                    211:                amp->bsize = parp->p_fsize * parp->p_frag;
                    212:                amp->secsperblk = parp->p_frag;
                    213:        }
                    214:        amp->rootb = (parp->p_size / amp->secsperblk - 1 + parp->p_cpg) >> 1;
                    215:        amp->numblks = parp->p_size / amp->secsperblk - parp->p_cpg;
                    216:
                    217:        bp = NULL;
                    218:        if ((error = bread(devvp, (daddr_t)BBOFF,
1.32      bouyer    219:                           amp->bsize, NOCRED, &bp)) != 0) {
                    220:                brelse(bp);
1.17      mhitch    221:                goto fail;
1.32      bouyer    222:        }
1.17      mhitch    223:        amp->dostype = adoswordn(bp, 0);
                    224:        brelse(bp);
                    225:
                    226:        if (amp->dostype < 0x444f5300 || amp->dostype > 0x444f5305) {
                    227:                error = EINVAL;
                    228:                goto fail;
                    229:        }
                    230:
1.1       chopps    231:        amp->nwords = amp->bsize >> 2;
1.17      mhitch    232:        amp->dbsize = amp->bsize - (IS_FFS(amp) ? 0 : OFS_DATA_OFFSET);
1.9       mycroft   233:        amp->devvp = devvp;
1.1       chopps    234:
                    235:        mp->mnt_data = (qaddr_t)amp;
1.9       mycroft   236:         mp->mnt_stat.f_fsid.val[0] = (long)devvp->v_rdev;
1.1       chopps    237:         mp->mnt_stat.f_fsid.val[1] = makefstype(MOUNT_ADOSFS);
1.9       mycroft   238:        mp->mnt_flag |= MNT_LOCAL;
1.1       chopps    239:
                    240:        /*
                    241:         * init anode table.
                    242:         */
                    243:        for (i = 0; i < ANODEHASHSZ; i++)
                    244:                LIST_INIT(&amp->anodetab[i]);
                    245:
                    246:        /*
                    247:         * get the root anode, if not a valid fs this will fail.
                    248:         */
1.16      christos  249:        if ((error = VFS_ROOT(mp, &rvp)) != 0)
1.1       chopps    250:                goto fail;
1.17      mhitch    251:        /* allocate and load bitmap, set free space */
                    252:        amp->bitmap = malloc(((amp->numblks + 31) / 32) * sizeof(*amp->bitmap),
                    253:            M_ADOSFSBITMAP, M_WAITOK);
                    254:        if (amp->bitmap)
                    255:                adosfs_loadbitmap(amp);
                    256:        if (mp->mnt_flag & MNT_RDONLY && amp->bitmap) {
                    257:                /*
                    258:                 * Don't need the bitmap any more if it's read-only.
                    259:                 */
                    260:                free(amp->bitmap, M_ADOSFSBITMAP);
                    261:                amp->bitmap = NULL;
                    262:        }
1.2       chopps    263:        vput(rvp);
                    264:
1.1       chopps    265:        return(0);
1.9       mycroft   266:
1.1       chopps    267: fail:
1.38      wrstuden  268:        vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
1.9       mycroft   269:        (void) VOP_CLOSE(devvp, FREAD, NOCRED, p);
1.38      wrstuden  270:        VOP_UNLOCK(devvp, 0);
1.17      mhitch    271:        if (amp && amp->bitmap)
                    272:                free(amp->bitmap, M_ADOSFSBITMAP);
1.2       chopps    273:        if (amp)
                    274:                free(amp, M_ADOSFSMNT);
1.9       mycroft   275:        return (error);
1.1       chopps    276: }
                    277:
                    278: int
                    279: adosfs_start(mp, flags, p)
                    280:        struct mount *mp;
                    281:        int flags;
                    282:        struct proc *p;
                    283: {
1.9       mycroft   284:
                    285:        return (0);
1.1       chopps    286: }
                    287:
                    288: int
1.9       mycroft   289: adosfs_unmount(mp, mntflags, p)
1.1       chopps    290:        struct mount *mp;
1.9       mycroft   291:        int mntflags;
1.1       chopps    292:        struct proc *p;
                    293: {
1.10      mycroft   294:        struct adosfsmount *amp;
1.9       mycroft   295:        int error, flags;
1.1       chopps    296:
1.9       mycroft   297:        flags = 0;
                    298:        if (mntflags & MNT_FORCE)
                    299:                flags |= FORCECLOSE;
1.16      christos  300:        if ((error = vflush(mp, NULLVP, flags)) != 0)
1.9       mycroft   301:                return (error);
1.1       chopps    302:        amp = VFSTOADOSFS(mp);
1.39      enami     303:        if (amp->devvp->v_type != VBAD)
1.41      tron      304:                amp->devvp->v_specmountpoint = NULL;
1.37      wrstuden  305:        vn_lock(amp->devvp, LK_EXCLUSIVE | LK_RETRY);
1.9       mycroft   306:        error = VOP_CLOSE(amp->devvp, FREAD, NOCRED, p);
1.37      wrstuden  307:        vput(amp->devvp);
1.17      mhitch    308:        if (amp->bitmap)
                    309:                free(amp->bitmap, M_ADOSFSBITMAP);
1.1       chopps    310:        free(amp, M_ADOSFSMNT);
1.9       mycroft   311:        mp->mnt_data = (qaddr_t)0;
1.2       chopps    312:        mp->mnt_flag &= ~MNT_LOCAL;
                    313:        return (error);
1.1       chopps    314: }
                    315:
                    316: int
                    317: adosfs_root(mp, vpp)
                    318:        struct mount *mp;
                    319:        struct vnode **vpp;
                    320: {
1.2       chopps    321:        struct vnode *nvp;
                    322:        int error;
1.1       chopps    323:
1.16      christos  324:        if ((error = VFS_VGET(mp, (ino_t)VFSTOADOSFS(mp)->rootb, &nvp)) != 0)
1.2       chopps    325:                return (error);
1.17      mhitch    326:        /* XXX verify it's a root block? */
1.2       chopps    327:        *vpp = nvp;
                    328:        return (0);
1.1       chopps    329: }
                    330:
                    331: int
                    332: adosfs_statfs(mp, sbp, p)
                    333:        struct mount *mp;
                    334:        struct statfs *sbp;
                    335:        struct proc *p;
                    336: {
1.10      mycroft   337:        struct adosfsmount *amp;
1.9       mycroft   338:
1.1       chopps    339:        amp = VFSTOADOSFS(mp);
1.28      fvdl      340: #ifdef COMPAT_09
                    341:        sbp->f_type = 16;
                    342: #else
1.1       chopps    343:        sbp->f_type = 0;
1.28      fvdl      344: #endif
1.1       chopps    345:        sbp->f_bsize = amp->bsize;
1.17      mhitch    346:        sbp->f_iosize = amp->dbsize;
                    347:        sbp->f_blocks = amp->numblks;
                    348:        sbp->f_bfree = amp->freeblks;
                    349:        sbp->f_bavail = amp->freeblks;
1.1       chopps    350:        sbp->f_files = 0;               /* who knows */
                    351:        sbp->f_ffree = 0;               /* " " */
                    352:        if (sbp != &mp->mnt_stat) {
1.30      perry     353:                memcpy(sbp->f_mntonname, mp->mnt_stat.f_mntonname, MNAMELEN);
                    354:                memcpy(sbp->f_mntfromname, mp->mnt_stat.f_mntfromname, MNAMELEN);
1.1       chopps    355:        }
                    356:        strncpy(sbp->f_fstypename, mp->mnt_op->vfs_name, MFSNAMELEN);
1.9       mycroft   357:        return (0);
1.1       chopps    358: }
                    359:
1.2       chopps    360: /*
                    361:  * lookup an anode, check mount's hash table if not found, create
                    362:  * return locked and referenced al la vget(vp, 1);
                    363:  */
1.1       chopps    364: int
1.2       chopps    365: adosfs_vget(mp, an, vpp)
1.1       chopps    366:        struct mount *mp;
1.2       chopps    367:        ino_t an;
                    368:        struct vnode **vpp;
1.1       chopps    369: {
1.10      mycroft   370:        struct adosfsmount *amp;
1.2       chopps    371:        struct vnode *vp;
                    372:        struct anode *ap;
                    373:        struct buf *bp;
                    374:        char *nam, *tmp;
1.17      mhitch    375:        int namlen, error;
1.2       chopps    376:
                    377:        error = 0;
                    378:        amp = VFSTOADOSFS(mp);
                    379:        bp = NULL;
                    380:
                    381:        /*
                    382:         * check hash table. we are done if found
                    383:         */
1.16      christos  384:        if ((*vpp = adosfs_ahashget(mp, an)) != NULL)
1.2       chopps    385:                return (0);
                    386:
1.16      christos  387:        error = getnewvnode(VT_ADOSFS, mp, adosfs_vnodeop_p, &vp);
                    388:        if (error)
1.2       chopps    389:                return (error);
                    390:
                    391:        /*
                    392:         * setup, insert in hash, and lock before io.
                    393:         */
1.31      thorpej   394:        vp->v_data = ap = pool_get(&adosfs_node_pool, PR_WAITOK);
1.30      perry     395:        memset(ap, 0, sizeof(struct anode));
1.2       chopps    396:        ap->vp = vp;
                    397:        ap->amp = amp;
                    398:        ap->block = an;
                    399:        ap->nwords = amp->nwords;
                    400:        adosfs_ainshash(amp, ap);
                    401:
1.36      is        402:        if ((error = bread(amp->devvp, an * amp->bsize / DEV_BSIZE,
1.17      mhitch    403:                           amp->bsize, NOCRED, &bp)) != 0) {
1.32      bouyer    404:                brelse(bp);
1.2       chopps    405:                vput(vp);
                    406:                return (error);
                    407:        }
                    408:
                    409:        /*
                    410:         * get type and fill rest in based on that.
                    411:         */
                    412:        switch (ap->type = adosfs_getblktype(amp, bp)) {
                    413:        case AROOT:
                    414:                vp->v_type = VDIR;
                    415:                vp->v_flag |= VROOT;
                    416:                ap->mtimev.days = adoswordn(bp, ap->nwords - 10);
                    417:                ap->mtimev.mins = adoswordn(bp, ap->nwords - 9);
                    418:                ap->mtimev.ticks = adoswordn(bp, ap->nwords - 8);
                    419:                ap->created.days = adoswordn(bp, ap->nwords - 7);
                    420:                ap->created.mins = adoswordn(bp, ap->nwords - 6);
                    421:                ap->created.ticks = adoswordn(bp, ap->nwords - 5);
                    422:                break;
                    423:        case ALDIR:
                    424:        case ADIR:
                    425:                vp->v_type = VDIR;
                    426:                break;
                    427:        case ALFILE:
                    428:        case AFILE:
                    429:                vp->v_type = VREG;
                    430:                ap->fsize = adoswordn(bp, ap->nwords - 47);
                    431:                break;
                    432:        case ASLINK:            /* XXX soft link */
                    433:                vp->v_type = VLNK;
                    434:                /*
                    435:                 * convert from BCPL string and
                    436:                 * from: "part:dir/file" to: "/part/dir/file"
                    437:                 */
                    438:                nam = bp->b_data + (6 * sizeof(long));
1.17      mhitch    439:                namlen = strlen(nam);
1.2       chopps    440:                tmp = nam;
1.17      mhitch    441:                while (*tmp && *tmp != ':')
1.2       chopps    442:                        tmp++;
                    443:                if (*tmp == 0) {
                    444:                        ap->slinkto = malloc(namlen + 1, M_ANODE, M_WAITOK);
1.30      perry     445:                        memcpy(ap->slinkto, nam, namlen);
1.2       chopps    446:                } else if (*nam == ':') {
                    447:                        ap->slinkto = malloc(namlen + 1, M_ANODE, M_WAITOK);
1.30      perry     448:                        memcpy(ap->slinkto, nam, namlen);
1.2       chopps    449:                        ap->slinkto[0] = '/';
                    450:                } else {
                    451:                        ap->slinkto = malloc(namlen + 2, M_ANODE, M_WAITOK);
                    452:                        ap->slinkto[0] = '/';
1.30      perry     453:                        memcpy(&ap->slinkto[1], nam, namlen);
1.2       chopps    454:                        ap->slinkto[tmp - nam + 1] = '/';
                    455:                        namlen++;
                    456:                }
                    457:                ap->slinkto[namlen] = 0;
1.19      mhitch    458:                ap->fsize = namlen;
1.2       chopps    459:                break;
                    460:        default:
                    461:                brelse(bp);
                    462:                vput(vp);
                    463:                return (EINVAL);
                    464:        }
1.17      mhitch    465:
                    466:        /*
                    467:         * Get appropriate data from this block;  hard link needs
                    468:         * to get other data from the "real" block.
                    469:         */
                    470:
                    471:        /*
                    472:         * copy in name (from original block)
                    473:         */
1.20      thorpej   474:        nam = bp->b_data + (ap->nwords - 20) * sizeof(u_int32_t);
1.17      mhitch    475:        namlen = *(u_char *)nam++;
                    476:        if (namlen > 30) {
                    477: #ifdef DIAGNOSTIC
1.23      christos  478:                printf("adosfs: aget: name length too long blk %d\n", an);
1.17      mhitch    479: #endif
                    480:                brelse(bp);
                    481:                vput(vp);
                    482:                return (EINVAL);
                    483:        }
1.30      perry     484:        memcpy(ap->name, nam, namlen);
1.17      mhitch    485:        ap->name[namlen] = 0;
                    486:
1.2       chopps    487:        /*
                    488:         * if dir alloc hash table and copy it in
                    489:         */
                    490:        if (vp->v_type == VDIR) {
                    491:                int i;
                    492:
                    493:                ap->tab = malloc(ANODETABSZ(ap) * 2, M_ANODE, M_WAITOK);
                    494:                ap->ntabent = ANODETABENT(ap);
                    495:                ap->tabi = (int *)&ap->tab[ap->ntabent];
1.30      perry     496:                memset(ap->tabi, 0, ANODETABSZ(ap));
1.2       chopps    497:                for (i = 0; i < ap->ntabent; i++)
                    498:                        ap->tab[i] = adoswordn(bp, i + 6);
                    499:        }
                    500:
                    501:        /*
                    502:         * misc.
                    503:         */
                    504:        ap->pblock = adoswordn(bp, ap->nwords - 3);
                    505:        ap->hashf = adoswordn(bp, ap->nwords - 4);
                    506:        ap->linknext = adoswordn(bp, ap->nwords - 10);
                    507:        ap->linkto = adoswordn(bp, ap->nwords - 11);
1.5       chopps    508:
                    509:        /*
                    510:         * setup last indirect block cache.
                    511:         */
                    512:        ap->lastlindblk = 0;
1.17      mhitch    513:        if (ap->type == AFILE)  {
1.5       chopps    514:                ap->lastindblk = ap->block;
1.17      mhitch    515:                if (adoswordn(bp, ap->nwords - 10))
                    516:                        ap->linkto = ap->block;
                    517:        } else if (ap->type == ALFILE) {
1.5       chopps    518:                ap->lastindblk = ap->linkto;
1.17      mhitch    519:                brelse(bp);
                    520:                bp = NULL;
1.36      is        521:                error = bread(amp->devvp, ap->linkto * amp->bsize / DEV_BSIZE,
1.17      mhitch    522:                    amp->bsize, NOCRED, &bp);
1.32      bouyer    523:                if (error) {
                    524:                        brelse(bp);
                    525:                        vput(vp);
                    526:                        return (error);
                    527:                }
1.17      mhitch    528:                ap->fsize = adoswordn(bp, ap->nwords - 47);
                    529:                /*
                    530:                 * Should ap->block be set to the real file header block?
                    531:                 */
                    532:                ap->block = ap->linkto;
                    533:        }
1.5       chopps    534:
1.8       chopps    535:        if (ap->type == AROOT) {
1.17      mhitch    536:                ap->adprot = 15;
1.8       chopps    537:                ap->uid = amp->uid;
                    538:                ap->gid = amp->gid;
                    539:        } else {
1.17      mhitch    540:                ap->adprot = adoswordn(bp, ap->nwords - 48) ^ 15;
1.25      kleink    541:                /*
                    542:                 * ADOS directories do not have a `x' protection bit as
                    543:                 * it is known in VFS; this functionality is fulfilled
                    544:                 * by the ADOS `r' bit.
                    545:                 *
                    546:                 * To retain the ADOS behaviour, fake execute permissions
                    547:                 * in that case.
                    548:                 */
1.26      kleink    549:                if ((ap->type == ADIR || ap->type == ALDIR) &&
                    550:                    (ap->adprot & 0x00000008) == 0)
                    551:                        ap->adprot &= ~0x00000002;
1.25      kleink    552:
1.8       chopps    553:                /*
                    554:                 * Get uid/gid from extensions in file header
                    555:                 * (really need to know if this is a muFS partition)
                    556:                 */
                    557:                ap->uid = (adoswordn(bp, ap->nwords - 49) >> 16) & 0xffff;
                    558:                ap->gid = adoswordn(bp, ap->nwords - 49) & 0xffff;
                    559:                if (ap->uid || ap->gid) {
                    560:                        if (ap->uid == 0xffff)
                    561:                                ap->uid = 0;
                    562:                        if (ap->gid == 0xffff)
                    563:                                ap->gid = 0;
                    564:                        ap->adprot |= 0x40000000;       /* Kludge */
                    565:                }
                    566:                else {
                    567:                        /*
                    568:                         * uid & gid extension don't exist,
                    569:                         * so use the mount-point uid/gid
                    570:                         */
                    571:                        ap->uid = amp->uid;
                    572:                        ap->gid = amp->gid;
                    573:                }
                    574:        }
1.2       chopps    575:        ap->mtime.days = adoswordn(bp, ap->nwords - 23);
                    576:        ap->mtime.mins = adoswordn(bp, ap->nwords - 22);
                    577:        ap->mtime.ticks = adoswordn(bp, ap->nwords - 21);
                    578:
1.17      mhitch    579:        *vpp = vp;              /* return vp */
                    580:        brelse(bp);             /* release buffer */
                    581:        return (0);
                    582: }
                    583:
                    584: /*
                    585:  * Load the bitmap into memory, and count the number of available
                    586:  * blocks.
                    587:  * The bitmap will be released if the filesystem is read-only;  it's
                    588:  * only needed to find the free space.
                    589:  */
                    590: int
                    591: adosfs_loadbitmap(amp)
                    592:        struct adosfsmount *amp;
                    593: {
                    594:        struct buf *bp, *mapbp;
                    595:        u_long bn;
                    596:        int blkix, endix, mapix;
                    597:        int bmsize;
                    598:        int error;
                    599:
                    600:        bp = mapbp = NULL;
                    601:        bn = amp->rootb;
1.36      is        602:        if ((error = bread(amp->devvp, bn * amp->bsize / DEV_BSIZE, amp->bsize,
1.32      bouyer    603:            NOCRED, &bp)) != 0) {
                    604:                brelse(bp);
1.17      mhitch    605:                return (error);
1.32      bouyer    606:        }
1.17      mhitch    607:        blkix = amp->nwords - 49;
                    608:        endix = amp->nwords - 24;
                    609:        mapix = 0;
                    610:        bmsize = (amp->numblks + 31) / 32;
                    611:        while (mapix < bmsize) {
                    612:                int n;
                    613:                u_long bits;
                    614:
                    615:                if (adoswordn(bp, blkix) == 0)
                    616:                        break;
                    617:                if (mapbp != NULL)
                    618:                        brelse(mapbp);
                    619:                if ((error = bread(amp->devvp,
1.36      is        620:                    adoswordn(bp, blkix) * amp->bsize / DEV_BSIZE, amp->bsize,
1.17      mhitch    621:                     NOCRED, &mapbp)) != 0)
                    622:                        break;
                    623:                if (adoscksum(mapbp, amp->nwords)) {
1.2       chopps    624: #ifdef DIAGNOSTIC
1.23      christos  625:                        printf("adosfs: loadbitmap - cksum of blk %d failed\n",
1.21      christos  626:                            adoswordn(bp, blkix));
1.1       chopps    627: #endif
1.17      mhitch    628:                        /* XXX Force read-only?  Set free space 0? */
                    629:                        break;
                    630:                }
                    631:                n = 1;
                    632:                while (n < amp->nwords && mapix < bmsize) {
                    633:                        amp->bitmap[mapix++] = bits = adoswordn(mapbp, n);
                    634:                        ++n;
                    635:                        if (mapix == bmsize && amp->numblks & 31)
                    636:                                bits &= ~(0xffffffff << (amp->numblks & 31));
                    637:                        while (bits) {
                    638:                                if (bits & 1)
                    639:                                        ++amp->freeblks;
                    640:                                bits >>= 1;
                    641:                        }
                    642:                }
                    643:                ++blkix;
                    644:                if (mapix < bmsize && blkix == endix) {
                    645:                        bn = adoswordn(bp, blkix);
                    646:                        brelse(bp);
1.36      is        647:                        if ((error = bread(amp->devvp, bn * amp->bsize / DEV_BSIZE,
1.17      mhitch    648:                            amp->bsize, NOCRED, &bp)) != 0)
                    649:                                break;
                    650:                        /*
                    651:                         * Why is there no checksum on these blocks?
                    652:                         */
                    653:                        blkix = 0;
                    654:                        endix = amp->nwords - 1;
                    655:                }
                    656:        }
                    657:        if (bp)
1.2       chopps    658:                brelse(bp);
1.17      mhitch    659:        if (mapbp)
                    660:                brelse(mapbp);
                    661:        return (error);
1.1       chopps    662: }
                    663:
1.14      chopps    664:
                    665: /*
                    666:  * File handle to vnode
                    667:  *
                    668:  * Have to be really careful about stale file handles:
                    669:  * - check that the inode number is in range
                    670:  * - call iget() to get the locked inode
                    671:  * - check for an unallocated inode (i_mode == 0)
                    672:  * - check that the generation number matches
                    673:  */
                    674:
                    675: struct ifid {
                    676:        ushort  ifid_len;
                    677:        ushort  ifid_pad;
                    678:        int     ifid_ino;
                    679:        long    ifid_start;
                    680: };
                    681:
1.1       chopps    682: int
1.35      wrstuden  683: adosfs_fhtovp(mp, fhp, vpp)
1.1       chopps    684:        struct mount *mp;
                    685:        struct fid *fhp;
                    686:        struct vnode **vpp;
                    687: {
1.14      chopps    688:        struct ifid *ifhp = (struct ifid *)fhp;
1.16      christos  689: #if 0
1.14      chopps    690:        struct anode *ap;
1.16      christos  691: #endif
1.14      chopps    692:        struct vnode *nvp;
                    693:        int error;
                    694:
1.1       chopps    695: #ifdef ADOSFS_DIAGNOSTIC
1.23      christos  696:        printf("adfhtovp(%x, %x, %x)\n", mp, fhp, vpp);
1.1       chopps    697: #endif
1.14      chopps    698:
1.16      christos  699:        if ((error = VFS_VGET(mp, ifhp->ifid_ino, &nvp)) != 0) {
1.14      chopps    700:                *vpp = NULLVP;
                    701:                return (error);
                    702:        }
                    703: #if 0
                    704:        ap = VTOA(nvp);
                    705:        if (ap->inode.iso_mode == 0) {
                    706:                vput(nvp);
                    707:                *vpp = NULLVP;
                    708:                return (ESTALE);
                    709:        }
                    710: #endif
                    711:        *vpp = nvp;
1.35      wrstuden  712:        return(0);
                    713: }
                    714:
                    715: int
                    716: adosfs_checkexp(mp, nam, exflagsp, credanonp)
                    717:        struct mount *mp;
                    718:        struct mbuf *nam;
                    719:        int *exflagsp;
                    720:        struct ucred **credanonp;
                    721: {
                    722:        struct adosfsmount *amp = VFSTOADOSFS(mp);
                    723: #if 0
                    724:        struct anode *ap;
                    725: #endif
                    726:        struct netcred *np;
                    727:
                    728: #ifdef ADOSFS_DIAGNOSTIC
                    729:        printf("adcheckexp(%x, %x, %x)\n", mp, nam, exflagsp);
                    730: #endif
                    731:
                    732:        /*
                    733:         * Get the export permission structure for this <mp, client> tuple.
                    734:         */
                    735:        np = vfs_export_lookup(mp, &amp->export, nam);
                    736:        if (np == NULL)
                    737:                return (EACCES);
                    738:
1.14      chopps    739:        *exflagsp = np->netc_exflags;
                    740:        *credanonp = &np->netc_anon;
1.1       chopps    741:        return(0);
                    742: }
                    743:
                    744: int
                    745: adosfs_vptofh(vp, fhp)
                    746:        struct vnode *vp;
                    747:        struct fid *fhp;
                    748: {
1.14      chopps    749:        struct anode *ap = VTOA(vp);
                    750:        struct ifid *ifhp;
                    751:
                    752:        ifhp = (struct ifid *)fhp;
                    753:        ifhp->ifid_len = sizeof(struct ifid);
                    754:
                    755:        ifhp->ifid_ino = ap->block;
                    756:        ifhp->ifid_start = ap->block;
                    757:
1.1       chopps    758: #ifdef ADOSFS_DIAGNOSTIC
1.23      christos  759:        printf("advptofh(%x, %x)\n", vp, fhp);
1.1       chopps    760: #endif
                    761:        return(0);
                    762: }
                    763:
                    764: int
1.2       chopps    765: adosfs_quotactl(mp, cmds, uid, arg, p)
                    766:        struct mount *mp;
                    767:        int cmds;
                    768:        uid_t uid;
                    769:        caddr_t arg;
                    770:        struct proc *p;
                    771: {
                    772:        return(EOPNOTSUPP);
                    773: }
                    774:
                    775: int
1.16      christos  776: adosfs_sync(mp, waitfor, uc, p)
1.2       chopps    777:        struct mount *mp;
                    778:        int waitfor;
1.16      christos  779:        struct ucred *uc;
                    780:        struct proc *p;
1.1       chopps    781: {
                    782: #ifdef ADOSFS_DIAGNOSTIC
1.23      christos  783:        printf("ad_sync(%x, %x)\n", mp, waitfor);
1.1       chopps    784: #endif
                    785:        return(0);
                    786: }
                    787:
1.16      christos  788: void
1.2       chopps    789: adosfs_init()
                    790: {
1.28      fvdl      791:        simple_lock_init(&adosfs_hashlock);
1.31      thorpej   792:
                    793:        pool_init(&adosfs_node_pool, sizeof(struct anode), 0, 0, 0,
                    794:            "adosndpl", 0, pool_page_alloc_nointr, pool_page_free_nointr,
                    795:            M_ANODE);
1.28      fvdl      796: }
                    797:
1.42    ! jdolecek  798: void
        !           799: adosfs_done()
        !           800: {
        !           801:        pool_destroy(&adosfs_node_pool);
        !           802: }
        !           803:
1.28      fvdl      804: int
                    805: adosfs_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
                    806:        int *name;
                    807:        u_int namelen;
                    808:        void *oldp;
                    809:        size_t *oldlenp;
                    810:        void *newp;
                    811:        size_t newlen;
                    812:        struct proc *p;
                    813: {
                    814:        return (EOPNOTSUPP);
1.2       chopps    815: }
                    816:
1.1       chopps    817: /*
                    818:  * vfs generic function call table
                    819:  */
1.27      thorpej   820:
                    821: extern struct vnodeopv_desc adosfs_vnodeop_opv_desc;
                    822:
                    823: struct vnodeopv_desc *adosfs_vnodeopv_descs[] = {
                    824:        &adosfs_vnodeop_opv_desc,
                    825:        NULL,
                    826: };
                    827:
1.1       chopps    828: struct vfsops adosfs_vfsops = {
                    829:        MOUNT_ADOSFS,
                    830:        adosfs_mount,
                    831:        adosfs_start,
                    832:        adosfs_unmount,
                    833:        adosfs_root,
                    834:        adosfs_quotactl,
                    835:        adosfs_statfs,
                    836:        adosfs_sync,
1.2       chopps    837:        adosfs_vget,
1.1       chopps    838:        adosfs_fhtovp,
                    839:        adosfs_vptofh,
                    840:        adosfs_init,
1.42    ! jdolecek  841:        adosfs_done,
1.28      fvdl      842:        adosfs_sysctl,
1.27      thorpej   843:        NULL,                           /* vfs_mountroot */
1.35      wrstuden  844:        adosfs_checkexp,
1.27      thorpej   845:        adosfs_vnodeopv_descs,
                    846: };

CVSweb <webmaster@jp.NetBSD.org>