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

Annotation of src/sys/adosfs/advnops.c, Revision 1.31

1.31    ! christos    1: /*     $NetBSD: advnops.c,v 1.30 1996/09/07 12:40:22 mycroft Exp $     */
1.8       cgd         2:
1.1       chopps      3: /*
                      4:  * Copyright (c) 1994 Christian E. Hopps
1.27      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:  */
                     33: #include <sys/param.h>
1.13      cgd        34: #include <sys/systm.h>
1.1       chopps     35: #include <sys/vnode.h>
                     36: #include <sys/mount.h>
                     37: #include <sys/time.h>
                     38: #include <sys/queue.h>
                     39: #include <sys/namei.h>
                     40: #include <sys/buf.h>
                     41: #include <sys/dirent.h>
1.6       chopps     42: #include <sys/malloc.h>
1.1       chopps     43: #include <sys/stat.h>
1.6       chopps     44: #include <sys/unistd.h>
1.25      christos   45: #include <sys/proc.h>
1.29      mycroft    46:
                     47: #include <miscfs/genfs/genfs.h>
1.1       chopps     48: #include <miscfs/specfs/specdev.h>
                     49: #include <adosfs/adosfs.h>
                     50:
                     51: extern struct vnodeops adosfs_vnodeops;
                     52:
1.29      mycroft    53: #define        adosfs_open     genfs_nullop
1.25      christos   54: int    adosfs_getattr  __P((void *));
                     55: int    adosfs_read     __P((void *));
                     56: int    adosfs_write    __P((void *));
                     57: int    adosfs_ioctl    __P((void *));
1.30      mycroft    58: #define        adosfs_poll     genfs_poll
1.25      christos   59: int    adosfs_strategy __P((void *));
1.26      christos   60: int    adosfs_link     __P((void *));
                     61: int    adosfs_symlink  __P((void *));
1.29      mycroft    62: #define        adosfs_abortop  genfs_abortop
1.25      christos   63: int    adosfs_lock     __P((void *));
                     64: int    adosfs_unlock   __P((void *));
                     65: int    adosfs_bmap     __P((void *));
                     66: int    adosfs_print    __P((void *));
                     67: int    adosfs_readdir  __P((void *));
                     68: int    adosfs_access   __P((void *));
                     69: int    adosfs_readlink __P((void *));
                     70: int    adosfs_inactive __P((void *));
                     71: int    adosfs_islocked __P((void *));
                     72: int    adosfs_reclaim  __P((void *));
                     73: int    adosfs_pathconf __P((void *));
                     74:
1.29      mycroft    75: #define adosfs_close   genfs_nullop
                     76: #define adosfs_fsync   genfs_nullop
1.25      christos   77: #ifdef NFSSERVER
                     78: int    lease_check __P((void *));
1.29      mycroft    79: #define        adosfs_lease_check      lease_check
1.25      christos   80: #else
1.29      mycroft    81: #define adosfs_lease_check     genfs_nullop
1.25      christos   82: #endif
1.29      mycroft    83: #define adosfs_seek    genfs_nullop
                     84: #define adosfs_vfree   genfs_nullop
1.25      christos   85:
1.29      mycroft    86: #define adosfs_advlock         genfs_eopnotsupp
                     87: #define adosfs_blkatoff        genfs_eopnotsupp
                     88: #define adosfs_bwrite  genfs_eopnotsupp
                     89: #define adosfs_create  genfs_eopnotsupp
                     90: #define adosfs_mkdir   genfs_eopnotsupp
                     91: #define adosfs_mknod   genfs_eopnotsupp
                     92: #define adosfs_mmap    genfs_eopnotsupp
                     93: #define adosfs_remove  genfs_eopnotsupp
                     94: #define adosfs_rename  genfs_eopnotsupp
                     95: #define adosfs_rmdir   genfs_eopnotsupp
                     96: #define adosfs_setattr         genfs_eopnotsupp
                     97: #define adosfs_truncate        genfs_eopnotsupp
                     98: #define adosfs_update  genfs_nullop
                     99: #define adosfs_valloc  genfs_eopnotsupp
