344 lines · 7.1 KB · C
RawDownload
/* * 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;};