[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.31

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

CVSweb <webmaster@jp.NetBSD.org>