Annotation of researchv10no/sys/fs/fs.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * traditional disk filesystem
        !             3:  */
        !             4: #include "sys/param.h"
        !             5: #include "sys/systm.h"
        !             6: #include "sys/ino.h"
        !             7: #include "sys/buf.h"
        !             8: #include "sys/filsys.h"
        !             9: #include "sys/mount.h"
        !            10: #include "sys/dir.h"
        !            11: #include "sys/user.h"
        !            12: #include "sys/inode.h"
        !            13: #include "sys/file.h"
        !            14: #include "sys/conf.h"
        !            15: #include "sys/vlimit.h"
        !            16: #include "sys/stat.h"
        !            17: #include "sys/filio.h"
        !            18: #include "sys/cmap.h"
        !            19: #include "sys/stream.h"
        !            20: 
        !            21: int fsput(), fsupdat(), fsread(), fswrite(), fstrunc(), fsstat();
        !            22: int fsnami(), fsmount(), fsioctl(), fsdirread();
        !            23: struct inode *fsopen();
        !            24: struct fstypsw fsfs =
        !            25: fsinit(fsput, fsupdat, fsread, fswrite, fstrunc, fsstat,
        !            26:        fsnami, fsmount, fsioctl, fsopen, fsdirread);
        !            27: 
        !            28: extern struct mount fsmtab[];
        !            29: extern int fscnt;
        !            30: 
        !            31: /*
        !            32:  * silly mount/unmount routine for fs type 0
        !            33:  */
        !            34: 
        !            35: fsmount(sip, ip, flag, mnt, fstyp)
        !            36: register struct inode *ip, *sip;
        !            37: int flag, mnt, fstyp;
        !            38: {
        !            39: 
        !            40:        if (!suser())
        !            41:                return;
        !            42:        if (mnt)
        !            43:                fson(sip, ip, flag, fstyp);
        !            44:        else
        !            45:                fsoff(ip, fstyp);
        !            46: }
        !            47: 
        !            48: /*
        !            49:  * mount a type 0 filesystem (sip on ip)
        !            50:  * maintain the mount table for vm code's sake
        !            51:  *
        !            52:  * magic to help booting:
        !            53:  * if rootdir == NULL, we are being called from iinit, so
        !            54:  *     - allow s_valid == 0 on bitmapped filesystems so root may be mounted
        !            55:  *     - call clkinit to set the clock from the super-block time
        !            56:  */
        !            57: 
        !            58: fson(sip, ip, ronly, fstyp)
        !            59: register struct inode *ip, *sip;
        !            60: int ronly, fstyp;
        !            61: {
        !            62:        dev_t dev;
        !            63:        register struct mount *mp;
        !            64:        struct mount *emp;
        !            65:        struct inode *rip;
        !            66:        register struct filsys *fp;
        !            67:        struct buf *bp;
        !            68:        struct inode pi;        /* primer */
        !            69: 
        !            70:        if ((sip->i_mode&IFMT) != IFBLK) {
        !            71:                u.u_error = EINVAL;
        !            72:                return;
        !            73:        }
        !            74:        if (ip->i_fstyp == fstyp && ip->i_dev == sip->i_un.i_rdev) {
        !            75:                u.u_error = EBUSY;
        !            76:                return;
        !            77:        }
        !            78:        emp = NULL;
        !            79:        for (mp = &fsmtab[fscnt-1]; mp >= fsmtab; mp--) {
        !            80:                if (mp->m_dev == NULL)
        !            81:                        emp = mp;
        !            82:                else if (mp->m_dev == sip)
        !            83:                        goto hopeless;
        !            84:        }
        !            85:        if (emp == NULL)
        !            86:                goto hopeless;
        !            87:        emp->m_dev = sip;
        !            88:        dev = (dev_t)sip->i_un.i_rdev;
        !            89:        bp = bread(dev, SUPERB);
        !            90:        if(u.u_error) {
        !            91:                emp->m_dev = NULL;
        !            92:                brelse(bp);
        !            93:                return;
        !            94:        }
        !            95:        bp->b_flags |= B_LOCKED;
        !            96:        brelse(bp);
        !            97:        fp = bp->b_un.b_filsys;
        !            98:        fp->s_ilock = 0;
        !            99:        fp->s_flock = 0;
        !           100:        fp->s_ronly = ronly & 1;
        !           101:        fp->s_nbehind = 0;
        !           102:        fp->s_lasti = 1;
        !           103:        if(fp->s_cylsize == 0)
        !           104:                fp->s_cylsize = 40;     /* transition hack */
        !           105:        if(fp->s_aspace == 0)
        !           106:                fp->s_aspace = 4;       /* likewise */
        !           107:        if(BITFS(dev) && !fp->s_valid && !fp->s_ronly && rootdir != NULL)
        !           108:                goto failed;                    /* NOT IMPLEMENTED */
        !           109:        if(BITFS(dev) && fp->U.N.S_flag) {
        !           110:                if(fsbiton(dev, fp))
        !           111:                        goto failed;
        !           112:        /* hack until pjw fixes chuck */
        !           113:        } else if (BITFS(dev) && fp->s_isize + BITMAP*BITCELL < fp->s_fsize)
        !           114:                if(fsbiton(dev, fp))
        !           115:                        goto failed;
        !           116:        pi.i_dev = dev;
        !           117:        pi.i_fstyp = fstyp;
        !           118:        pi.i_un.i_bufp = bp;
        !           119:        if ((rip = iget(&pi, dev, ROOTINO)) == NULL)
        !           120:                goto failed;
        !           121:        if (rip->i_count == 1 && fsiread(&pi, rip) < 0)
        !           122:                goto failed;
        !           123:        if (rip->i_count != 1) {        /* already mounted */
        !           124:                iput(rip);
        !           125:                goto failed;
        !           126:        }
        !           127:        emp->m_mroot = rip;
        !           128:        ip->i_mroot = rip;
        !           129:        rip->i_mpoint = ip;
        !           130:        ip->i_count++;
        !           131:        sip->i_count++;
        !           132:        prele(rip);
        !           133:        if (rootdir == NULL)
        !           134:                clkinit(fp->s_time);
        !           135:        return;
        !           136: failed:
        !           137:        bp->b_flags &= ~B_LOCKED;
        !           138:        emp->m_dev = NULL;
        !           139: hopeless:
        !           140:        if (u.u_error == 0)
        !           141:                u.u_error = EBUSY;
        !           142: }
        !           143: 
        !           144: fsoff(mip, fstyp)
        !           145: register struct inode *mip;
        !           146: {
        !           147:        dev_t dev;
        !           148:        register struct mount *mp;
        !           149:        register struct inode *rip;
        !           150:        struct buf *bp;
        !           151:        struct filsys *fp;
        !           152: 
        !           153:        rip = mip->i_mroot;
        !           154:        for (mp = &fsmtab[fscnt-1]; mp >= fsmtab; mp--)
        !           155:                if (mp->m_mroot == rip)
        !           156:                        break;
        !           157:        if (mp < fsmtab)
        !           158:                panic("umount mp");
        !           159:        plock(rip);
        !           160:        xumount(rip);
        !           161:        update();       /* silly */
        !           162:        if (rip->i_count > 1 || ifsbusy(rip)) {
        !           163:                u.u_error = EBUSY;
        !           164:                prele(rip);
        !           165:                return;
        !           166:        }
        !           167:        plock(mip);
        !           168:        mip->i_mroot = NULL;
        !           169:        iput(mip);
        !           170:        dev = rip->i_dev;
        !           171:        if ((bp = getblk(dev, SUPERB)) != rip->i_un.i_bufp)
        !           172:                panic("umount");
        !           173:        iput(rip);
        !           174:        bp->b_flags &= ~(B_LOCKED|B_ASYNC);     /* ~async needed? */
        !           175:        if (bp->b_un.b_filsys->s_ronly)
        !           176:                brelse(bp);
        !           177:        else {
        !           178:                if (BITFS(dev)) {
        !           179:                        fp = bp->b_un.b_filsys;
        !           180:                        fp->s_valid = 1;
        !           181:                        if(fp->U.N.S_flag)
        !           182:                                fsbitoff(dev, fp, 1);
        !           183:                }
        !           184:                bwrite(bp);
        !           185:        }
        !           186:        mpurge(mp - fsmtab);
        !           187:        idec(mp->m_dev);
        !           188:        mp->m_dev = NULL;
        !           189: }
        !           190: 
        !           191: fsbiton(dev, fp)
        !           192: dev_t dev;
        !           193: register struct filsys *fp;
        !           194: {
        !           195:        register int i, nf;
        !           196:        register struct buf **bpp;
        !           197:        register struct buf *bp;
        !           198: 
        !           199:        /* two chuck should do */
        !           200:        fp->U.N.S_flag = 1;     /* bit map not in superblock */
        !           201:        nf = fp->U.N.S_bsize = BSIZE(dev) * NBBY;
        !           202:        if (fp->s_ronly)
        !           203:                return (0);
        !           204:        nf = (fp->s_fsize + nf - 1) / nf;
        !           205:        bpp = fp->U.N.S_blk;
        !           206:        for(i = 0; i < nf; i++)
        !           207:                bpp[i] = 0;
        !           208:        for(i = 0; i < nf; i++) {
        !           209:                bp = bread(dev, fp->s_fsize-nf+i);
        !           210:                if(u.u_error) {
        !           211:                        brelse(bp);
        !           212:                        goto failed;
        !           213:                }
        !           214:                bp->b_flags |= B_LOCKED;
        !           215:                brelse(bp);
        !           216:                bpp[i] = bp;
        !           217:        }
        !           218:        return(0);
        !           219: failed:
        !           220:        fsbitoff(dev, fp, 0);
        !           221:        return(1);
        !           222: }
        !           223: 
        !           224: fsbitoff(dev, fp, wrtflg)
        !           225: dev_t dev;
        !           226: struct filsys *fp;
        !           227: {
        !           228:        register struct buf **bpp;
        !           229:        register struct buf *bp;
        !           230:        register int i, nf;
        !           231: 
        !           232:        if (fp->s_ronly)
        !           233:                return;
        !           234:        nf = fp->U.N.S_bsize;
        !           235:        nf = (fp->s_fsize + nf-1)/nf;
        !           236:        bpp = fp->U.N.S_blk;
        !           237:        for(i = 0; i < nf; i++)
        !           238:                if(bpp[i]) {
        !           239:                        if ((bp = getblk(dev, fp->s_fsize - nf + i)) != bpp[i])
        !           240:                                panic("fsbitoff");
        !           241:                        bp->b_flags &= ~B_LOCKED;
        !           242:                        if(wrtflg)
        !           243:                                bwrite(bp);
        !           244:                        bpp[i] = 0;     /* safety first */
        !           245:                }
        !           246: }
        !           247: 
        !           248: /*
        !           249:  * fill in inode ip from the disk copy
        !           250:  * in filesystem fip
        !           251:  * ip is an inode fresh from iget
        !           252:  */
        !           253: fsiread(fip, ip)
        !           254: register struct inode *fip, *ip;
        !           255: {
        !           256:        register struct buf *bp;
        !           257:        daddr_t bno;
        !           258: 
        !           259:        if (ip->i_number <= 0) {
        !           260:                u.u_error = EINVAL;
        !           261:                iput(ip);
        !           262:                return (-1);
        !           263:        }
        !           264:        bno = itod(fip->i_dev, (ino_t)ip->i_number);
        !           265:        if (bno >= getfs(fip)->s_isize) {
        !           266:                u.u_error = EINVAL;
        !           267:                iput(ip);
        !           268:                return (-1);
        !           269:        }
        !           270:        bp = bread(fip->i_dev, bno);
        !           271:        if((bp->b_flags&B_ERROR) != 0) {
        !           272:                brelse(bp);
        !           273:                iput(ip);
        !           274:                return(-1);
        !           275:        }
        !           276:        iexpand(ip, bp->b_un.b_dino+itoo(fip->i_dev, (ino_t)ip->i_number));
        !           277:        brelse(bp);
        !           278:        ip->i_un.i_bufp = fip->i_un.i_bufp;
        !           279:        ip->i_un.i_lastr = 0;
        !           280:        return (0);
        !           281: }
        !           282: 
        !           283: iexpand(ip, dp)
        !           284: register struct inode *ip;
        !           285: register struct dinode *dp;
        !           286: {
        !           287:        register char *p1, *p2;
        !           288:        register int i;
        !           289: 
        !           290:        ip->i_mode = dp->di_mode;
        !           291:        ip->i_nlink = dp->di_nlink;
        !           292:        ip->i_uid = dp->di_uid;
        !           293:        ip->i_gid = dp->di_gid;
        !           294:        ip->i_size = dp->di_size;
        !           295:        p1 = (char *)ip->i_un.i_addr;
        !           296:        p2 = (char *)dp->di_addr;
        !           297:        for(i=0; i<NADDR; i++) {
        !           298:                *p1++ = *p2++;
        !           299:                *p1++ = *p2++;
        !           300:                *p1++ = *p2++;
        !           301:                *p1++ = 0;
        !           302:        }
        !           303: }
        !           304: 
        !           305: fsput(ip)
        !           306: struct inode *ip;
        !           307: {
        !           308:        if (ip->i_nlink == 0) {
        !           309:                fstrunc(ip);
        !           310:                ifree(ip);
        !           311:                ip->i_mode = 0;
        !           312:                ip->i_flag |= IUPD|ICHG;
        !           313:        }
        !           314:        if ((ip->i_flag&(IUPD|IACC|ICHG)) != 0)
        !           315:                fsiupdat(ip, &time, &time, 0);
        !           316: }
        !           317: 
        !           318: fsupdat(ip, ta, tm, waitfor)
        !           319: register struct inode *ip;
        !           320: time_t *ta, *tm;
        !           321: {
        !           322:        fsiupdat(ip, ta, tm, waitfor);
        !           323:        if (ip->i_un.i_bufp->b_un.b_filsys->s_fmod)
        !           324:                fsfupdat(ip);
        !           325: }
        !           326: 
        !           327: /*
        !           328:  * update the inode on disk
        !           329:  * if the super-block is dirty, write it too
        !           330:  */
        !           331: 
        !           332: fsiupdat(ip, ta, tm, waitfor)
        !           333: register struct inode *ip;
        !           334: time_t *ta, *tm;
        !           335: {
        !           336:        register struct buf *bp;
        !           337:        struct dinode *dp;
        !           338:        register char *p1, *p2;
        !           339:        register int i;
        !           340: 
        !           341:        if (ip->i_un.i_bufp->b_un.b_filsys->s_ronly)
        !           342:                return;
        !           343:        bp = bread(ip->i_dev, itod(ip->i_dev, ip->i_number));
        !           344:        if (bp->b_flags & B_ERROR) {
        !           345:                brelse(bp);
        !           346:                return;
        !           347:        }
        !           348:        dp = bp->b_un.b_dino;
        !           349:        dp += itoo(ip->i_dev, ip->i_number);
        !           350:        dp->di_mode = ip->i_mode;
        !           351:        dp->di_nlink = ip->i_nlink;
        !           352:        dp->di_uid = ip->i_uid;
        !           353:        dp->di_gid = ip->i_gid;
        !           354:        dp->di_size = ip->i_size;
        !           355:        p1 = (char *)dp->di_addr;
        !           356:        p2 = (char *)ip->i_un.i_addr;
        !           357:        for(i=0; i<NADDR; i++) {
        !           358:                *p1++ = *p2++;
        !           359:                *p1++ = *p2++;
        !           360:                *p1++ = *p2++;
        !           361:                if(*p2++)
        !           362:                        printf("ino %d dev #%x addr #%x\n", ip->i_number, ip->i_dev, ip->i_un.i_addr[i]);
        !           363:        }
        !           364:        if(ip->i_flag&IACC)
        !           365:                dp->di_atime = *ta;
        !           366:        if(ip->i_flag&IUPD)
        !           367:                dp->di_mtime = *tm;
        !           368:        if(ip->i_flag&ICHG)
        !           369:                dp->di_ctime = time;
        !           370:        ip->i_flag &= ~(IUPD|IACC|ICHG);
        !           371:        if (waitfor)
        !           372:                bwrite(bp);
        !           373:        else
        !           374:                bdwrite(bp);
        !           375: }
        !           376: 
        !           377: /*
        !           378:  * write the super-block
        !           379:  */
        !           380: 
        !           381: fsfupdat(ip)
        !           382: struct inode *ip;
        !           383: {
        !           384:        register struct filsys *fp;
        !           385:        struct buf *bp;
        !           386: 
        !           387:        fp = ip->i_un.i_bufp->b_un.b_filsys;
        !           388:        if (fp->s_fmod == 0 || fp->s_ilock || fp->s_flock || fp->s_ronly)
        !           389:                return;
        !           390:        bp = getblk(ip->i_dev, SUPERB);
        !           391:        if (bp->b_un.b_filsys != fp)
        !           392:                panic("fsfupdat");
        !           393:        fp->s_fmod = 0;
        !           394:        fp->s_time = time;
        !           395:        bwrite(bp);
        !           396: }
        !           397: 
        !           398: fsstat(ip, ub)
        !           399: register struct inode *ip;
        !           400: struct stat *ub;
        !           401: {
        !           402:        register struct dinode *dp;
        !           403:        register struct buf *bp;
        !           404:        struct stat ds;
        !           405: 
        !           406:        /*
        !           407:         * first copy from inode table
        !           408:         */
        !           409:        ds.st_dev = ip->i_dev;
        !           410:        ds.st_ino = ip->i_number;
        !           411:        ds.st_mode = ip->i_mode;
        !           412:        ds.st_nlink = ip->i_nlink;
        !           413:        ds.st_uid = ip->i_uid;
        !           414:        ds.st_gid = ip->i_gid;
        !           415:        ds.st_rdev = (dev_t)ip->i_un.i_rdev;
        !           416:        ds.st_size = ip->i_size;
        !           417:        /*
        !           418:         * next the dates in the disk
        !           419:         */
        !           420:        bp = bread(ip->i_dev, itod(ip->i_dev, ip->i_number));
        !           421:        dp = bp->b_un.b_dino;
        !           422:        dp += itoo(ip->i_dev, ip->i_number);
        !           423:        ds.st_atime = dp->di_atime;
        !           424:        ds.st_mtime = dp->di_mtime;
        !           425:        ds.st_ctime = dp->di_ctime;
        !           426:        brelse(bp);
        !           427:        if (copyout((caddr_t)&ds, (caddr_t)ub, sizeof(ds)) < 0)
        !           428:                u.u_error = EFAULT;
        !           429: }
        !           430: 
        !           431: fstrunc(ip)
        !           432: register struct inode *ip;
        !           433: {
        !           434:        register i;
        !           435:        daddr_t bn;
        !           436:        struct inode itmp;
        !           437: 
        !           438:        i = ip->i_mode & IFMT;
        !           439:        if (i!=IFREG && i!=IFDIR && i!=IFLNK)
        !           440:                return;
        !           441:        /*
        !           442:         * Clean inode on disk before freeing blocks
        !           443:         * to insure no duplicates if system crashes.
        !           444:         */
        !           445:        itmp = *ip;
        !           446:        itmp.i_size = 0;
        !           447:        for (i = 0; i < NADDR; i++)
        !           448:                itmp.i_un.i_addr[i] = 0;
        !           449:        itmp.i_flag |= ICHG|IUPD;
        !           450:        fsiupdat(&itmp, &time, &time, 1);
        !           451:        ip->i_flag &= ~(IUPD|IACC|ICHG);
        !           452: 
        !           453:        /*
        !           454:         * Now return blocks to free list... if machine
        !           455:         * crashes, they will be harmless MISSING blocks.
        !           456:         */
        !           457:        for(i=NADDR-1; i>=0; i--) {
        !           458:                bn = ip->i_un.i_addr[i];
        !           459:                if(bn == (daddr_t)0)
        !           460:                        continue;
        !           461:                ip->i_un.i_addr[i] = (daddr_t)0;
        !           462:                switch(i) {
        !           463: 
        !           464:                default:
        !           465:                        free(ip, bn);
        !           466:                        break;
        !           467: 
        !           468:                case NADDR-3:
        !           469:                        tloop(ip, bn, 0, 0);
        !           470:                        break;
        !           471: 
        !           472:                case NADDR-2:
        !           473:                        tloop(ip, bn, 1, 0);
        !           474:                        break;
        !           475: 
        !           476:                case NADDR-1:
        !           477:                        tloop(ip, bn, 1, 1);
        !           478:                }
        !           479:        }
        !           480:        ip->i_size = 0;
        !           481:        /*
        !           482:         * Inode was written and flags updated above.
        !           483:         * No need to modify flags here.
        !           484:         */
        !           485: }
        !           486: 
        !           487: tloop(fip, bn, f1, f2)
        !           488: register struct inode *fip;
        !           489: daddr_t bn;
        !           490: {
        !           491:        register i;
        !           492:        register struct buf *bp;
        !           493:        register daddr_t *bap;
        !           494:        daddr_t nb;
        !           495: 
        !           496:        bp = NULL;
        !           497:        for(i=NINDIR(fip->i_dev)-1; i>=0; i--) {
        !           498:                if(bp == NULL) {
        !           499:                        bp = bread(fip->i_dev, bn);
        !           500:                        if (bp->b_flags & B_ERROR) {
        !           501:                                brelse(bp);
        !           502:                                return;
        !           503:                        }
        !           504:                        bap = bp->b_un.b_daddr;
        !           505:                }
        !           506:                nb = bap[i];
        !           507:                if(nb == (daddr_t)0)
        !           508:                        continue;
        !           509:                if(f1) {
        !           510:                        brelse(bp);
        !           511:                        bp = NULL;
        !           512:                        tloop(fip, nb, f2, 0);
        !           513:                } else
        !           514:                        free(fip, nb);
        !           515:        }
        !           516:        if(bp != NULL)
        !           517:                brelse(bp);
        !           518:        free(fip, bn);
        !           519: }
        !           520: 
        !           521: fsioctl(ip, cmd, cmarg, flag)
        !           522: register struct inode *ip;
        !           523: caddr_t cmarg;
        !           524: {
        !           525:        int fmt;
        !           526:        register dev_t dev;
        !           527: 
        !           528:        fmt = ip->i_mode & IFMT;
        !           529:        if (fmt != IFCHR) {
        !           530:                if (cmd==FIONREAD && (fmt == IFREG || fmt == IFDIR)) {
        !           531:                        off_t nread = ip->i_size; /* - fp->f_offset */
        !           532:                        if (copyout((caddr_t)&nread, cmarg, sizeof(off_t)))
        !           533:                                u.u_error = EFAULT;
        !           534:                } else
        !           535:                        u.u_error = ENOTTY;
        !           536:                return;
        !           537:        }
        !           538:        dev = ip->i_un.i_rdev;
        !           539:        u.u_r.r_val1 = 0;
        !           540:        (*cdevsw[major(dev)]->d_ioctl)(dev, cmd, cmarg, flag);
        !           541: }
        !           542: 
        !           543: struct inode *
        !           544: fsopen(ip, rw)
        !           545: register struct inode *ip;
        !           546: {
        !           547:        dev_t dev;
        !           548:        register unsigned int maj;
        !           549: 
        !           550:        dev = (dev_t)ip->i_un.i_rdev;
        !           551:        maj = major(dev);
        !           552: 
        !           553:        switch(ip->i_mode&IFMT) {
        !           554:        case IFCHR:
        !           555:                if(maj >= nchrdev || cdevsw[maj] == NULL)
        !           556:                        goto bad;
        !           557:                if (cdevsw[maj]->qinfo)         /* stream device */
        !           558:                        return(stopen(cdevsw[major(dev)]->qinfo, dev, rw, ip));
        !           559:                (*cdevsw[maj]->d_open)(dev, rw);
        !           560:                break;
        !           561: 
        !           562:        case IFBLK:
        !           563:                if(maj >= nblkdev || bdevsw[maj] == NULL)
        !           564:                        goto bad;
        !           565:                (*bdevsw[maj]->d_open)(dev, rw);
        !           566:        }
        !           567:        if (u.u_error) {
        !           568:                iput(ip);
        !           569:                return (NULL);
        !           570:        }
        !           571:        return (ip);
        !           572: 
        !           573: bad:
        !           574:        u.u_error = ENXIO;
        !           575:        iput(ip);
        !           576:        return(NULL);
        !           577: }
        !           578: 
        !           579: fsread(ip)
        !           580: register struct inode *ip;
        !           581: {
        !           582:        struct buf *bp;
        !           583:        dev_t dev;
        !           584:        daddr_t lbn, bn;
        !           585:        off_t diff;
        !           586:        register int on, type;
        !           587:        register unsigned n;
        !           588: 
        !           589:        dev = (dev_t)ip->i_un.i_rdev;
        !           590:        type = ip->i_mode&IFMT;
        !           591:        if (type==IFCHR) {
        !           592:                (*cdevsw[major(dev)]->d_read)(dev);
        !           593:                return;
        !           594:        }
        !           595:        if (Lsign(u.u_offset) < 0) {            /* and not IFCHR */
        !           596:                u.u_error = EINVAL;
        !           597:                return;
        !           598:        }
        !           599:        if (type != IFBLK) {    /* if offset >= size, avoid overflow */
        !           600:                if (Lsign(Lladd(u.u_offset, -ip->i_size))>=0)
        !           601:                        return;
        !           602:                dev = ip->i_dev;
        !           603:        }
        !           604:        do {
        !           605:                lbn = bn = Lshift(u.u_offset, BSHIFT(dev));
        !           606:                on = Ltol(u.u_offset) & BMASK(dev);
        !           607:                n = MIN((unsigned)(BSIZE(dev)-on), u.u_count);
        !           608:                if (type!=IFBLK) {
        !           609:                        diff = ip->i_size - Ltol(u.u_offset);
        !           610:                        if (diff <= 0)
        !           611:                                return;
        !           612:                        if (diff < n)
        !           613:                                n = diff;
        !           614:                        bn = bmap(ip, bn, B_READ);
        !           615:                        if (u.u_error)
        !           616:                                return;
        !           617:                } else
        !           618:                        rablock = bn+1;
        !           619:                if ((long)bn<0) {
        !           620:                        bp = geteblk();
        !           621:                        clrbuf(bp);
        !           622:                } else if (ip->i_un.i_lastr+1==lbn)
        !           623:                        bp = breada(dev, bn, rablock);
        !           624:                else
        !           625:                        bp = bread(dev, bn);
        !           626:                ip->i_un.i_lastr = lbn;
        !           627:                n = MIN(n, BSIZE(dev)-bp->b_resid);
        !           628:                if (n!=0)
        !           629:                        iomove(bp->b_un.b_addr+on, n, B_READ);
        !           630:                brelse(bp);
        !           631:        } while(u.u_error==0 && u.u_count!=0 && n!=0);
        !           632: }
        !           633: 
        !           634: fsdirread(ip, len)
        !           635: struct inode *ip;
        !           636: {      struct buf *bp = 0, *outb;
        !           637:        dev_t dev;
        !           638:        daddr_t bn, lbn;
        !           639:        int on, type, j, m, new = 0;
        !           640:        char *p, *lp, *lastp;
        !           641:        struct direct *dp;
        !           642:        char ncvt[24];
        !           643: 
        !           644:        if(Lsign(u.u_offset) < 0) {
        !           645:                u.u_error = EINVAL;
        !           646:                return;
        !           647:        }
        !           648:        type = ip->i_mode & IFMT;
        !           649:        if(type != IFDIR) {
        !           650:                u.u_error = ENOTDIR;
        !           651:                return;
        !           652:        }
        !           653:        dev = ip->i_dev;
        !           654:        outb = geteblk();       /* to hold the stuff for the user */
        !           655:        if(len > BSIZE(dev))
        !           656:                len = BSIZE(dev);
        !           657:        p = lp = outb->b_un.b_addr;
        !           658:        lastp = p + len;
        !           659: loop:
        !           660:        if(new <= 0) {  /* get some goo */
        !           661:                lbn = bn = Lshift(u.u_offset, BSHIFT(dev));
        !           662:                on = Ltol(u.u_offset) & BMASK(dev);
        !           663:                if(ip->i_size <= Ltol(u.u_offset))
        !           664:                        goto done;
        !           665:                bn = bmap(ip, bn, B_READ);
        !           666:                if(u.u_error)
        !           667:                        return;
        !           668:                if((long)bn < 0) {      /* holes in dirs? */
        !           669:                        u.u_offset = Lladd(u.u_offset, BSIZE(dev)-on);
        !           670:                        goto loop;      /* try the next block */
        !           671:                }
        !           672:                if(bp)
        !           673:                        brelse(bp);
        !           674:                if(ip->i_un.i_lastr + 1 == lbn)
        !           675:                        bp = breada(dev, bn, rablock);
        !           676:                else
        !           677:                        bp = bread(dev, bn);
        !           678:                ip->i_un.i_lastr = lbn;
        !           679:                new = BSIZE(dev) - on;
        !           680:                if(new > BSIZE(dev) - bp->b_resid)      /* io error? */
        !           681:                        new = BSIZE(dev) - bp->b_resid; /* or paranoia */
        !           682:                if(new > ip->i_size - Ltol(u.u_offset))
        !           683:                        new = ip->i_size - Ltol(u.u_offset);
        !           684:                dp = (struct direct *) (bp->b_un.b_addr + on);
        !           685:        }
        !           686:        if(dp->d_ino == 0)
        !           687:                goto incr;
        !           688:        for(m = dp->d_ino, j = sizeof(ncvt)-1; m; j--) {
        !           689:                ncvt[j] = m%10 + '0';
        !           690:                m /= 10;
        !           691:        }
        !           692:        for(++j; j < sizeof(ncvt) && p < lastp; )
        !           693:                *p++ = ncvt[j++];
        !           694:        if(j != sizeof(ncvt) || p >= lastp)
        !           695:                goto early;
        !           696:        *p++ = '\t';
        !           697:        for(j = 0; j < DIRSIZ && dp->d_name[j] && p < lastp; j++)
        !           698:                *p++ = dp->d_name[j];
        !           699:        if(p >= lastp)
        !           700:                goto early;
        !           701:        *p++ = 0;
        !           702: incr:
        !           703:        lp = p;
        !           704:        new -= sizeof(*dp);
        !           705:        u.u_offset = Lladd(u.u_offset, sizeof(*dp));
        !           706:        dp++;
        !           707:        if(p < lastp)
        !           708:                goto loop;
        !           709: done:
        !           710:        j = lp - outb->b_un.b_addr;
        !           711:        if(j > 0)
        !           712:                if(copyout((caddr_t)outb->b_un.b_addr, u.u_base, j))
        !           713:                        u.u_error = EFAULT;
        !           714:        if(bp)
        !           715:                brelse(bp);
        !           716:        brelse(outb);
        !           717:        u.u_r.r_val1 = j;
        !           718:        return;
        !           719: early:
        !           720:        *lp = 0;
        !           721:        if(lp > outb->b_un.b_addr)
        !           722:                goto done;
        !           723:        u.u_error = ENOSPC;
        !           724:        if(bp)
        !           725:                brelse(bp);
        !           726:        brelse(outb);
        !           727: }
        !           728: 
        !           729: fswrite(ip)
        !           730: register struct inode *ip;
        !           731: {
        !           732:        struct buf *bp;
        !           733:        dev_t dev;
        !           734:        daddr_t bn;
        !           735:        register int on, type;
        !           736:        register unsigned n;
        !           737:        register int i;
        !           738: 
        !           739:        dev = (dev_t)ip->i_un.i_rdev;
        !           740:        type = ip->i_mode&IFMT;
        !           741:        if (type==IFCHR) {
        !           742:                ip->i_flag |= IUPD|ICHG;
        !           743:                (*cdevsw[major(dev)]->d_write)(dev);
        !           744:                return;
        !           745:        }
        !           746:        if (Lsign(u.u_offset) < 0) {            /* and not IFCHR */
        !           747:                u.u_error = EINVAL;
        !           748:                return;
        !           749:        }
        !           750:        if (u.u_count == 0)
        !           751:                return;
        !           752:        if ((ip->i_mode&IFMT)==IFREG &&
        !           753:            (Lsign(Luadd(u.u_offset, u.u_count))!=0 || 
        !           754:             Ltol(u.u_offset) + u.u_count > u.u_limit[LIM_FSIZE])) {
        !           755:                u.u_error = EMFILE;
        !           756:                return;
        !           757:        }
        !           758:        if (type != IFBLK)
        !           759:                dev = ip->i_dev;
        !           760:        do {
        !           761:                bn = Lshift(u.u_offset, BSHIFT(dev));
        !           762:                on = Ltol(u.u_offset) & BMASK(dev);
        !           763:                n = MIN((unsigned)(BSIZE(dev)-on), u.u_count);
        !           764:                if (type!=IFBLK) {
        !           765:                        bn = bmap(ip, bn, B_WRITE);
        !           766:                        if((long)bn<0)
        !           767:                                return;
        !           768:                }
        !           769:                i = getfsx(dev);
        !           770:                if (bn && mfind(i, bn))
        !           771:                        munhash(i, bn);
        !           772:                if(n == BSIZE(dev)) 
        !           773:                        bp = getblk(dev, bn);
        !           774:                else
        !           775:                        bp = bread(dev, bn);
        !           776:                iomove(bp->b_un.b_addr+on, n, B_WRITE);
        !           777:                if(u.u_error != 0)
        !           778:                        brelse(bp);
        !           779:                else {
        !           780:                        if ((ip->i_mode&IFMT) == IFDIR &&
        !           781:                            ((struct direct *)(bp->b_un.b_addr+on))->d_ino == 0)
        !           782:                                bwrite(bp);     /* consistency */
        !           783:                        else if ((n+on) == BSIZE(dev))
        !           784:                                bawrite(bp);
        !           785:                        else
        !           786:                                bdwrite(bp);
        !           787:                }
        !           788:                if(Ltol(u.u_offset) > ip->i_size &&
        !           789:                   (type==IFDIR || type==IFREG || type==IFLNK))
        !           790:                        ip->i_size = Ltol(u.u_offset);
        !           791:                ip->i_flag |= IUPD|ICHG;
        !           792:        } while(u.u_error==0 && u.u_count!=0);
        !           793: }
        !           794: 
        !           795: /*
        !           796:  * Getfsx returns the index in the file system
        !           797:  * table of the specified device.  The swap device
        !           798:  * is also assigned a pseudo-index.  The index may
        !           799:  * be used as a compressed indication of the location
        !           800:  * of a block, recording
        !           801:  *     <getfsx(dev),blkno>
        !           802:  * rather than
        !           803:  *     <dev, blkno>
        !           804:  * provided the information need remain valid only
        !           805:  * as long as the file system is mounted.
        !           806:  *
        !           807:  * only the vm code calls this.
        !           808:  */
        !           809: getfsx(dev)
        !           810:        dev_t dev;
        !           811: {
        !           812:        register struct mount *mp;
        !           813: 
        !           814:        if (dev == swapdev)
        !           815:                return (MSWAPX);
        !           816:        for (mp = &fsmtab[fscnt-1]; mp >= fsmtab; mp--) {
        !           817:                if (mp->m_dev == NULL)
        !           818:                        continue;
        !           819:                if (mp->m_dev->i_un.i_rdev == dev)
        !           820:                        return (mp - fsmtab);
        !           821:        }
        !           822:        return (-1);
        !           823: }

unix.superglobalmegacorp.com

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