1.25      christos  100:
                    101: struct vnodeopv_entry_desc adosfs_vnodeop_entries[] = {
1.29      mycroft   102:        { &vop_default_desc, vn_default_error },
                    103:        { &vop_lookup_desc, adosfs_lookup },            /* lookup */
                    104:        { &vop_create_desc, adosfs_create },            /* create */
                    105:        { &vop_mknod_desc, adosfs_mknod },              /* mknod */
                    106:        { &vop_open_desc, adosfs_open },                /* open */
                    107:        { &vop_close_desc, adosfs_close },              /* close */
                    108:        { &vop_access_desc, adosfs_access },            /* access */
                    109:        { &vop_getattr_desc, adosfs_getattr },          /* getattr */
                    110:        { &vop_setattr_desc, adosfs_setattr },          /* setattr */
                    111:        { &vop_read_desc, adosfs_read },                /* read */
                    112:        { &vop_write_desc, adosfs_write },              /* write */
                    113:        { &vop_lease_desc, adosfs_lease_check },        /* lease */
                    114:        { &vop_ioctl_desc, adosfs_ioctl },              /* ioctl */
1.30      mycroft   115:        { &vop_poll_desc, adosfs_poll },                /* poll */
1.29      mycroft   116:        { &vop_mmap_desc, adosfs_mmap },                /* mmap */
                    117:        { &vop_fsync_desc, adosfs_fsync },              /* fsync */
                    118:        { &vop_seek_desc, adosfs_seek },                /* seek */
                    119:        { &vop_remove_desc, adosfs_remove },            /* remove */
                    120:        { &vop_link_desc, adosfs_link },                /* link */
                    121:        { &vop_rename_desc, adosfs_rename },            /* rename */
                    122:        { &vop_mkdir_desc, adosfs_mkdir },              /* mkdir */
                    123:        { &vop_rmdir_desc, adosfs_rmdir },              /* rmdir */
                    124:        { &vop_symlink_desc, adosfs_symlink },          /* symlink */
                    125:        { &vop_readdir_desc, adosfs_readdir },          /* readdir */
                    126:        { &vop_readlink_desc, adosfs_readlink },        /* readlink */
                    127:        { &vop_abortop_desc, adosfs_abortop },          /* abortop */
                    128:        { &vop_inactive_desc, adosfs_inactive },        /* inactive */
                    129:        { &vop_reclaim_desc, adosfs_reclaim },          /* reclaim */
                    130:        { &vop_lock_desc, adosfs_lock },                /* lock */
                    131:        { &vop_unlock_desc, adosfs_unlock },            /* unlock */
                    132:        { &vop_bmap_desc, adosfs_bmap },                /* bmap */
                    133:        { &vop_strategy_desc, adosfs_strategy },        /* strategy */
                    134:        { &vop_print_desc, adosfs_print },              /* print */
                    135:        { &vop_islocked_desc, adosfs_islocked },        /* islocked */
                    136:        { &vop_pathconf_desc, adosfs_pathconf },        /* pathconf */
                    137:        { &vop_advlock_desc, adosfs_advlock },          /* advlock */
                    138:        { &vop_blkatoff_desc, adosfs_blkatoff },        /* blkatoff */
                    139:        { &vop_valloc_desc, adosfs_valloc },            /* valloc */
                    140:        { &vop_vfree_desc, adosfs_vfree },              /* vfree */
                    141:        { &vop_truncate_desc, adosfs_truncate },        /* truncate */
                    142:        { &vop_update_desc, adosfs_update },            /* update */
                    143:        { &vop_bwrite_desc, adosfs_bwrite },            /* bwrite */
1.25      christos  144:        { (struct vnodeop_desc*)NULL, (int(*) __P((void *)))NULL }
                    145: };
                    146:
                    147: struct vnodeopv_desc adosfs_vnodeop_opv_desc =
                    148:        { &adosfs_vnodeop_p, adosfs_vnodeop_entries };
                    149:
1.1       chopps    150: int
1.25      christos  151: adosfs_getattr(v)
                    152:        void *v;
                    153: {
1.6       chopps    154:        struct vop_getattr_args /* {
                    155:                struct vnode *a_vp;
                    156:                struct vattr *a_vap;
                    157:                struct ucred *a_cred;
                    158:                struct proc *a_p;
1.25      christos  159:        } */ *sp = v;
1.1       chopps    160:        struct vattr *vap;
1.20      mycroft   161:        struct adosfsmount *amp;
1.1       chopps    162:        struct anode *ap;
1.2       chopps    163:        u_long fblks;
1.1       chopps    164:
                    165: #ifdef ADOSFS_DIAGNOSTIC
1.6       chopps    166:        advopprint(sp);
1.1       chopps    167: #endif
1.6       chopps    168:        vap = sp->a_vap;
                    169:        ap = VTOA(sp->a_vp);
1.1       chopps    170:        amp = ap->amp;
                    171:        vattr_null(vap);
1.18      chopps    172:        vap->va_uid = ap->uid;
                    173:        vap->va_gid = ap->gid;
1.6       chopps    174:        vap->va_fsid = sp->a_vp->v_mount->mnt_stat.f_fsid.val[0];
1.23      jtc       175:        vap->va_atime.tv_sec = vap->va_mtime.tv_sec = vap->va_ctime.tv_sec =
1.18      chopps    176:                ap->mtime.days * 24 * 60 * 60 + ap->mtime.mins * 60 +
                    177:                ap->mtime.ticks / 50 + (8 * 365 + 2) * 24 * 60 * 60;
1.23      jtc       178:        vap->va_atime.tv_nsec = vap->va_mtime.tv_nsec = vap->va_ctime.tv_nsec = 0;
1.1       chopps    179:        vap->va_gen = 0;
                    180:        vap->va_flags = 0;
1.2       chopps    181:        vap->va_rdev = NODEV;
                    182:        vap->va_fileid = ap->block;
1.6       chopps    183:        vap->va_type = sp->a_vp->v_type;
1.2       chopps    184:        vap->va_mode = amp->mask & adunixprot(ap->adprot);
1.6       chopps    185:        if (sp->a_vp->v_type == VDIR) {
1.3       chopps    186:                vap->va_nlink = 1;      /* XXX bogus, oh well */
1.1       chopps    187:                vap->va_bytes = amp->bsize;
                    188:                vap->va_size = amp->bsize;
1.2       chopps    189:        } else {
                    190:                /*
                    191:                 * XXX actually we can track this if we were to walk the list
                    192:                 * of links if it exists.
1.27      mhitch    193:                 * XXX for now, just set nlink to 2 if this is a hard link
                    194:                 * to a file, or a file with a hard link.
1.2       chopps    195:                 */
1.27      mhitch    196:                vap->va_nlink = 1 + (ap->linkto != 0);
1.2       chopps    197:                /*
                    198:                 * round up to nearest blocks add number of file list
                    199:                 * blocks needed and mutiply by number of bytes per block.
                    200:                 */
1.27      mhitch    201:                fblks = howmany(ap->fsize, amp->dbsize);
1.2       chopps    202:                fblks += howmany(fblks, ANODENDATBLKENT(ap));
1.27      mhitch    203:                vap->va_bytes = fblks * amp->dbsize;
1.2       chopps    204:                vap->va_size = ap->fsize;
1.21      chopps    205:
1.27      mhitch    206:                vap->va_blocksize = amp->dbsize;
1.1       chopps    207:        }
                    208: #ifdef ADOSFS_DIAGNOSTIC
1.31    ! christos  209:        kprintf(" 0)");
1.1       chopps    210: #endif
                    211:        return(0);
                    212: }
                    213: /*
                    214:  * are things locked??? they need to be to avoid this being
                    215:  * deleted or changed (data block pointer blocks moving about.)
                    216:  */
                    217: int
