| /* |
| * An FFS file system is a sequence of cylinder groups. |
| * |
| * Each cylinder group is laid out as follows: |
| * |
| * fs superblock (Fsblk) |
| * cylinder group block (Cgblk) |
| * inodes |
| * data |
| * |
| * The location of the fs superblock in the first cylinder |
| * group is known. The rest of the info about cylinder group |
| * layout can be derived from the super block. |
| */ |
| |
| #define daddr_t u32int |
| #define time_t u32int |
| |
| 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; |
| |
| enum |
| { |
| BYTESPERSEC = 512, |
| |
| /* constants for Fsblk */ |
| FSMAXMNTLEN = 512, |
| FSMAXMNTLEN2 = 468, |
| FSMAXVOLLEN = 32, /* UFS2 */ |
| FSNOCSPTRSLEN = 128-12, |
| FSNOCSPTRSLEN2 = 128-16, /* UFS2 */ |
| FSMAXSNAP = 20, |
| FSMAGIC = 0x011954, |
| FSMAGIC2 = 0x19540119, |
| FSCHECKSUM = 0x7c269d38, |
| |
| /* Fsblk.inodefmt */ |
| FS42INODEFMT = -1, |
| FS44INODEFMT = 2, |
| |
| /* offset and size of first boot block */ |
| BBOFF = 0, |
| BBSIZE = 8192, |
| |
| /* offset and size of first super block */ |
| SBOFF = BBOFF+BBSIZE, |
| SBOFF2 = BBOFF+65536, /* UFS2 */ |
| SBOFFPIGGY = BBOFF+262144, /* UFS2 */ |
| SBSIZE = 8192, |
| |
| /* minimum block size */ |
| MINBSIZE = 4096, |
| |
| /* maximum fragments per block */ |
| MAXFRAG = 8, |
| |
| /* constants for Cgblk */ |
| CGMAGIC = 0x090255, |
| |
| /* inode-related */ |
| ROOTINODE = 2, |
| WHITEOUT = 1, |
| |
| NXADDR = 2, /* UFS2 */ |
| NDADDR = 12, |
| NIADDR = 3, |
| |
| /* permissions in Inode.mode */ |
| IEXEC = 00100, |
| IWRITE = 0200, |
| IREAD = 0400, |
| ISVTX = 01000, |
| ISGID = 02000, |
| ISUID = 04000, |
| |
| /* type in Inode.mode */ |
| IFMT = 0170000, |
| IFIFO = 0010000, |
| IFCHR = 0020000, |
| IFDIR = 0040000, |
| IFBLK = 0060000, |
| IFREG = 0100000, |
| IFLNK = 0120000, |
| IFSOCK = 0140000, |
| IFWHT = 0160000, |
| |
| /* type in Dirent.type */ |
| DTUNKNOWN = 0, |
| DTFIFO = 1, |
| DTCHR = 2, |
| DTDIR = 4, |
| DTBLK = 6, |
| DTREG = 8, |
| DTLNK = 10, |
| DTSOCK = 12, |
| DTWHT = 14 |
| }; |
| |
| struct Cylsum |
| { |
| u32int ndir; |
| u32int nbfree; |
| u32int nifree; |
| 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; |
| u32int unused1; |
| daddr_t sfragno; /* fragment address of super block in file system */ |
| 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 ncg; /* number of cylinder groups in fs */ |
| u32int blocksize; /* block size in fs */ |
| u32int fragsize; /* frag size in fs */ |
| u32int fragsperblock; /* fragments per block: blocksize / fragsize */ |
| u32int minfree; /* ignored by us */ |
| u32int rotdelay; /* ... */ |
| u32int rps; |
| u32int bmask; |
| u32int fmask; |
| u32int bshift; |
| u32int fshift; |
| u32int maxcontig; |
| u32int maxbpg; |
| u32int fragshift; |
| u32int fsbtodbshift; |
| 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 optim; |
| 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 */ |
| u32int inospergroup; /* inodes per group */ |
| u32int fragspergroup; /* data blocks per group * fragperblock */ |
| Cylsum _cstotal; /* more unused... */ |
| u8int fmod; |
| u8int clean; |
| u8int ronly; |
| u8int _flags; |
| /* char fsmnt[512]; in UFS1 */ |
| char fsmnt[FSMAXMNTLEN2]; |
| char volname[FSMAXVOLLEN]; |
| u64int swuid; |
| u32int pad; |
| u32int cgrotor; |
| 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], pendingblocks, pendinginodes; in UFS1 */ |
| u32int savecgsize; |
| u32int sparecon[26]; |
| u32int flags; |
| u32int contigsumsize; |
| u32int maxsymlinklen; |
| 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; /* FSMAGIC or FSMAGIC2 */ |
| }; |
| |
| /* |
| * Cylinder group block for a file system. |
| */ |
| struct Cgblk |
| { |
| u32int unused0; |
| u32int magic; /* CGMAGIC */ |
| u32int time; /* time last written */ |
| u32int num; /* we are cg #cgnum */ |
| u16int ncyl; /* number of cylinders in gp */ |
| u16int nino; /* number of inodes */ |
| u32int nfrag; /* number of fragments */ |
| Cylsum csum; |
| u32int rotor; |
| u32int frotor; |
| u32int irotor; |
| u32int frsum[MAXFRAG]; /* counts of available frags */ |
| u32int btotoff; |
| u32int boff; |
| u32int imapoff; /* offset to used inode map */ |
| u32int fmapoff; /* offset to free fragment map */ |
| u32int nextfrag; /* next free fragment */ |
| u32int csumoff; |
| u32int clusteroff; |
| u32int ncluster; |
| u32int sparecon[13]; |
| }; |
| |
| struct Cylgrp |
| { |
| /* these are block numbers not fragment numbers */ |
| 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 Inode1 |
| { |
| u16int mode; |
| u16int nlink; |
| u32int unused; |
| u64int size; |
| u32int atime; |
| u32int atimensec; |
| u32int mtime; |
| u32int mtimensec; |
| u32int ctime; |
| u32int ctimensec; |
| /* rdev is db[0] */ |
| u32int db[NDADDR]; |
| u32int ib[NIADDR]; |
| u32int flags; |
| u32int nblock; |
| u32int gen; |
| u32int uid; |
| u32int gid; |
| 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; |
| u16int reclen; |
| u8int type; |
| u8int namlen; |
| char name[1]; |
| }; |
| |
| /* |
| * main file system structure |
| */ |
| struct Ffs |
| { |
| int ufs; |
| int blocksize; |
| u64int nblock; |
| int fragsize; |
| int fragsperblock; |
| int inosperblock; |
| u64int blockspergroup; |
| u64int fragspergroup; |
| int inospergroup; |
| |
| u64int nfrag; |
| u64int ndfrag; |
| |
| int ncg; |
| Cylgrp *cg; |
| |
| Disk *disk; |
| }; |
| |