Annotation of researchv10no/netfs/serv/ffs.c, revision 1.1.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.