1.25      christos  218: adosfs_read(v)
                    219:        void *v;
                    220: {
1.6       chopps    221:        struct vop_read_args /* {
                    222:                struct vnode *a_vp;
                    223:                struct uio *a_uio;
                    224:                int a_ioflag;
                    225:                struct ucred *a_cred;
1.25      christos  226:        } */ *sp = v;
1.20      mycroft   227:        struct adosfsmount *amp;
1.1       chopps    228:        struct anode *ap;
1.6       chopps    229:        struct uio *uio;
                    230:        struct buf *bp;
1.25      christos  231:        daddr_t lbn;
1.1       chopps    232:        int size, diff, error;
                    233:        long n, on;
                    234:
                    235: #ifdef ADOSFS_DIAGNOSTIC
1.6       chopps    236:        advopprint(sp);
1.1       chopps    237: #endif
                    238:        error = 0;
1.6       chopps    239:        uio = sp->a_uio;
                    240:        ap = VTOA(sp->a_vp);
1.1       chopps    241:        amp = ap->amp;
                    242:        /*
                    243:         * Return EOF for character devices, EIO for others
                    244:         */
1.6       chopps    245:        if (sp->a_vp->v_type != VREG) {
1.1       chopps    246:                error = EIO;
                    247:                goto reterr;
                    248:        }
                    249:        if (uio->uio_resid == 0)
                    250:                goto reterr;
                    251:        if (uio->uio_offset < 0) {
                    252:                error = EINVAL;
                    253:                goto reterr;
                    254:        }
                    255:
                    256:        /*
                    257:         * to expensive to let general algorithm figure out that
                    258:         * we are beyond the file.  Do it now.
                    259:         */
                    260:        if (uio->uio_offset >= ap->fsize)
                    261:                goto reterr;
                    262:
                    263:        /*
                    264:         * taken from ufs_read()
                    265:         */
                    266:        do {
                    267:                /*
                    268:                 * we are only supporting ADosFFS currently
1.27      mhitch    269:                 * (which have data blocks without headers)
1.1       chopps    270:                 */
1.27      mhitch    271:                size = amp->dbsize;
1.1       chopps    272:                lbn = uio->uio_offset / size;
                    273:                on = uio->uio_offset % size;
1.4       chopps    274:                n = min((u_int)(size - on), uio->uio_resid);
1.1       chopps    275:                diff = ap->fsize - uio->uio_offset;
                    276:                /*
                    277:                 * check for EOF
                    278:                 */
                    279:                if (diff <= 0)
                    280:                        return(0);
                    281:                if (diff < n)
                    282:                        n = diff;
                    283:                /*
                    284:                 * read ahead could possibly be worth something
                    285:                 * but not much as ados makes little attempt to
                    286:                 * make things contigous
                    287:                 */
1.27      mhitch    288:                error = bread(sp->a_vp, lbn * amp->secsperblk,
                    289:                              amp->bsize, NOCRED, &bp);
1.6       chopps    290:                sp->a_vp->v_lastr = lbn;
1.27      mhitch    291:
                    292:                if (!IS_FFS(amp)) {
                    293:                        if (bp->b_resid > 0)
                    294:                                error = EIO; /* OFS needs the complete block */
                    295:                        else if (adoswordn(bp, 0) != BPT_DATA) {
                    296: #ifdef DIAGNOSTIC
1.31    ! christos  297:                                kprintf("adosfs: bad primary type blk %ld\n",
        !           298:                                    bp->b_blkno / amp->secsperblk);
1.27      mhitch    299: #endif
                    300:                                error=EINVAL;
                    301:                        }
                    302:                        else if ( adoscksum(bp, ap->nwords)) {
                    303: #ifdef DIAGNOSTIC
1.31    ! christos  304:                                kprintf("adosfs: blk %ld failed cksum.\n",
        !           305:                                    bp->b_blkno / amp->secsperblk);
1.27      mhitch    306: #endif
                    307:                                error=EINVAL;
                    308:                        }
                    309:                }
                    310:
1.1       chopps    311:                if (error) {
                    312:                        brelse(bp);
                    313:                        goto reterr;
                    314:                }
                    315: #ifdef ADOSFS_DIAGNOSTIC
1.31    ! christos  316:                kprintf(" %d+%d-%d+%d", lbn, on, lbn, n);
1.1       chopps    317: #endif
1.27      mhitch    318:                n = min(n, (u_int)size - bp->b_resid);
                    319:                error = uiomove(bp->b_un.b_addr + on +
                    320:                                amp->bsize - amp->dbsize, (int)n, uio);
1.1       chopps    321:                brelse(bp);
                    322:        } while (error == 0 && uio->uio_resid > 0 && n != 0);
                    323: reterr:
                    324: #ifdef ADOSFS_DIAGNOSTIC
1.31    ! christos  325:        kprintf(" %d)", error);
1.1       chopps    326: #endif
                    327:        return(error);
                    328: }
                    329:
                    330: int
