Annotation of researchv10no/netfs/serv/ffs.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * read a Berkeley `fast file system'
        !             3:  * quick, cheap hack
        !             4:  */
        !             5: 
        !             6: #include <stdio.h>
        !             7: #include <sys/types.h>
        !             8: #include <sys/stat.h>  /* for file modes; they happen to match */
        !             9: #include "bsdffs.h"
        !            10: 
        !            11: #include "rf.h"
        !            12: #include <errno.h>
        !            13: #include <libc.h>
        !            14: 
        !            15: int fserrno;
        !            16: static int devfd;
        !            17: static Rfile *root;
        !            18: static union {
        !            19:        char buf[SBSIZE];
        !            20:        struct fs super;
        !            21: } super;
        !            22: #define        sb      (super.super)
        !            23: static long firstblk;  /* offset to beginning of filsys */
        !            24: static char *blk;
        !            25: 
        !            26: typedef struct Fsfile {
        !            27:        long dir[NDADDR];
        !            28:        long ind[NIADDR];
        !            29: } Fsfile;
        !            30: #define        fsp(f)  ((Fsfile *)((f)->fs))
        !            31: 
        !            32: /*
        !            33:  * init:
        !            34:  * open the device
        !            35:  */
        !            36: 
        !            37: Rfile *
        !            38: fsinit(argc, argv)
        !            39: int argc;
        !            40: char **argv;
        !            41: {
        !            42:        register Rfile *f;
        !            43: 
        !            44:        if (argc <= 1)
        !            45:                rfpanic("no device specified\n");
        !            46:        if ((devfd = open(argv[1], 0)) < 0)
        !            47:                rfpanic("%s: cannot open\n", argv[1]);
        !            48:        if (argc > 2)
        !            49:                firstblk = atol(argv[2]) * 512;
        !            50:        lseek(devfd, firstblk + SBLOCK, 0);
        !            51:        if (read(devfd, super.buf, SBSIZE) != SBSIZE)
        !            52:                rfpanic("can't read super block\n");
        !            53:        if ((blk = malloc(sb.fs_bsize)) == NULL)
        !            54:                rfpanic("can't alloc %d for block buf\n", sb.fs_bsize);
        !            55:        if ((f = (Rfile *)malloc(sizeof(Rfile))) == NULL)
        !            56:                rfpanic("no mem for root\n");
        !            57:        if ((f->fs = malloc(sizeof(Fsfile))) == NULL)
        !            58:                rfpanic("no mem for root\n");
        !            59:        f->ino = ROOTINO;
        !            60:        fsstat(f);
        !            61:        root = f;
        !            62:        return (f);
        !            63: }
        !            64: 
        !            65: /*
        !            66:  * access a file
        !            67:  */
        !            68: 
        !            69: Rfile *
        !            70: fswalk(df, name)
        !            71: register Rfile *df;
        !            72: char *name;
        !            73: {
        !            74:        register Rfile *f;
        !            75:        int ino;
        !            76: 
        !            77:        if ((ino = dsearch(df, name)) == 0) {
        !            78:                fserrno = ENOENT;
        !            79:                return (NULL);
        !            80:        }
        !            81:        if (df == root) {       /* "." and ".." magic */
        !            82:                if (strcmp(name, ".") == 0)
        !            83:                        return (df);
        !            84:                if (strcmp(name, "..") == 0) {
        !            85:                        fserrno = 0;    /* pseudo-error: popped out of root */
        !            86:                        return (NULL);
        !            87:                }
        !            88:        }
        !            89:        if ((f = (Rfile *)malloc(sizeof(Rfile))) == NULL) {
        !            90:                fserrno = ENOMEM;
        !            91:                return (NULL);
        !            92:        }
        !            93:        if ((f->fs = malloc(sizeof(Fsfile))) == NULL) {
        !            94:                free((char *)f);
        !            95:                fserrno = ENOMEM;
        !            96:                return (NULL);
        !            97:        }
        !            98:        f->ino = ino;
        !            99:        fsstat(f);
        !           100:        return (f);
        !           101: }
        !           102: 
        !           103: /*
        !           104:  * discard a file reference
        !           105:  */
        !           106: int
        !           107: fsdone(f)
        !           108: Rfile *f;
        !           109: {
        !           110: 
        !           111:        free(f->fs);
        !           112:        free((char *)f);
        !           113:        return (0);
        !           114: }
        !           115: 
        !           116: /*
        !           117:  * return file status
        !           118:  */
        !           119: int
        !           120: fsstat(f)
        !           121: Rfile *f;
        !           122: {
        !           123: 
        !           124:        getino(f);
        !           125:        return (0);
        !           126: }
        !           127: 
        !           128: /*
        !           129:  * read data
        !           130:  */
        !           131: int
        !           132: fsread(f, off, buf, len)
        !           133: register Rfile *f;
        !           134: long off;
        !           135: char *buf;
        !           136: int len;
        !           137: {
        !           138:        int rest;
        !           139:        long bno;
        !           140: 
        !           141:        switch (f->mode & S_IFMT) {
        !           142:        case S_IFREG:
        !           143:        case S_IFDIR:
        !           144:                break;
        !           145: 
        !           146:        default:
        !           147:                return (0);
        !           148:        }
        !           149:        if (off >= f->size)
        !           150:                return (0);
        !           151:        if (off + len > f->size)
        !           152:                len = f->size - off;
        !           153:        bno = off / sb.fs_bsize;
        !           154:        if (getlblk(f, bno, blk, f->size - bno*sb.fs_bsize) == 0)
        !           155:                return (-1);
        !           156:        rest = (bno + 1)*sb.fs_bsize - off;
        !           157:        if (len > rest)
        !           158:                len = rest;
        !           159:        memcpy(buf, blk + (off % sb.fs_bsize), len);
        !           160:        return (len);
        !           161: }
        !           162: 
        !           163: /*
        !           164:  * read a piece of a directory
        !           165:  */
        !           166: int
        !           167: fsdirread(f, off, buf, len, offp)
        !           168: register Rfile *f;
        !           169: long off;
        !           170: char *buf;
        !           171: int len;
        !           172: long *offp;
        !           173: {
        !           174:        int stlen;
        !           175:        register struct direct *de;
        !           176:        struct direct *endblk;
        !           177:        char one[MAXNAMLEN+30];
        !           178:        int n;
        !           179: 
        !           180:        stlen = len;
        !           181:        endblk = de = (struct direct *)&blk[sb.fs_bsize];
        !           182:        for (; off < f->size; off += de->d_reclen,
        !           183:             de = (struct direct *)&blk[off%sb.fs_bsize]) {
        !           184:                if (de >= endblk) {
        !           185:                        if (getlblk(f, off/sb.fs_bsize, blk, f->size - off) == 0)
        !           186:                                break;
        !           187:                        de = (struct direct *)&blk[off%sb.fs_bsize];
        !           188:                }
        !           189:                if (de->d_reclen == 0)
        !           190:                        break;
        !           191:                if (de->d_ino == 0)
        !           192:                        continue;
        !           193:                sprintf(one, "%ld\t%s", de->d_ino, de->d_name);
        !           194:                n = strlen(one)+1;
        !           195:                if (n > len)
        !           196:                        break;
        !           197:                memcpy(buf, one, n);
        !           198:                len -= n;
        !           199:                buf += n;
        !           200:        }
        !           201:        *offp = off;
        !           202:        return (stlen - len);
        !           203: }
        !           204: 
        !           205: /*
        !           206:  * fetch an i-node
        !           207:  * -- no sanity check for now
        !           208:  * -- magic inode-to-disk-block stuff here
        !           209:  */
        !           210: 
        !           211: int
        !           212: getino(f)
        !           213: register Rfile *f;
        !           214: {
        !           215:        register struct icommon *dp;
        !           216:        register int cg;
        !           217:        register long ifrag;
        !           218:        register long ino;
        !           219: 
        !           220:        cg = f->ino / sb.fs_ipg;
        !           221:        ino = f->ino % sb.fs_ipg;
        !           222:        ifrag = cg*sb.fs_fpg + sb.fs_cgoffset*(cg&~sb.fs_cgmask) + sb.fs_iblkno;
        !           223:        ifrag += ino / (sb.fs_fsize/sizeof(struct icommon));
        !           224:        lseek(devfd, firstblk + ifrag * sb.fs_fsize, 0);
        !           225:        if (read(devfd, blk, sb.fs_fsize) != sb.fs_fsize) {
        !           226:                /* print error */
        !           227:                return (0);
        !           228:        }
        !           229:        dp = ((struct icommon *)blk) + (ino % (sb.fs_fsize/sizeof(struct icommon)));
        !           230:        switch (dp->i_mode & S_IFMT) {
        !           231:        case S_IFREG:
        !           232:        case S_IFDIR:
        !           233:        case S_IFBLK:
        !           234:        case S_IFCHR:
        !           235:                break;
        !           236: 
        !           237:        default:
        !           238:                return (0);     /* unalloc or illegal */
        !           239:        }
        !           240:        memcpy((char *)fsp(f)->dir, (char *)dp->i_db, NDADDR*sizeof(long));
        !           241:        memcpy((char *)fsp(f)->ind, (char *)dp->i_ib, NIADDR*sizeof(long));
        !           242:        f->dev = 0;
        !           243:        f->rdev = 0;    /* well ... */
        !           244:        f->mode = dp->i_mode;
        !           245:        f->nlink = dp->i_nlink;
        !           246:        f->uid = dp->i_uid;
        !           247:        f->gid = dp->i_gid;
        !           248:        f->size = dp->i_size;
        !           249:        f->tm = dp->i_mtime;
        !           250:        f->ta = dp->i_atime;
        !           251:        f->tc = dp->i_ctime;
        !           252:        return (1);
        !           253: }
        !           254: 
        !           255: /*
        !           256:  * look up a file
        !           257:  */
        !           258: 
        !           259: int
        !           260: dsearch(f, name)
        !           261: Rfile *f;
        !           262: char *name;
        !           263: {
        !           264:        register struct direct *de;
        !           265:        register struct direct *endblk;
        !           266:        register long b, size;
        !           267: 
        !           268:        endblk = (struct direct *)(blk + sb.fs_bsize);
        !           269:        for (b = 0, size = f->size; size > 0; b++, size -= sb.fs_bsize) {
        !           270:                if (getlblk(f, b, blk, size) == 0)
        !           271:                        continue;
        !           272:                for (de = (struct direct *)blk; de < endblk;
        !           273:                     de = (struct direct *)((char *)de + de->d_reclen)) {
        !           274:                        if (de->d_reclen == 0)          /* safety */
        !           275:                                break;
        !           276:                        if (de->d_ino == 0)
        !           277:                                continue;
        !           278:                        if (strcmp(de->d_name, name) == 0)
        !           279:                                return (de->d_ino);
        !           280:                }
        !           281:        }
        !           282:        return (0);
        !           283: }
        !           284: 
        !           285: /*
        !           286:  * read a block from a file
        !           287:  */
        !           288: long bmap();
        !           289: 
        !           290: getlblk(f, bno, buf, maxlen)
        !           291: Rfile *f;
        !           292: long bno;
        !           293: char *buf;
        !           294: int maxlen;
        !           295: {
        !           296:        long dbno;
        !           297: 
        !           298:        if (maxlen > sb.fs_bsize)
        !           299:                maxlen = sb.fs_bsize;
        !           300:        if ((dbno = bmap(f, bno)) == 0) {
        !           301:                memset(buf, 0, maxlen);
        !           302:                return (1);
        !           303:        }
        !           304:        lseek(devfd, firstblk + dbno*sb.fs_fsize, 0);
        !           305:        if (read(devfd, buf, maxlen) != maxlen) {
        !           306:                fserrno = errno;
        !           307:                return (0);
        !           308:        }
        !           309:        return (1);
        !           310: }
        !           311: 
        !           312: /*
        !           313:  * logical to physical block
        !           314:  * only singly-indirect files for now
        !           315:  */
        !           316: 
        !           317: long
        !           318: bmap(f, bno)
        !           319: register Rfile *f;
        !           320: long bno;
        !           321: {
        !           322: 
        !           323:        if (bno < NDADDR)
        !           324:                return (fsp(f)->dir[bno]);
        !           325:        bno -= NDADDR;
        !           326:        if (bno >= sb.fs_nindir)
        !           327:                return (0);
        !           328:        lseek(devfd, firstblk + fsp(f)->ind[0] * sb.fs_fsize, 0);
        !           329:        if (read(devfd, blk, sb.fs_bsize) != sb.fs_bsize)
        !           330:                return (0);
        !           331:        return (((long *)blk)[bno]);
        !           332: }

unix.superglobalmegacorp.com

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