2005-07-13 03:48:35 +00:00
|
|
|
/*
|
|
|
|
* 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;
|
2005-08-11 16:45:39 +00:00
|
|
|
typedef struct Cylsumtotal Cylsumtotal;
|
2005-07-13 03:48:35 +00:00
|
|
|
typedef struct Ffs Ffs;
|
|
|
|
typedef struct Fsblk Fsblk;
|
2005-08-11 16:45:39 +00:00
|
|
|
typedef struct Inode1 Inode1;
|
2005-07-13 03:48:35 +00:00
|
|
|
typedef struct Inode Inode;
|
|
|
|
typedef struct Dirent Dirent;
|
|
|
|
|
|
|
|
enum
|
|
|
|
{
|
|
|
|
BYTESPERSEC = 512,
|
|
|
|
|
|
|
|
/* constants for Fsblk */
|
|
|
|
FSMAXMNTLEN = 512,
|
2005-08-11 16:45:39 +00:00
|
|
|
FSMAXMNTLEN2 = 468,
|
|
|
|
FSMAXVOLLEN = 32, /* UFS2 */
|
|
|
|
FSNOCSPTRSLEN = 128-12,
|
|
|
|
FSNOCSPTRSLEN2 = 128-16, /* UFS2 */
|
2005-07-13 03:48:35 +00:00
|
|
|
FSMAXSNAP = 20,
|
|
|
|
FSMAGIC = 0x011954,
|
2005-08-11 16:45:39 +00:00
|
|
|
FSMAGIC2 = 0x19540119,
|
2005-07-13 03:48:35 +00:00
|
|
|
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,
|
2005-08-11 16:45:39 +00:00
|
|
|
SBOFF2 = BBOFF+65536, /* UFS2 */
|
|
|
|
SBOFFPIGGY = BBOFF+262144, /* UFS2 */
|
2005-07-13 03:48:35 +00:00
|
|
|
SBSIZE = 8192,
|
|
|
|
|
|
|
|
/* minimum block size */
|
|
|
|
MINBSIZE = 4096,
|
|
|
|
|
|
|
|
/* maximum fragments per block */
|
|
|
|
MAXFRAG = 8,
|
|
|
|
|
|
|
|
/* constants for Cgblk */
|
|
|
|
CGMAGIC = 0x090255,
|
|
|
|
|
|
|
|
/* inode-related */
|
|
|
|
ROOTINODE = 2,
|
|
|
|
WHITEOUT = 1,
|
|
|
|
|
2005-08-11 16:45:39 +00:00
|
|
|
NXADDR = 2, /* UFS2 */
|
2005-07-13 03:48:35 +00:00
|
|
|
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;
|
|
|
|
};
|
|
|
|
|
2005-08-11 16:45:39 +00:00
|
|
|
struct Cylsumtotal
|
|
|
|
{
|
|
|
|
u64int ndir;
|
|
|
|
u64int nbfree;
|
|
|
|
u64int nifree;
|
|
|
|
u64int nffree;
|
|
|
|
u64int numclusters;
|
|
|
|
u64int unused[3];
|
|
|
|
};
|
|
|
|
|
|
|
|
/* Fields beginning with underscore are deprecated in UFS2 */
|
2005-07-13 03:48:35 +00:00
|
|
|
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 */
|
2005-08-11 16:45:39 +00:00
|
|
|
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;
|
2005-07-13 03:48:35 +00:00
|
|
|
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;
|
2005-08-11 16:45:39 +00:00
|
|
|
u32int sbsize; /* size of super block */
|
2005-07-13 03:48:35 +00:00
|
|
|
u32int unused2; /* more stuff we don't use ... */
|
|
|
|
u32int unused3;
|
|
|
|
u32int nindir;
|
|
|
|
u32int inosperblock; /* inodes per block */
|
2005-08-11 16:45:39 +00:00
|
|
|
u32int _nspf;
|
2005-07-13 03:48:35 +00:00
|
|
|
u32int optim;
|
2005-08-11 16:45:39 +00:00
|
|
|
u32int _npsect;
|
|
|
|
u32int _interleave;
|
|
|
|
u32int _trackskew;
|
2005-07-13 03:48:35 +00:00
|
|
|
u32int id[2];
|
2005-08-11 16:45:39 +00:00
|
|
|
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 */
|
2005-07-13 03:48:35 +00:00
|
|
|
u32int inospergroup; /* inodes per group */
|
|
|
|
u32int fragspergroup; /* data blocks per group * fragperblock */
|
2005-08-11 16:45:39 +00:00
|
|
|
Cylsum _cstotal; /* more unused... */
|
2005-07-13 03:48:35 +00:00
|
|
|
u8int fmod;
|
|
|
|
u8int clean;
|
|
|
|
u8int ronly;
|
2005-08-11 16:45:39 +00:00
|
|
|
u8int _flags;
|
|
|
|
/* char fsmnt[512]; in UFS1 */
|
|
|
|
char fsmnt[FSMAXMNTLEN2];
|
|
|
|
char volname[FSMAXVOLLEN];
|
|
|
|
u64int swuid;
|
|
|
|
u32int pad;
|
2005-07-13 03:48:35 +00:00
|
|
|
u32int cgrotor;
|
2005-08-11 16:45:39 +00:00
|
|
|
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;
|
2005-07-13 03:48:35 +00:00
|
|
|
u32int snapinum[FSMAXSNAP];
|
|
|
|
u32int avgfilesize;
|
|
|
|
u32int avgfpdir;
|
2005-08-11 16:45:39 +00:00
|
|
|
/* u32int sparecon[26], pendingblocks, pendinginodes; in UFS1 */
|
|
|
|
u32int savecgsize;
|
|
|
|
u32int sparecon[26];
|
|
|
|
u32int flags;
|
2005-07-13 03:48:35 +00:00
|
|
|
u32int contigsumsize;
|
|
|
|
u32int maxsymlinklen;
|
2005-08-11 16:45:39 +00:00
|
|
|
u32int _inodefmt; /* format of on-disk inodes */
|
2005-07-13 03:48:35 +00:00
|
|
|
u64int maxfilesize; /* maximum representable file size */
|
|
|
|
u64int qbmask;
|
|
|
|
u64int qfmask;
|
|
|
|
u32int state;
|
2005-08-11 16:45:39 +00:00
|
|
|
u32int _postblformat;
|
|
|
|
u32int _nrpos;
|
|
|
|
u32int _postbloff;
|
|
|
|
u32int _rotbloff;
|
|
|
|
u32int magic; /* FSMAGIC or FSMAGIC2 */
|
2005-07-13 03:48:35 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Cylinder group block for a file system.
|
|
|
|
*/
|
|
|
|
struct Cgblk
|
|
|
|
{
|
|
|
|
u32int unused0;
|
2005-08-11 16:45:39 +00:00
|
|
|
u32int magic; /* CGMAGIC */
|
2005-07-13 03:48:35 +00:00
|
|
|
u32int time; /* time last written */
|
2005-08-11 16:45:39 +00:00
|
|
|
u32int num; /* we are cg #cgnum */
|
2005-07-13 03:48:35 +00:00
|
|
|
u16int ncyl; /* number of cylinders in gp */
|
2005-08-11 16:45:39 +00:00
|
|
|
u16int nino; /* number of inodes */
|
|
|
|
u32int nfrag; /* number of fragments */
|
2005-07-13 03:48:35 +00:00
|
|
|
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 */
|
2005-08-11 16:45:39 +00:00
|
|
|
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;
|
2005-07-13 03:48:35 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* this is the on-disk structure
|
|
|
|
*/
|
2005-08-11 16:45:39 +00:00
|
|
|
struct Inode1
|
2005-07-13 03:48:35 +00:00
|
|
|
{
|
|
|
|
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];
|
|
|
|
};
|
|
|
|
|
2005-08-11 16:45:39 +00:00
|
|
|
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];
|
|
|
|
};
|
|
|
|
|
2005-07-13 03:48:35 +00:00
|
|
|
struct Dirent
|
|
|
|
{
|
|
|
|
u32int ino;
|
|
|
|
u16int reclen;
|
|
|
|
u8int type;
|
|
|
|
u8int namlen;
|
|
|
|
char name[1];
|
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* main file system structure
|
|
|
|
*/
|
|
|
|
struct Ffs
|
|
|
|
{
|
2005-08-11 16:45:39 +00:00
|
|
|
int ufs;
|
2005-07-13 03:48:35 +00:00
|
|
|
int blocksize;
|
2005-08-11 16:45:39 +00:00
|
|
|
u64int nblock;
|
2005-07-13 03:48:35 +00:00
|
|
|
int fragsize;
|
|
|
|
int fragsperblock;
|
|
|
|
int inosperblock;
|
2005-08-11 16:45:39 +00:00
|
|
|
u64int blockspergroup;
|
|
|
|
u64int fragspergroup;
|
2005-07-13 03:48:35 +00:00
|
|
|
int inospergroup;
|
|
|
|
|
2005-08-11 16:45:39 +00:00
|
|
|
u64int nfrag;
|
|
|
|
u64int ndfrag;
|
2005-07-13 03:48:35 +00:00
|
|
|
|
|
|
|
int ncg;
|
|
|
|
Cylgrp *cg;
|
|
|
|
|
|
|
|
Disk *disk;
|
|
|
|
};
|
|
|
|
|