1.25      christos  331: adosfs_write(v)
                    332:        void *v;
                    333: {
                    334: #ifdef ADOSFS_DIAGNOSTIC
1.6       chopps    335:        struct vop_write_args /* {
                    336:                struct vnode *a_vp;
                    337:                struct uio *a_uio;
                    338:                int a_ioflag;
                    339:                struct ucred *a_cred;
1.25      christos  340:        } */ *sp = v;
1.6       chopps    341:        advopprint(sp);
1.31    ! christos  342:        kprintf(" EOPNOTSUPP)");
1.1       chopps    343: #endif
                    344:        return(EOPNOTSUPP);
                    345: }
                    346:
                    347: /*
                    348:  * Device ioctl operation.
                    349:  */
                    350: /* ARGSUSED */
                    351: int
1.25      christos  352: adosfs_ioctl(v)
                    353:        void *v;
                    354: {
                    355: #ifdef ADOSFS_DIAGNOSTIC
1.6       chopps    356:        struct vop_ioctl_args /* {
                    357:                struct vnode *a_vp;
1.14      cgd       358:                u_long a_command;
1.6       chopps    359:                caddr_t  a_data;
                    360:                int  a_fflag;
                    361:                struct ucred *a_cred;
                    362:                struct proc *a_p;
1.25      christos  363:        } */ *sp = v;
1.6       chopps    364:        advopprint(sp);
1.31    ! christos  365:        kprintf(" ENOTTY)");
1.1       chopps    366: #endif
                    367:        return(ENOTTY);
                    368: }
                    369:
                    370: /*
                    371:  * Just call the device strategy routine
                    372:  */
                    373: int
1.25      christos  374: adosfs_strategy(v)
                    375:        void *v;
                    376: {
1.6       chopps    377:        struct vop_strategy_args /* {
                    378:                struct buf *a_bp;
1.25      christos  379:        } */ *sp = v;
1.1       chopps    380:        struct buf *bp;
                    381:        struct anode *ap;
                    382:        struct vnode *vp;
                    383:        int error;
                    384:
                    385: #ifdef ADOSFS_DIAGNOSTIC
1.6       chopps    386:        advopprint(sp);
1.1       chopps    387: #endif
                    388:        error = 0;
1.6       chopps    389:        bp = sp->a_bp;
1.1       chopps    390:        if (bp->b_vp == NULL) {
                    391:                bp->b_flags |= B_ERROR;
                    392:                biodone(bp);
                    393:                error = EIO;
                    394:                goto reterr;
                    395:        }
                    396:        vp = bp->b_vp;
                    397:        ap = VTOA(vp);
1.6       chopps    398:        if (bp->b_blkno == bp->b_lblkno) {
1.25      christos  399:                error = VOP_BMAP(vp, bp->b_lblkno, NULL, &bp->b_blkno, NULL);
                    400:                if (error) {
1.1       chopps    401:                        bp->b_flags |= B_ERROR;
                    402:                        biodone(bp);
                    403:                        goto reterr;
                    404:                }
1.6       chopps    405:        }
                    406:        if ((long)bp->b_blkno == -1) {
                    407:                biodone(bp);
                    408:                error = 0;
                    409:                goto reterr;
                    410:        }
1.1       chopps    411:        vp = ap->amp->devvp;
                    412:        bp->b_dev = vp->v_rdev;
1.6       chopps    413:        VOCALL(vp->v_op, VOFFSET(vop_strategy), sp);
1.1       chopps    414: reterr:
                    415: #ifdef ADOSFS_DIAGNOSTIC
1.31    ! christos  416:        kprintf(" %d)", error);
1.1       chopps    417: #endif
                    418:        return(error);
                    419: }
                    420:
1.24      mycroft   421: int
1.25      christos  422: adosfs_link(v)
                    423:        void *v;
                    424: {
1.24      mycroft   425:        struct vop_link_args /* {
                    426:                struct vnode *a_dvp;
                    427:                struct vnode *a_vp;
                    428:                struct componentname *a_cnp;
1.25      christos  429:        } */ *ap = v;
1.24      mycroft   430:
                    431:        VOP_ABORTOP(ap->a_dvp, ap->a_cnp);
                    432:        vput(ap->a_dvp);
                    433:        return (EROFS);
                    434: }
                    435:
                    436: int
1.25      christos  437: adosfs_symlink(v)
                    438:        void *v;
                    439: {
1.24      mycroft   440:        struct vop_symlink_args /* {
                    441:                struct vnode *a_dvp;
                    442:                struct vnode **a_vpp;
                    443:                struct componentname *a_cnp;
                    444:                struct vattr *a_vap;
                    445:                char *a_target;
1.25      christos  446:        } */ *ap = v;
1.24      mycroft   447:
                    448:        VOP_ABORTOP(ap->a_dvp, ap->a_cnp);
                    449:        vput(ap->a_dvp);
                    450:        return (EROFS);
                    451: }
                    452:
1.1       chopps    453: /*
1.6       chopps    454:  * lock the anode
1.1       chopps    455:  */
                    456: int
