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

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

CVSweb <webmaster@jp.NetBSD.org>