diff options
author | rsc <devnull@localhost> | 2005-08-11 16:45:39 +0000 |
---|---|---|
committer | rsc <devnull@localhost> | 2005-08-11 16:45:39 +0000 |
commit | e060bc52275a6d7eff5238fba5ba592004da3eb3 (patch) | |
tree | 4e80fe188be423c8fee9ec6b90c13a468f1b54da /src/libdiskfs | |
parent | 8ecefa411d235498ed036c6e173f62547a2e5dd4 (diff) | |
download | plan9port-e060bc52275a6d7eff5238fba5ba592004da3eb3.tar.gz plan9port-e060bc52275a6d7eff5238fba5ba592004da3eb3.tar.bz2 plan9port-e060bc52275a6d7eff5238fba5ba592004da3eb3.zip |
Add UFS2 support.
Diffstat (limited to 'src/libdiskfs')
-rw-r--r-- | src/libdiskfs/ffs.c | 155 | ||||
-rw-r--r-- | src/libdiskfs/ffs.h | 165 | ||||
-rw-r--r-- | src/libdiskfs/mkfile | 2 |
3 files changed, 219 insertions, 103 deletions
diff --git a/src/libdiskfs/ffs.c b/src/libdiskfs/ffs.c index d26d0ff3..f6a87883 100644 --- a/src/libdiskfs/ffs.c +++ b/src/libdiskfs/ffs.c @@ -6,6 +6,8 @@ #include <diskfs.h> #include "ffs.h" +#define BADBNO ((u64int)~0ULL) + #define checkcg 0 #define debug 0 @@ -57,7 +59,7 @@ error: } static Cgblk* -ffscylgrp(Ffs *fs, int i, Block **pb) +ffscylgrp(Ffs *fs, u32int i, Block **pb) { Block *b; Cgblk *cg; @@ -82,6 +84,7 @@ static int ffssync(Fsys *fsys) { int i; + int off[] = { SBOFF, SBOFF2, SBOFFPIGGY }; Block *b, *cgb; Cgblk *cgblk; Cylgrp *cg; @@ -95,12 +98,18 @@ ffssync(Fsys *fsys) /* * Read super block. */ - if((b = diskread(disk, SBSIZE, SBOFF)) == nil) - goto error; - fsblk = (Fsblk*)b->data; - if(checkfsblk(fsblk) < 0) - goto error; + for(i=0; i<nelem(off); i++){ + if((b = diskread(disk, SBSIZE, off[i])) == nil) + goto error; + fsblk = (Fsblk*)b->data; + fprint(2, "offset of magic: %d\n", offsetof(Fsblk, magic)); + if((fs->ufs = checkfsblk(fsblk)) > 0) + goto okay; + blockput(b); + } + goto error; +okay: fs->blocksize = fsblk->blocksize; fs->nblock = (fsblk->nfrag+fsblk->fragsperblock-1) / fsblk->fragsperblock; fs->fragsize = fsblk->fragsize; @@ -111,21 +120,31 @@ ffssync(Fsys *fsys) fs->nfrag = fsblk->nfrag; fs->ndfrag = fsblk->ndfrag; - fs->blockspergroup = (u64int)fsblk->cylspergroup * - fsblk->secspercyl * BYTESPERSEC / fsblk->blocksize; + /* + * used to use + * fs->blockspergroup = (u64int)fsblk->_cylspergroup * + * fsblk->secspercyl * BYTESPERSEC / fsblk->blocksize; + * for UFS1, but this should work for both UFS1 and UFS2 + */ + fs->blockspergroup = (u64int)fsblk->fragspergroup / fsblk->fragsperblock; fs->ncg = fsblk->ncg; fsys->blocksize = fs->blocksize; fsys->nblock = fs->nblock; - if(0) fprint(2, "ffs %d %d-byte blocks, %d cylinder groups\n", + if(debug) fprint(2, "ffs %lld %d-byte blocks, %d cylinder groups\n", fs->nblock, fs->blocksize, fs->ncg); + if(debug) fprint(2, "\tinospergroup %d perblock %d blockspergroup %lld\n", + fs->inospergroup, fs->inosperblock, fs->blockspergroup); if(fs->cg == nil) fs->cg = emalloc(fs->ncg*sizeof(Cylgrp)); for(i=0; i<fs->ncg; i++){ cg = &fs->cg[i]; - cg->bno = fs->blockspergroup*i + fsblk->cgoffset * (i & ~fsblk->cgmask); + if(fs->ufs == 2) + cg->bno = (u64int)fs->blockspergroup*i; + else + cg->bno = fs->blockspergroup*i + fsblk->_cgoffset * (i & ~fsblk->_cgmask); cg->cgblkno = cg->bno + fsblk->cfragno/fs->fragsperblock; cg->ibno = cg->bno + fsblk->ifragno/fs->fragsperblock; cg->dbno = cg->bno + fsblk->dfragno/fs->fragsperblock; @@ -172,12 +191,20 @@ ffsclose(Fsys *fsys) static int checkfsblk(Fsblk *super) { - if(super->magic != FSMAGIC){ - werrstr("bad super block"); - return -1; +fprint(2, "ffs magic 0x%ux\n", super->magic); + if(super->magic == FSMAGIC){ + super->time = super->_time; + super->nfrag = super->_nfrag; + super->ndfrag = super->_ndfrag; + super->flags = super->_flags; + return 1; + } + if(super->magic == FSMAGIC2){ + return 2; } - return 0; + werrstr("bad super block"); + return -1; } static int @@ -198,11 +225,10 @@ int nskipx; static Block* ffsblockread(Fsys *fsys, u64int bno) { - u32int i, o; + int i, o; u8int *fmap; int frag, fsize, avail; Block *b; -// Cylgrp *cg; Cgblk *cgblk; Ffs *fs; @@ -211,10 +237,6 @@ ffsblockread(Fsys *fsys, u64int bno) o = bno % fs->blockspergroup; if(i >= fs->ncg) return nil; -// cg = &fs->cg[i]; - -// if(o >= cg->nblock) -// return nil; if((cgblk = ffscylgrp(fs, i, &b)) == nil) return nil; @@ -257,7 +279,7 @@ nskipx++; } static Block* -ffsdatablock(Ffs *fs, u32int bno, int size) +ffsdatablock(Ffs *fs, u64int bno, int size) { int fsize; u64int diskaddr; @@ -290,25 +312,26 @@ ffsdatablock(Ffs *fs, u32int bno, int size) return b; } -static u32int -ifetch(Ffs *fs, u32int bno, u32int off) +static u64int +ifetch(Ffs *fs, u64int bno, u32int off) { - u32int *a; Block *b; - if(bno == ~0) - return ~0; + if(bno == BADBNO) + return BADBNO; b = ffsdatablock(fs, bno, fs->blocksize); if(b == nil) - return ~0; - a = (u32int*)b->data; - bno = a[off]; + return BADBNO; + if(fs->ufs == 2) + bno = ((u64int*)b->data)[off]; + else + bno = ((u32int*)b->data)[off]; blockput(b); return bno; } -static u32int -ffsfileblockno(Ffs *fs, Inode *ino, u32int bno) +static u64int +ffsfileblockno(Ffs *fs, Inode *ino, u64int bno) { int ppb; @@ -329,16 +352,15 @@ ffsfileblockno(Ffs *fs, Inode *ino, u32int bno) if(bno/ppb/ppb/ppb == 0) /* bno < ppb*ppb*ppb w/o overflow */ return ifetch(fs, ifetch(fs, ifetch(fs, ino->ib[2], bno/ppb/ppb), (bno/ppb)%ppb), bno%ppb); - bno -= ppb*ppb*ppb; - fprint(2, "ffsfileblock %lud: way too big\n", (ulong)bno+NDADDR); - return ~0; + fprint(2, "ffsfileblock %llud: way too big\n", bno+NDADDR+ppb+ppb*ppb); + return BADBNO; } static Block* -ffsfileblock(Ffs *fs, Inode *ino, u32int bno, int size) +ffsfileblock(Ffs *fs, Inode *ino, u64int bno, int size) { - u32int b; + u64int b; b = ffsfileblockno(fs, ino, bno); if(b == ~0) @@ -365,7 +387,33 @@ byte2u32(uchar *p) return (p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3]; } -static u64int iaddr; +static u64int lastiaddr; /* debugging */ + +static void +inode1to2(Inode1 *i1, Inode *i2) +{ + int i; + + memset(i2, 0, sizeof *i2); + i2->mode = i1->mode; + i2->nlink = i1->nlink; + i2->size = i1->size; + i2->atime = i1->atime; + i2->atimensec = i1->atimensec; + i2->mtime = i1->mtime; + i2->mtimensec = i1->mtimensec; + i2->ctime = i1->ctime; + i2->ctimensec = i1->ctimensec; + for(i=0; i<NDADDR; i++) + i2->db[i] = i1->db[i]; + for(i=0; i<NIADDR; i++) + i2->ib[i] = i1->ib[i]; + i2->flags = i1->flags; + i2->nblock = i1->nblock; + i2->gen = i1->gen; + i2->uid = i1->uid; + i2->gid = i1->gid; +} static Nfs3Status handle2ino(Ffs *fs, Nfs3Handle *h, u32int *pinum, Inode *ino) @@ -373,8 +421,10 @@ handle2ino(Ffs *fs, Nfs3Handle *h, u32int *pinum, Inode *ino) int i; u32int ioff; u32int inum; + u64int iaddr; Block *b; Cylgrp *cg; + Inode1 ino1; if(h->len != 4) return Nfs3ErrBadHandle; @@ -390,20 +440,21 @@ handle2ino(Ffs *fs, Nfs3Handle *h, u32int *pinum, Inode *ino) if(i >= fs->ncg) return Nfs3ErrBadHandle; cg = &fs->cg[i]; -/* - if(ioff >= cg->nino) - return Nfs3ErrBadHandle; -*/ - if(debug) print("cg->ibno %d...", cg->ibno); - if((b = diskread(fs->disk, fs->blocksize, - (cg->ibno+ioff/fs->inosperblock)*(vlong)fs->blocksize)) == nil) + if(debug) print("cg->ibno %lld ufs %d...", cg->ibno, fs->ufs); + iaddr = (cg->ibno+ioff/fs->inosperblock)*(vlong)fs->blocksize; + ioff = ioff%fs->inosperblock; + if((b = diskread(fs->disk, fs->blocksize, iaddr)) == nil) return Nfs3ErrIo; - iaddr = (cg->ibno+ioff/fs->inosperblock)*(vlong)fs->blocksize - + (ioff%fs->inosperblock)*sizeof(Inode); - *ino = ((Inode*)b->data)[ioff%fs->inosperblock]; + if(fs->ufs == 2){ + *ino = ((Inode*)b->data)[ioff]; + lastiaddr = iaddr+ioff*sizeof(Inode); + }else{ + ino1 = ((Inode1*)b->data)[ioff]; + inode1to2(&ino1, ino); + lastiaddr = iaddr+ioff*sizeof(Inode1); + } blockput(b); - return Nfs3Ok; } @@ -717,7 +768,7 @@ ffsreaddir(Fsys *fsys, SunAuthUnix *au, Nfs3Handle *h, u32int count, u64int cook static u64int ffsxfileblock(Fsys *fsys, Nfs3Handle *h, u64int offset) { - u32int bno; + u64int bno; Inode ino; Nfs3Status ok; Ffs *fs; @@ -727,8 +778,8 @@ ffsxfileblock(Fsys *fsys, Nfs3Handle *h, u64int offset) nfs3errstr(ok); return 0; } - if(offset == 1) - return iaddr; + if(offset == 1) /* clumsy hack for debugging */ + return lastiaddr; if(offset >= ino.size){ werrstr("beyond end of file"); return 0; @@ -820,7 +871,7 @@ ffsreadlink(Fsys *fsys, SunAuthUnix *au, Nfs3Handle *h, char **link) len = ino.size; if(ino.nblock != 0){ - /* BUG: assumes symlink fits in one block */ + /* assumes symlink fits in one block */ b = ffsfileblock(fs, &ino, 0, len); if(b == nil) return Nfs3ErrIo; diff --git a/src/libdiskfs/ffs.h b/src/libdiskfs/ffs.h index 479ff65f..4a90aef2 100644 --- a/src/libdiskfs/ffs.h +++ b/src/libdiskfs/ffs.h @@ -19,8 +19,10 @@ typedef struct Cgblk Cgblk; typedef struct Cylgrp Cylgrp; typedef struct Cylsum Cylsum; +typedef struct Cylsumtotal Cylsumtotal; typedef struct Ffs Ffs; typedef struct Fsblk Fsblk; +typedef struct Inode1 Inode1; typedef struct Inode Inode; typedef struct Dirent Dirent; @@ -30,9 +32,13 @@ enum /* constants for Fsblk */ FSMAXMNTLEN = 512, - FSNOCSPTRS = 128 / sizeof(void*) - 3, + FSMAXMNTLEN2 = 468, + FSMAXVOLLEN = 32, /* UFS2 */ + FSNOCSPTRSLEN = 128-12, + FSNOCSPTRSLEN2 = 128-16, /* UFS2 */ FSMAXSNAP = 20, FSMAGIC = 0x011954, + FSMAGIC2 = 0x19540119, FSCHECKSUM = 0x7c269d38, /* Fsblk.inodefmt */ @@ -45,6 +51,8 @@ enum /* offset and size of first super block */ SBOFF = BBOFF+BBSIZE, + SBOFF2 = BBOFF+65536, /* UFS2 */ + SBOFFPIGGY = BBOFF+262144, /* UFS2 */ SBSIZE = 8192, /* minimum block size */ @@ -60,6 +68,7 @@ enum ROOTINODE = 2, WHITEOUT = 1, + NXADDR = 2, /* UFS2 */ NDADDR = 12, NIADDR = 3, @@ -102,6 +111,17 @@ struct Cylsum u32int nffree; }; +struct Cylsumtotal +{ + u64int ndir; + u64int nbfree; + u64int nifree; + u64int nffree; + u64int numclusters; + u64int unused[3]; +}; + +/* Fields beginning with underscore are deprecated in UFS2 */ struct Fsblk { u32int unused0; @@ -110,11 +130,11 @@ struct Fsblk daddr_t cfragno; /* fragment address if cylinder block in file system */ daddr_t ifragno; /* fragment offset of inode blocks in file system */ daddr_t dfragno; /* fragment offset of data blocks in cg */ - u32int cgoffset; /* block (maybe fragment?) offset of Cgblk in cylinder */ - u32int cgmask; - time_t time; - u32int nfrag; /* number of blocks in fs * fragsperblock */ - u32int ndfrag; + u32int _cgoffset; /* block (maybe fragment?) offset of Cgblk in cylinder */ + u32int _cgmask; + time_t _time; + u32int _nfrag; /* number of blocks in fs * fragsperblock */ + u32int _ndfrag; u32int ncg; /* number of cylinder groups in fs */ u32int blocksize; /* block size in fs */ u32int fragsize; /* frag size in fs */ @@ -130,58 +150,73 @@ struct Fsblk u32int maxbpg; u32int fragshift; u32int fsbtodbshift; - u32int sbsize; /* size of super block */ + u32int sbsize; /* size of super block */ u32int unused2; /* more stuff we don't use ... */ u32int unused3; u32int nindir; u32int inosperblock; /* inodes per block */ - u32int nspf; + u32int _nspf; u32int optim; - u32int npsect; - u32int interleave; - u32int trackskew; + u32int _npsect; + u32int _interleave; + u32int _trackskew; u32int id[2]; - daddr_t csaddr; /* blk addr of cyl grp summary area */ - u32int cssize; /* size of cyl grp summary area */ - u32int cgsize; /* cylinder group size */ - u32int trackspercyl; /* tracks per cylinder */ - u32int secspertrack; /* sectors per track */ - u32int secspercyl; /* sectors per cylinder */ - u32int ncyl; /* cylinders in fs */ - u32int cylspergroup; /* cylinders per group */ + daddr_t _csaddr; /* blk addr of cyl grp summary area */ + u32int cssize; /* size of cyl grp summary area */ + u32int cgsize; /* cylinder group size */ + u32int _trackspercyl; /* tracks per cylinder */ + u32int _secspertrack; /* sectors per track */ + u32int _secspercyl; /* sectors per cylinder */ + u32int _ncyl; /* cylinders in fs */ + u32int _cylspergroup; /* cylinders per group */ u32int inospergroup; /* inodes per group */ u32int fragspergroup; /* data blocks per group * fragperblock */ - Cylsum cstotal; /* more unused... */ + Cylsum _cstotal; /* more unused... */ u8int fmod; u8int clean; u8int ronly; - u8int flags; - char fsmnt[FSMAXMNTLEN]; + u8int _flags; + /* char fsmnt[512]; in UFS1 */ + char fsmnt[FSMAXMNTLEN2]; + char volname[FSMAXVOLLEN]; + u64int swuid; + u32int pad; u32int cgrotor; - void* ocsp[FSNOCSPTRS]; - u8int* contigdirs; - Cylsum* csp; - u32int* maxcluster; - u32int cpc; - u16int opostbl[16][8]; + uchar ocsp[FSNOCSPTRSLEN]; /* last 4 bytes is contigdirs in UFS2 */ + u32int contigdirs; /* csp in UFS2 */ + u32int csp; /* maxcluster in UFS2 */ + u32int maxcluster; /* active in UFS2 */ + u32int _cpc; + /* u16int opostbl[16][8]; in UFS1 */ + u32int maxbsize; + u64int spare64[17]; + u64int sblockloc; + Cylsumtotal cstotal; + u64int time; + u64int nfrag; + u64int ndfrag; + u64int csaddr; + u64int pendingblocks; + u32int pendinginodes; u32int snapinum[FSMAXSNAP]; u32int avgfilesize; u32int avgfpdir; - u32int sparecon[26]; - u32int pendingblocks; - u32int pendinginodes; + /* u32int sparecon[26], pendingblocks, pendinginodes; in UFS1 */ + u32int savecgsize; + u32int sparecon[26]; + u32int flags; u32int contigsumsize; u32int maxsymlinklen; - u32int inodefmt; /* format of on-disk inodes */ + u32int _inodefmt; /* format of on-disk inodes */ u64int maxfilesize; /* maximum representable file size */ u64int qbmask; u64int qfmask; u32int state; - u32int postblformat; - u32int nrpos; - u32int postbloff; - u32int rotbloff; - u32int magic; /* FS_MAGIC */ + u32int _postblformat; + u32int _nrpos; + u32int _postbloff; + u32int _rotbloff; + u32int magic; /* FSMAGIC or FSMAGIC2 */ }; /* @@ -190,12 +225,12 @@ struct Fsblk struct Cgblk { u32int unused0; - u32int magic; /* CGMAGIC */ + u32int magic; /* CGMAGIC */ u32int time; /* time last written */ - u32int num; /* we are cg #cgnum */ + u32int num; /* we are cg #cgnum */ u16int ncyl; /* number of cylinders in gp */ - u16int nino; /* number of inodes */ - u32int nfrag; /* number of fragments */ + u16int nino; /* number of inodes */ + u32int nfrag; /* number of fragments */ Cylsum csum; u32int rotor; u32int frotor; @@ -215,16 +250,16 @@ struct Cgblk struct Cylgrp { /* these are block numbers not fragment numbers */ - u32int bno; /* disk block address of start of cg */ - u32int ibno; /* disk block address of first inode */ - u32int dbno; /* disk block address of first data */ - u32int cgblkno; + u64int bno; /* disk block address of start of cg */ + u64int ibno; /* disk block address of first inode */ + u64int dbno; /* disk block address of first data */ + u64int cgblkno; }; /* * this is the on-disk structure */ -struct Inode +struct Inode1 { u16int mode; u16int nlink; @@ -247,6 +282,33 @@ struct Inode u32int spare[2]; }; +struct Inode +{ + u16int mode; + u16int nlink; + u32int uid; + u32int gid; + u32int blksize; + u64int size; + u64int nblock; + u64int atime; + u64int mtime; + u64int ctime; + u64int btime; + u32int atimensec; + u32int mtimensec; + u32int ctimensec; + u32int btimensec; + u32int gen; + u32int kernflags; + u32int flags; + u32int extsize; + u64int ext[NXADDR]; + u64int db[NDADDR]; + u64int ib[NIADDR]; + u64int spare[3]; +}; + struct Dirent { u32int ino; @@ -261,17 +323,18 @@ struct Dirent */ struct Ffs { + int ufs; int blocksize; - int nblock; + u64int nblock; int fragsize; int fragsperblock; int inosperblock; - int blockspergroup; - int fragspergroup; + u64int blockspergroup; + u64int fragspergroup; int inospergroup; - u32int nfrag; - u32int ndfrag; + u64int nfrag; + u64int ndfrag; int ncg; Cylgrp *cg; diff --git a/src/libdiskfs/mkfile b/src/libdiskfs/mkfile index 61538da1..cade2662 100644 --- a/src/libdiskfs/mkfile +++ b/src/libdiskfs/mkfile @@ -29,3 +29,5 @@ CFLAGS=$CFLAGS %.acid: %.$O %.c $CC $CFLAGS -a $stem.c >$stem.acid + +ffs.$O: ffs.h |