1.25      christos  457: adosfs_lock(v)
                    458:        void *v;
                    459: {
1.6       chopps    460:        struct vop_lock_args /* {
                    461:                struct vnode *a_vp;
1.25      christos  462:        } */ *sp = v;
1.1       chopps    463:        struct vnode *vp;
1.6       chopps    464:        struct anode *ap;
                    465:
1.1       chopps    466: #ifdef ADOSFS_DIAGNOSTIC
1.6       chopps    467:        advopprint(sp);
1.1       chopps    468: #endif
1.6       chopps    469:        vp = sp->a_vp;
                    470: start:
                    471:        while (vp->v_flag & VXLOCK) {
                    472:                vp->v_flag |= VXWANT;
                    473:                tsleep(vp, PINOD, "adosfs_lock vp", 0);
                    474:        }
                    475:        if (vp->v_tag == VT_NON)
                    476:                return (ENOENT);
                    477:        ap = VTOA(vp);
                    478:        if (ap->flags & ALOCKED) {
                    479:                ap->flags |= AWANT;
                    480:                tsleep(ap, PINOD, "adosfs_lock ap", 0);
                    481:                goto start;
                    482:        }
                    483:        ap->flags |= ALOCKED;
1.1       chopps    484: #ifdef ADOSFS_DIAGNOSTIC
1.31    ! christos  485:        kprintf(" 0)");
1.1       chopps    486: #endif
                    487:        return(0);
                    488: }
                    489:
1.6       chopps    490: /*
                    491:  * unlock an anode
                    492:  */
1.1       chopps    493: int
1.25      christos  494: adosfs_unlock(v)
                    495:        void *v;
                    496: {
1.6       chopps    497:        struct vop_unlock_args /* {
                    498:                struct vnode *a_vp;
1.25      christos  499:        } */ *sp = v;
1.6       chopps    500:        struct anode *ap;
                    501:
1.1       chopps    502: #ifdef ADOSFS_DIAGNOSTIC
1.6       chopps    503:        advopprint(sp);
1.1       chopps    504: #endif
1.6       chopps    505:        ap = VTOA(sp->a_vp);
                    506:        ap->flags &= ~ALOCKED;
                    507:        if (ap->flags & AWANT) {
                    508:                ap->flags &= ~AWANT;
                    509:                wakeup(ap);
                    510:        }
1.1       chopps    511:
                    512: #ifdef ADOSFS_DIAGNOSTIC
1.31    ! christos  513:        kprintf(" 0)");
1.1       chopps    514: #endif
                    515:        return(0);
                    516: }
                    517:
                    518:
                    519: /*
                    520:  * Wait until the vnode has finished changing state.
                    521:  */
                    522: int
1.25      christos  523: adosfs_bmap(v)
                    524:        void *v;
                    525: {
1.6       chopps    526:        struct vop_bmap_args /* {
                    527:                struct vnode *a_vp;
                    528:                daddr_t  a_bn;
                    529:                struct vnode **a_vpp;
                    530:                daddr_t *a_bnp;
                    531:                int *a_runp;
1.25      christos  532:        } */ *sp = v;
1.1       chopps    533:        struct anode *ap;
                    534:        struct buf *flbp;
1.9       chopps    535:        long nb, flblk, flblkoff, fcnt;
1.6       chopps    536:        daddr_t *bnp;
                    537:        daddr_t bn;
1.1       chopps    538:        int error;
                    539:
                    540: #ifdef ADOSFS_DIAGNOSTIC
1.6       chopps    541:        advopprint(sp);
1.1       chopps    542: #endif
1.27      mhitch    543:        ap = VTOA(sp->a_vp);
                    544:        bn = sp->a_bn / ap->amp->secsperblk;
1.6       chopps    545:        bnp = sp->a_bnp;
1.1       chopps    546:        error = 0;
                    547:
1.6       chopps    548:        if (sp->a_vpp != NULL)
                    549:                *sp->a_vpp = ap->amp->devvp;
                    550:        if (bnp == NULL)
                    551:                goto reterr;
1.1       chopps    552:        if (bn < 0) {
                    553:                error = EFBIG;
                    554:                goto reterr;
                    555:        }
1.6       chopps    556:        if (sp->a_vp->v_type != VREG) {
1.1       chopps    557:                error = EINVAL;
                    558:                goto reterr;
                    559:        }
                    560:
                    561:        /*
                    562:         * walk the chain of file list blocks until we find
                    563:         * the one that will yield the block pointer we need.
                    564:         */
                    565:        if (ap->type == AFILE)
                    566:                nb = ap->block;                 /* pointer to ourself */
                    567:        else if (ap->type == ALFILE)
                    568:                nb = ap->linkto;                /* pointer to real file */
                    569:        else {
                    570:                error = EINVAL;
                    571:                goto reterr;
                    572:        }
                    573:
                    574:        flblk = bn / ANODENDATBLKENT(ap);
                    575:        flbp = NULL;
1.9       chopps    576:
                    577:        /*
                    578:         * check last indirect block cache
                    579:         */
1.18      chopps    580:        if (flblk < ap->lastlindblk)
1.9       chopps    581:                fcnt = 0;
                    582:        else {
                    583:                flblk -= ap->lastlindblk;
                    584:                fcnt = ap->lastlindblk;
                    585:                nb = ap->lastindblk;
                    586:        }
1.1       chopps    587:        while (flblk >= 0) {
                    588:                if (flbp)
                    589:                        brelse(flbp);
                    590:                if (nb == 0) {
                    591: #ifdef DIAGNOSTIC
1.31    ! christos  592:                        kprintf("adosfs: bad file list chain.\n");
1.1       chopps    593: #endif
                    594:                        error = EINVAL;
                    595:                        goto reterr;
                    596:                }
1.27      mhitch    597:                error = bread(ap->amp->devvp, nb * ap->amp->secsperblk,
                    598:                              ap->amp->bsize, NOCRED, &flbp);
1.25      christos  599:                if (error)
1.1       chopps    600:                        goto reterr;
                    601:                if (adoscksum(flbp, ap->nwords)) {
                    602: #ifdef DIAGNOSTIC
1.31    ! christos  603:                        kprintf("adosfs: blk %ld failed cksum.\n", nb);
1.1       chopps    604: #endif
                    605:                        brelse(flbp);
                    606:                        error = EINVAL;
                    607:                        goto reterr;
                    608:                }
1.9       chopps    609:                /*
                    610:                 * update last indirect block cache
                    611:                 */
                    612:                ap->lastlindblk = fcnt++;
                    613:                ap->lastindblk = nb;
                    614:
1.1       chopps    615:                nb = adoswordn(flbp, ap->nwords - 2);
                    616:                flblk--;
                    617:        }
                    618:        /*
                    619:         * calculate offset of block number in table.  The table starts
                    620:         * at nwords - 51 and goes to offset 6 or less if indicated by the
                    621:         * valid table entries stored at offset ADBI_NBLKTABENT.
                    622:         */
                    623:        flblkoff = bn % ANODENDATBLKENT(ap);
                    624:        if (flblkoff < adoswordn(flbp, 2 /* ADBI_NBLKTABENT */)) {
                    625:                flblkoff = (ap->nwords - 51) - flblkoff;
1.27      mhitch    626:                *bnp = adoswordn(flbp, flblkoff) * ap->amp->secsperblk;
1.1       chopps    627:        } else {
                    628: #ifdef DIAGNOSTIC
1.31    ! christos  629:                kprintf("flblk offset %ld too large in lblk %ld blk %d\n",
1.27      mhitch    630:                    flblkoff, bn / ap->amp->secsperblk , flbp->b_blkno);
1.1       chopps    631: #endif
                    632:                error = EINVAL;
                    633:        }
                    634:        brelse(flbp);
                    635: reterr:
                    636: #ifdef ADOSFS_DIAGNOSTIC
                    637:        if (error == 0 && bnp)
1.31    ! christos  638:                kprintf(" %d => %d", bn, *bnp);
        !           639:        kprintf(" %d)", error);
1.1       chopps    640: #endif
                    641:        return(error);
                    642: }
                    643:
                    644: /*
                    645:  * Print out the contents of a adosfs vnode.
                    646:  */
                    647: /* ARGSUSED */
                    648: int
1.25      christos  649: adosfs_print(v)
                    650:        void *v;
                    651: {
                    652: #if 0
1.6       chopps    653:        struct vop_print_args /* {
                    654:                struct vnode *a_vp;
1.25      christos  655:        } */ *sp = v;
                    656: #endif
1.1       chopps    657:        return(0);
                    658: }
                    659:
                    660: struct adirent {
                    661:        u_long  fileno;
                    662:        u_short reclen;
1.6       chopps    663:        char    type;
                    664:        char    namlen;
1.1       chopps    665:        char    name[32];       /* maxlen of 30 plus 2 NUL's */
                    666: };
                    667:
                    668: int
1.25      christos  669: adosfs_readdir(v)
                    670:        void *v;
                    671: {
1.6       chopps    672:        struct vop_readdir_args /* {
                    673:                struct vnode *a_vp;
                    674:                struct uio *a_uio;
                    675:                struct ucred *a_cred;
                    676:                int *a_eofflag;
                    677:                u_long *a_cookies;
                    678:                int a_ncookies;
1.25      christos  679:        } */ *sp = v;
1.1       chopps    680:        int error, useri, chainc, hashi, scanned, uavail;
                    681:        struct adirent ad, *adp;
                    682:        struct anode *pap, *ap;
1.20      mycroft   683:        struct adosfsmount *amp;
1.6       chopps    684:        struct vnode *vp;
                    685:        struct uio *uio;
1.25      christos  686:        u_long nextbn;
1.1       chopps    687:        off_t uoff;
                    688:
                    689: #ifdef ADOSFS_DIAGNOSTIC
1.6       chopps    690:        advopprint(sp);
1.1       chopps    691: #endif
1.6       chopps    692:        if (sp->a_vp->v_type != VDIR) {
1.1       chopps    693:                error = ENOTDIR;
                    694:                goto reterr;
                    695:        }
1.6       chopps    696:        uio = sp->a_uio;
1.1       chopps    697:        uoff = uio->uio_offset;
                    698:        if (uoff < 0) {
                    699:                error = EINVAL;
                    700:                goto reterr;
                    701:        }
                    702:
1.6       chopps    703:        pap = VTOA(sp->a_vp);
1.1       chopps    704:        amp = pap->amp;
                    705:        adp = &ad;
                    706:        error = nextbn = hashi = chainc = scanned = 0;
                    707:        uavail = uio->uio_resid / sizeof(ad);
                    708:        useri = uoff / sizeof(ad);
                    709:
1.2       chopps    710:        /*
                    711:         * if no slots available or offset requested is not on a slot boundry
                    712:         */
                    713:        if (uavail < 1 || uoff % sizeof(ad)) {
                    714:                error = EINVAL;
                    715:                goto reterr;
                    716:        }
                    717:
1.6       chopps    718:        while (uavail && (sp->a_cookies == NULL || sp->a_ncookies > 0)) {
1.1       chopps    719:                if (hashi == pap->ntabent) {
1.6       chopps    720:                        *sp->a_eofflag = 1;
1.1       chopps    721:                        break;
                    722:                }
                    723:                if (pap->tab[hashi] == 0) {
                    724:                        hashi++;
                    725:                        continue;
                    726:                }
1.2       chopps    727:                if (nextbn == 0)
1.1       chopps    728:                        nextbn = pap->tab[hashi];
                    729:
                    730:                /*
                    731:                 * first determine if we can skip this chain
                    732:                 */
                    733:                if (chainc == 0) {
                    734:                        int skip;
                    735:
                    736:                        skip = useri - scanned;
                    737:                        if (pap->tabi[hashi] > 0 && pap->tabi[hashi] <= skip) {
                    738:                                scanned += pap->tabi[hashi];
                    739:                                hashi++;
1.2       chopps    740:                                nextbn = 0;
1.1       chopps    741:                                continue;
                    742:                        }
                    743:                }
                    744:
                    745:                /*
                    746:                 * now [continue to] walk the chain
                    747:                 */
                    748:                ap = NULL;
                    749:                do {
1.25      christos  750:                        error = VFS_VGET(amp->mp, (ino_t)nextbn, &vp);
                    751:                        if (error)
1.1       chopps    752:                                goto reterr;
1.6       chopps    753:                        ap = VTOA(vp);
1.1       chopps    754:                        scanned++;
                    755:                        chainc++;
                    756:                        nextbn = ap->hashf;
                    757:
                    758:                        /*
                    759:                         * check for end of chain.
                    760:                         */
                    761:                        if (nextbn == 0) {
                    762:                                pap->tabi[hashi] = chainc;
                    763:                                hashi++;
1.2       chopps    764:                                chainc = 0;
1.1       chopps    765:                        } else if (pap->tabi[hashi] <= 0 &&
                    766:                            -chainc < pap->tabi[hashi])
                    767:                                pap->tabi[hashi] = -chainc;
                    768:
1.2       chopps    769:                        if (useri >= scanned) {
1.6       chopps    770:                                vput(vp);
1.1       chopps    771:                                ap = NULL;
                    772:                        }
                    773:                } while (ap == NULL && nextbn != 0);
                    774:
                    775:                /*
                    776:                 * we left the loop but without a result so do main over.
                    777:                 */
                    778:                if (ap == NULL)
                    779:                        continue;
                    780:                /*
                    781:                 * Fill in dirent record
                    782:                 */
                    783:                bzero(adp, sizeof(struct adirent));
                    784:                adp->fileno = ap->block;
1.6       chopps    785:                /*
                    786:                 * this deserves an function in kern/vfs_subr.c
                    787:                 */
                    788:                switch (ATOV(ap)->v_type) {
                    789:                case VREG:
                    790:                        adp->type = DT_REG;
                    791:                        break;
                    792:                case VDIR:
                    793:                        adp->type = DT_DIR;
                    794:                        break;
                    795:                case VLNK:
                    796:                        adp->type = DT_LNK;
                    797:                        break;
                    798:                default:
                    799:                        adp->type = DT_UNKNOWN;
                    800:                        break;
                    801:                }
1.1       chopps    802:                adp->reclen = sizeof(struct adirent);
                    803:                adp->namlen = strlen(ap->name);
                    804:                bcopy(ap->name, adp->name, adp->namlen);
1.6       chopps    805:                vput(vp);
1.1       chopps    806:
1.25      christos  807:                error = uiomove((caddr_t) adp, sizeof(struct adirent), uio);
1.1       chopps    808:                if (error)
                    809:                        break;
1.6       chopps    810:                if (sp->a_cookies) {
                    811:                        *sp->a_cookies++ = uoff;
                    812:                        sp->a_ncookies--;
1.1       chopps    813:                }
                    814:                uoff += sizeof(struct adirent);
                    815:                useri++;
                    816:                uavail--;
                    817:        }
1.2       chopps    818: #if doesnt_uiomove_handle_this
1.1       chopps    819:        uio->uio_offset = uoff;
1.2       chopps    820: #endif
1.1       chopps    821: reterr:
                    822: #ifdef ADOSFS_DIAGNOSTIC
1.31    ! christos  823:        kprintf(" %d)", error);
1.1       chopps    824: #endif
                    825:        return(error);
                    826: }
                    827:
                    828:
                    829: int
1.25      christos  830: adosfs_access(v)
                    831:        void *v;
                    832: {
1.6       chopps    833:        struct vop_access_args /* {
                    834:                struct vnode *a_vp;
                    835:                int  a_mode;
                    836:                struct ucred *a_cred;
                    837:                struct proc *a_p;
1.25      christos  838:        } */ *sp = v;
1.1       chopps    839:        struct anode *ap;
1.19      chopps    840:        int error;
1.1       chopps    841:
                    842: #ifdef ADOSFS_DIAGNOSTIC
1.6       chopps    843:        advopprint(sp);
1.1       chopps    844: #endif
                    845:
1.6       chopps    846:        ap = VTOA(sp->a_vp);
1.1       chopps    847: #ifdef DIAGNOSTIC
1.6       chopps    848:        if (!VOP_ISLOCKED(sp->a_vp)) {
                    849:                vprint("adosfs_access: not locked", sp->a_vp);
1.1       chopps    850:                panic("adosfs_access: not locked");
                    851:        }
                    852: #endif
                    853: #ifdef QUOTA
                    854: #endif
1.18      chopps    855:        error = vaccess(adunixprot(ap->adprot) & ap->amp->mask, ap->uid,
1.19      chopps    856:            ap->gid, sp->a_mode, sp->a_cred);
1.1       chopps    857: #ifdef ADOSFS_DIAGNOSTIC
1.31    ! christos  858:        kprintf(" %d)", error);
1.1       chopps    859: #endif
                    860:        return(error);
                    861: }
                    862:
                    863: /*ARGSUSED*/
                    864: int
1.25      christos  865: adosfs_readlink(v)
                    866:        void *v;
                    867: {
1.6       chopps    868:        struct vop_readlink_args /* {
                    869:                struct vnode *a_vp;
                    870:                struct uio *a_uio;
                    871:                struct ucred *a_cred;
1.25      christos  872:        } */ *sp = v;
1.6       chopps    873:        struct anode *ap;
                    874:        int error;
                    875:
1.1       chopps    876: #ifdef ADOSFS_DIAGNOSTIC
1.6       chopps    877:        advopprint(sp);
1.1       chopps    878: #endif
1.6       chopps    879:        error = 0;
                    880:        ap = VTOA(sp->a_vp);
                    881:        if (ap->type != ASLINK)
                    882:                error = EBADF;
                    883:        /*
                    884:         * XXX Should this be NULL terminated?
                    885:         */
                    886:        if (error == 0)
                    887:                error = uiomove(ap->slinkto, strlen(ap->slinkto)+1, sp->a_uio);
1.1       chopps    888: #ifdef ADOSFS_DIAGNOSTIC
1.31    ! christos  889:        kprintf(" %d)", error);
1.1       chopps    890: #endif
1.6       chopps    891:        return(error);
1.1       chopps    892: }
                    893:
                    894: /*ARGSUSED*/
                    895: int
1.25      christos  896: adosfs_inactive(v)
                    897:        void *v;
                    898: {
1.6       chopps    899:        struct vop_inactive_args /* {
                    900:                struct vnode *a_vp;
1.25      christos  901:        } */ *sp = v;
1.1       chopps    902: #ifdef ADOSFS_DIAGNOSTIC
1.6       chopps    903:        advopprint(sp);
1.1       chopps    904: #endif
1.6       chopps    905:        if (sp->a_vp->v_usecount == 0 /* && check for file gone? */)
                    906:                vgone(sp->a_vp);
1.1       chopps    907:
                    908: #ifdef ADOSFS_DIAGNOSTIC
1.31    ! christos  909:        kprintf(" 0)");
1.1       chopps    910: #endif
                    911:        return(0);
                    912: }
1.25      christos  913:
1.1       chopps    914: int
1.25      christos  915: adosfs_islocked(v)
                    916:        void *v;
                    917: {
1.6       chopps    918:        struct vop_islocked_args /* {
                    919:                struct vnode *a_vp;
1.25      christos  920:        } */ *sp = v;
1.6       chopps    921:        int locked;
1.1       chopps    922:
                    923: #ifdef ADOSFS_DIAGNOSTIC
1.6       chopps    924:        advopprint(sp);
1.1       chopps    925: #endif
                    926:
1.6       chopps    927:        locked = (VTOA(sp->a_vp)->flags & ALOCKED) == ALOCKED;
1.1       chopps    928:
                    929: #ifdef ADOSFS_DIAGNOSTIC
1.31    ! christos  930:        kprintf(" %d)", locked);
1.1       chopps    931: #endif
1.6       chopps    932:        return(locked);
1.1       chopps    933: }
                    934:
1.6       chopps    935: /*
                    936:  * the kernel wants its vnode back.
                    937:  * no lock needed we are being called from vclean()
                    938:  */
1.1       chopps    939: int
1.25      christos  940: adosfs_reclaim(v)
                    941:        void *v;
                    942: {
1.6       chopps    943:        struct vop_reclaim_args /* {
                    944:                struct vnode *a_vp;
1.25      christos  945:        } */ *sp = v;
1.1       chopps    946:        struct vnode *vp;
                    947:        struct anode *ap;
                    948:
                    949: #ifdef ADOSFS_DIAGNOSTIC
1.31    ! christos  950:        kprintf("(reclaim 0)");
1.1       chopps    951: #endif
1.6       chopps    952:        vp = sp->a_vp;
1.1       chopps    953:        ap = VTOA(vp);
1.6       chopps    954:        LIST_REMOVE(ap, link);
                    955:        cache_purge(vp);
                    956:        if (vp->v_type == VDIR && ap->tab)
                    957:                free(ap->tab, M_ANODE);
                    958:        else if (vp->v_type == VLNK && ap->slinkto)
                    959:                free(ap->slinkto, M_ANODE);
                    960:        free(ap, M_ANODE);
                    961:        vp->v_data = NULL;
                    962:        return(0);
1.1       chopps    963: }
                    964:
                    965:
1.6       chopps    966: /*
                    967:  * POSIX pathconf info, grabbed from kern/u fs, probably need to
                    968:  * investigate exactly what each return type means as they are probably
                    969:  * not valid currently
                    970:  */
1.25      christos  971: int
                    972: adosfs_pathconf(v)
                    973:        void *v;
                    974: {
1.6       chopps    975:        struct vop_pathconf_args /* {
                    976:                struct vnode *a_vp;
                    977:                int a_name;
1.12      cgd       978:                register_t *a_retval;
1.25      christos  979:        } */ *sp = v;
1.1       chopps    980:
1.6       chopps    981:        switch (sp->a_name) {
                    982:        case _PC_LINK_MAX:
                    983:                *sp->a_retval = LINK_MAX;
                    984:                return (0);
                    985:        case _PC_MAX_CANON:
                    986:                *sp->a_retval = MAX_CANON;
                    987:                return (0);
                    988:        case _PC_MAX_INPUT:
                    989:                *sp->a_retval = MAX_INPUT;
                    990:                return (0);
                    991:        case _PC_PIPE_BUF:
                    992:                *sp->a_retval = PIPE_BUF;
                    993:                return (0);
                    994:        case _PC_CHOWN_RESTRICTED:
                    995:                *sp->a_retval = 1;
                    996:                return (0);
                    997:        case _PC_VDISABLE:
                    998:                *sp->a_retval = _POSIX_VDISABLE;
                    999:                return (0);
                   1000:        default:
                   1001:                return (EINVAL);
                   1002:        }
                   1003:        /* NOTREACHED */
1.1       chopps   1004: }

CVSweb <webmaster@jp.NetBSD.org>