code: mafs

Download patch

ref: 5c6b2660e2f1705b0fc9217d1ae105a96ff223bd
parent: 9976d0283cfac6c187e061a0f827026fddb18ef5
author: 9ferno <gophone2015@gmail.com>
date: Sun Dec 25 03:54:31 EST 2022

updating documentation

--- a/docs/mafs.ms
+++ b/docs/mafs.ms
@@ -67,8 +67,10 @@
 .sp
 Mafs organizes and saves content on a disk as directories and files, just like any other filesystem.
 .sp
-The unit of storage is a logical block (not physical sector) of data. Disk space is split into blocks of 512 bytes. A directory entry uses 2 blocks (1KiB) and a data block could use upto 2048 blocks (1MiB).
+The unit of storage is a logical block (not physical sector) of data. Disk space is split into blocks of 512 bytes. A directory entry uses a block and a data block could use upto 2048 blocks (1MiB).
 .sp
+Keeping the directory entries to a block reduces "snowdust" due to the "best fit" algorithm used for assigning disk blocks and memory.
+.sp
 .ne 14
 A sample disk of 2048 bytes with 4 blocks.
 .PS
@@ -127,7 +129,7 @@
 };
 .fi
 .sp
-Every file or directory is represented on the disk by a directory entry (Dentry). A directory entry uses a unit sized block (tag = Tdentry) and is uniquely identifiable by a Qid.
+Every file or directory is represented on the disk by a directory entry (Dentry). A directory entry uses a  block (tag = Tdentry) and is uniquely identifiable by a Qid.
 .sp
 A file's contents are stored in the directory entry itself if they are 320 bytes or lesser. A file stores its contents in blocks with a tag of Tdata if the file size is more than that. A directory holds the directory entries of it's children in blocks each with a tag of Tdentry.
 .sp
@@ -142,36 +144,34 @@
 .sp
 A directory entry is defined as:
 .nf
-enum {	Blocksize	= 512ULL,	/* minimum data unit size */
+enum {
+	Blocksize	= 512ULL,	/* minimum data unit size */
 
-	Metadataunits	= 2,
-	Metadatablocksize = Metadataunits*Blocksize, /* Keep the original and a copy together */
-
 	Maxdatablockunits = 2048,
 	Nindperblock= (Blocksize-3*sizeof(u64))/sizeof(u64),/* number of pointers per block */
 	Nu64perblock= (Blocksize/sizeof(u64)),		/* number of u64's in a block */
-	Dpathidx	= (Blocksize/sizeof(u64) -1),		/* index of path in the last data block, last u64 */
+	Dpathidx	= (Blocksize/sizeof(u64) -1),	/* index of path in the last data block, last u64 */
 
-	Namelen = 127,	/* maximum length of a file name, calculated manually */
+	Namelen = 128,	/* maximum length of a file name, calculated manually */
 	Ndblock	= 32,	/* number of direct blocks in a Dentry */
-	Niblock	= 5,		/* maximum depth of indirect blocks, can increase it to 8 without issues */
+	Niblock	= 5,	/* maximum depth of indirect blocks, can increase it to 8 without issues */
 };
 struct Dentryhdr
 {
+
 	u8 tag;
-	u8 verd;
+	u8 namelen;
 	s16 uid;
 	s16 gid;
 	s16 muid;		/* 8 */
 	u64 size;		/* 0 for directories. For files, size in bytes of the content - 16 */
 	u64 pdblkno; 	/* block number of the parent directory entry. Will be 0 for root. - 24 */
-	u64 pqpath; 	/* parent path - 32 */
-	u64 mtime;	/* modified time in nano seconds from epoch - 40 */
-	u64 qpath;	/* unique identifier Qid.path 48 */
+	u64 pqpath; 	/* parent qid.path - 32 */
+	u64 mtime;		/* modified time in nano seconds from epoch - 40 */
+	u64 qpath;		/* unique identifier Qid.path 48 */
 	u32 version;	/* Qid.version 52 */
-	u32 mode;	/* same bits as defined in /sys/include/libc.h:/Dir\.mode/ - 56 */
-	u8 namelen;	/* store name as a counted string 57 */
-	s8 name[Namelen]; /* Namelen = 127 - 184*/
+	u32 mode;		/* same bits as defined in /sys/include/libc.h:/Dir\.mode/ - 56 */
+	s8 name[Namelen]; /* Namelen = 128 - 184*/
 };
 struct Datahdr
 {
@@ -183,12 +183,17 @@
 
 enum {
 	/* size of identifiers used in a Tdata block */
-	Ddataidssize = sizeof(Dentryhdr) -sizeof(u64 /* trailing path */),
+	Ddataidssize = sizeof(Datahdr) +sizeof(u64 /* trailing path */),
 	/* max possible size of data that can be stuffed into a Dentry */
-	Ddatasize = Blocksize -Ddataidssize,
+	Ddatasize = Blocksize -sizeof(Dentryhdr) -sizeof(u64 /* trailing path */),
 	Maxdatablocksize = Maxdatablockunits*Blocksize -Ddataidssize,
 };
 
+struct Super
+{
+	u64 qidgen;	/* generator for unique ids. starts from 1024. */
+	u64 fsok;	/* fsck status, using 64 bits to keep it all aligned */
+};
 struct Dentry
 {
 	Dentryhdr;
@@ -197,8 +202,8 @@
 		struct
 		{
 			u64 dblocks[Ndblock];	/* direct blocks. */
-								/* List of Tdata block numbers for files and
-									Tdentry block numbers for directories */
+									/* List of Tdata block numbers for files and
+										Tdentry block numbers for directories */
 			u64 iblocks[Niblock];	/* indirect blocks */
 		};
 		Super;
@@ -210,34 +215,17 @@
 };
 struct Indirect
 {
-	u8 tagi;		/* the suffix i to avoid union complaining about ambiguous fields */
-	u8 veri;
-	u8 pad[6];		/* unused, to align to a multiple of 8 */
+	u8 tagi;	/* the suffix i to avoid union complaining about ambiguous fields */
+	u8 pad[7];	/* unused, to align to a multiple of 8 */
 	u64 dblkno;	/* block number of the directory entry */
 	u64 bufa[Nindperblock];
-	u64 path;		/* same as qid.path */
+	u64 pathi;	/* same as qid.path */
 };
-struct Metadataunit
-{
-	union
-	{
-		Indirect;
-		Dentry;
-	};
-};
-struct Metadata
-{
-	union
-	{
-		Indirect i[2];
-		Dentry d[2];
-	};
-};
 struct Data		/* used to unmarshall the disk contents */
 {
 	Datahdr;
-	u8 buf[1];	/* upto Maxdatablocksize, followed by u64 path */
-	/* u64 path; same as path at the end of the data content */
+	u8 buf[1];	/* upto Maxdatablocksize, followed by u64 qid.path */
+	/* u64 path; same as qid.path at the end of the data content - check consistency */
 };
 .fi
 .sp
@@ -249,11 +237,11 @@
 .sp
 .nf
 	; tests/6.sizes
-	Blocksize 512 Metadataunits 2 Maxdatablockunits 2048
+	Blocksize 512 Maxdatablockunits 2048
 	Dentryhdr size 184 Ddatasize 320
-	Dentry size 512 Namelen 127
+	Dentry size 512 Namelen 128
 	Datahdr size 12 Ddataidssize 20 Maxdatablocksize 1048556
-	Namelen 127 Ndblock 32 Niblock 5
+	Namelen 128 Ndblock 32 Niblock 5
 	Nindperblock 61 Maxdatablocksize 1048556
 	A Tind0 unit points to 1 data blocks (1048556 bytes)
 			block points to 61 data blocks
@@ -292,20 +280,20 @@
 	down
 	{ Bound: box height 9*bigboxht width 3.3*boxwid }
 	move 0.1i
-	box height fieldht invis "Tdentry 64 2"
+	box height fieldht invis "Tdentry qid.path 64"
 	box height fieldht invis "name dir1"
-	box height fieldht invis "version 0"
-	box height fieldht invis "path 64"
-	box height fieldht invis "size 0"
-	box height fieldht invis "pdblkno 20"
-	box height fieldht invis "pqpath 20"
-	box height fieldht invis "mtime 1653302180819962729"
-	box height fieldht invis "mode 20000000777"
 	box height fieldht invis "uid 10006"
 	box height fieldht invis "gid -1"
 	box height fieldht invis "muid 10006"
+	box height fieldht invis "size 0"
+	box height fieldht invis "pdblkno 10"
+	box height fieldht invis "pqpath 10"
+	box height fieldht invis "mtime 1653302180819962729"
+	box height fieldht invis "path 64"
+	box height fieldht invis "version 0"
+	box height fieldht invis "mode 20000000777"
 	box height fieldht invis "direct blocks"
-	box height fieldht invis "        0 24"
+	box height fieldht invis "        0 12"
 	box height fieldht invis "        1 0"
 	box height fieldht invis "        2 0"
 	box height fieldht invis "."
@@ -317,7 +305,7 @@
 	box height fieldht invis "        0 0"
 	box height fieldht invis "        1 0"
 	box height fieldht invis "        2 0"
-	"Block 22 contents: /dir1 Dentry" at Bound.nw + 0,0.1i ljust
+	"Block 11 contents: /dir1 Dentry" at Bound.nw + 0,0.1i ljust
 	"Representation of a file in a directory: /dir1/file1" ljust at Bound.n + 0,0.3i
 }
 move 4*boxwid
@@ -325,40 +313,20 @@
 	down
 	{ Bound: box height 5*bigboxht width 3.3*boxwid }
 	move 0.1i
-	box height fieldht invis "Tdentry 65 2"
+	box height fieldht invis "Tdentry qid.path 65"
 	box height fieldht invis "name file1"
-	box height fieldht invis ",version 0"
-	box height fieldht invis "path 65"
-	box height fieldht invis "size 5"
-	box height fieldht invis "pdblkno "
-	box height fieldht invis "pqpath 64"
-	box height fieldht invis "mtime 1653302180823455071"
-	box height fieldht invis "mode 666"
 	box height fieldht invis "uid 10006"
 	box height fieldht invis "gid -1"
 	box height fieldht invis "muid 10006"
-	"Block 24 contents: file1 Dentry" at Bound.nw + 0,0.1i ljust
-}
-down
-move 9*bigboxht
-{
-	down
-	{ Bound: box height 5*bigboxht width 3.3*boxwid }
-	move 0.1i
-	box height fieldht invis "Tdentry 65 3"
-	box height fieldht invis "name file1"
-	box height fieldht invis "version 0"
-	box height fieldht invis "path 65"
 	box height fieldht invis "size 5"
-	box height fieldht invis "pdblkno "
+	box height fieldht invis "pdblkno 11"
 	box height fieldht invis "pqpath 64"
 	box height fieldht invis "mtime 1653302180823455071"
+	box height fieldht invis "path 65"
+	box height fieldht invis "version 0"
 	box height fieldht invis "mode 666"
-	box height fieldht invis "uid 10006"
-	box height fieldht invis "gid -1"
-	box height fieldht invis "muid 10006"
 	box height fieldht invis "test"
-	"Block 25 contents: file1 Dentry" at Bound.nw + 0,0.1i ljust
+	"Block 12 contents: file1 Dentry" at Bound.nw + 0,0.1i ljust
 }
 .PE
 .sp
@@ -368,21 +336,21 @@
 	down
 	{ Bound: box height 8.5*bigboxht width 3.3*boxwid }
 	move 0.1i
-	box height fieldht invis "Tdentry 66 3"
+	box height fieldht invis "Tdentry qid.path 66"
 	box height fieldht invis "name dir2"
-	box height fieldht invis "version 0"
-	box height fieldht invis "path 66"
-	box height fieldht invis "size 0"
-	box height fieldht invis "pdblkno 20"
-	box height fieldht invis "pqpath 20"
-	box height fieldht invis "mtime 1653302180819962729"
-	box height fieldht invis "mode 20000000777"
 	box height fieldht invis "uid 10006"
 	box height fieldht invis "gid -1"
 	box height fieldht invis "muid 10006"
+	box height fieldht invis "size 0"
+	box height fieldht invis "pdblkno 10"
+	box height fieldht invis "pqpath 10"
+	box height fieldht invis "mtime 1653302180819962729"
+	box height fieldht invis "path 66"
+	box height fieldht invis "version 0"
+	box height fieldht invis "mode 20000000777"
 	box height fieldht invis "direct blocks"
-	box height fieldht invis "        0 28"
-	box height fieldht invis "        1 30"
+	box height fieldht invis "        0 14"
+	box height fieldht invis "        1 15"
 	box height fieldht invis "."
 	box height fieldht invis "."
 	box height fieldht invis "."
@@ -391,7 +359,7 @@
 	box height fieldht invis "        0 0"
 	box height fieldht invis "        1 0"
 	box height fieldht invis "        2 0"
-	"Block 27 contents: /dir2 directory entry" at Bound.nw + 0,0.1i ljust
+	"Block 13 contents: /dir2 directory entry" at Bound.nw + 0,0.1i ljust
 	"Representation of two files in a directory (/dir2/file1 and /dir2/file2)" ljust at Bound.nw + 0.2,0.3i
 }
 move 4*boxwid
@@ -399,41 +367,20 @@
 	down
 	{ Bound: box height 8.5*bigboxht width 3.3*boxwid }
 	move 0.1i
-	box height fieldht invis "Tdentry 67 3"
+	box height fieldht invis "Tdentry qid.path 67"
 	box height fieldht invis "name file1"
-	box height fieldht invis "version 0"
-	box height fieldht invis "path 67"
-	box height fieldht invis "size 5"
-	box height fieldht invis "pdblkno 26"
-	box height fieldht invis "pqpath 66"
-	box height fieldht invis "mtime 1653302180823455071"
-	box height fieldht invis "mode 666"
 	box height fieldht invis "uid 10006"
 	box height fieldht invis "gid -1"
 	box height fieldht invis "muid 10006"
-	box height fieldht invis "test"
-	"Block 29 contents: file1 directory entry" at Bound.nw + 0,0.1i ljust
-}
-down
-move 9*bigboxht
-{
-	down
-	{ Bound: box height 8.5*bigboxht width 3.3*boxwid }
-	move 0.1i
-	box height fieldht invis "Tdentry 68 3"
-	box height fieldht invis "name file2"
-	box height fieldht invis "version 0"
-	box height fieldht invis "path 68"
 	box height fieldht invis "size 5"
-	box height fieldht invis "pdblkno 26"
+	box height fieldht invis "pdblkno 13"
 	box height fieldht invis "pqpath 66"
 	box height fieldht invis "mtime 1653302180823455071"
+	box height fieldht invis "path 67"
+	box height fieldht invis "version 0"
 	box height fieldht invis "mode 666"
-	box height fieldht invis "uid 10006"
-	box height fieldht invis "gid -1"
-	box height fieldht invis "muid 10006"
 	box height fieldht invis "test"
-	"Block 31 contents: file2 directory entry" at Bound.nw + 0,0.1i ljust
+	"Block 14 contents: file1 directory entry" at Bound.nw + 0,0.1i ljust
 }
 .PE
 .sp
@@ -482,21 +429,21 @@
 	down
 	{ Bound: box height 8.5*bigboxht width 3.3*boxwid }
 	move 0.1i
-	box height fieldht invis "Tdentry 70 5"
+	box height fieldht invis "Tdentry qid.path 70"
 	box height fieldht invis "name 2MB.file"
-	box height fieldht invis "version 0"
-	box height fieldht invis "path 70"
-	box height fieldht invis "size 2056192"
-	box height fieldht invis "pdblkno 32"
-	box height fieldht invis "pqpath 69"
-	box height fieldht invis "mtime 1653302180819962729"
-	box height fieldht invis "mode 20000000777"
 	box height fieldht invis "uid 10006"
 	box height fieldht invis "gid -1"
 	box height fieldht invis "muid 10006"
+	box height fieldht invis "size 2056192"
+	box height fieldht invis "pdblkno 16"
+	box height fieldht invis "pqpath 69"
+	box height fieldht invis "mtime 1653302180819962729"
+	box height fieldht invis "path 70"
+	box height fieldht invis "version 0"
+	box height fieldht invis "mode 664"
 	box height fieldht invis "direct blocks"
-	box height fieldht invis "        0 36"
-	box height fieldht invis "        1 2084"
+	box height fieldht invis "        0 18"
+	box height fieldht invis "        1 2066"
 	box height fieldht invis "        2 0"
 	box height fieldht invis "."
 	box height fieldht invis "."
@@ -504,7 +451,7 @@
 	box height fieldht invis "       0 0"
 	box height fieldht invis "       1 0"
 	box height fieldht invis "       2 0"
-	"Block 34 contents" at Bound.nw + 0,0.1i ljust
+	"Block 17 contents" at Bound.nw + 0,0.1i ljust
 	"Representation of a 2 MiB file (/dir3/2MB.file)" ljust at Bound.n + 0,0.3i
 }
 move 4*boxwid
@@ -512,9 +459,9 @@
 	down
 	{ Bound: box height 6*bigboxht width 3.3*boxwid }
 	move 0.1i
-	box height fieldht invis "Tdata 70 34 2048"
+	box height fieldht invis "Tdata qid.path 70 dblkno 17 len 2048"
 	box height fieldht invis "0 0123456789"; {"contents of 2MB.file" at last box.e + 1i,0 ljust}
-	"Block 36 contents" at Bound.nw + 0,0.1i ljust
+	"Block 18 contents" at Bound.nw + 0,0.1i ljust
 }
 .PE
 \" from test.a
@@ -524,31 +471,31 @@
 	down
 	{ Bound: box height 9*bigboxht width 3.3*boxwid }
 	move 0.1i
-	box height fieldht invis "Tdentry 64 106"
+	box height fieldht invis "Tdentry qid.path 64"
 	box height fieldht invis "name big.file"
-	box height fieldht invis "version 0"
-	box height fieldht invis "path 64"
-	box height fieldht invis "size 26214400"
-	box height fieldht invis "pdblkno 20"
-	box height fieldht invis "pqpath 20"
-	box height fieldht invis "mtime 1653302180819962729"
-	box height fieldht invis "mode 664"
 	box height fieldht invis "uid 10006"
 	box height fieldht invis "gid -1"
 	box height fieldht invis "muid 10006"
+	box height fieldht invis "size 26214400"
+	box height fieldht invis "pdblkno 10"
+	box height fieldht invis "pqpath 10"
+	box height fieldht invis "mtime 1653302180819962729"
+	box height fieldht invis "path 64"
+	box height fieldht invis "version 0"
+	box height fieldht invis "mode 666"
 	box height fieldht invis "direct blocks"
-	box height fieldht invis "       0 24"
-	box height fieldht invis "       1 2072"
-	box height fieldht invis "       2 4120"
+	box height fieldht invis "       0 12"
+	box height fieldht invis "       1 2060"
+	box height fieldht invis "       2 4108"
 	box height fieldht invis "."
 	box height fieldht invis "."
-	box height fieldht invis "       31 63512"
+	box height fieldht invis "       31 63500"
 	box height fieldht invis "indirect blocks"
-	box height fieldht invis "       0 67608"
-	box height fieldht invis "       1 192538"
+	box height fieldht invis "       0 67596"
+	box height fieldht invis "       1 192525"
 	box height fieldht invis "       2 0"
-	"Block 22 contents" at Bound.nw + 0,0.1i ljust
-	"Representation of a 100 MiB file (/big.file)" ljust at Bound.n + 0,0.3i
+	"Block 11 contents" at Bound.nw + 0,0.1i ljust
+	"Representation of a 106490448 bytes file (/big.file)" ljust at Bound.n + 0,0.3i
 }
 move 4*boxwid
 {
@@ -555,12 +502,12 @@
 	down
 	{ Bound: box height 4*bigboxht width 3.3*boxwid }
 	move 0.1i
-	box height fieldht invis "Tdata 64 22 2048"
+	box height fieldht invis "Tdata qid.path 64 dblkno 11 len 2048"
 	box height fieldht invis "0 0123456789"; {"starting contents" at last box.e + 1i,0 ljust;}
 	box height fieldht invis "."; {"of big.file" at last box.e + 1i,0 ljust}
 	box height fieldht invis "."
 	box height fieldht invis "."
-	"Block 24 contents" at Bound.nw + 0,0.1i ljust
+	"Block 12 contents" at Bound.nw + 0,0.1i ljust
 }
 move to Start - 0,9.5*bigboxht
 {
@@ -567,13 +514,13 @@
 	down
 	{ Bound: box height 3*bigboxht width 3.3*boxwid }
 	move 0.1i
-	box height fieldht invis "Tind0 64 60 22"
-	box height fieldht invis "	0 65560"
-	box height fieldht invis "	1 67610"
-	box height fieldht invis "	2 69658"
+	box height fieldht invis "Tind0 qid.path 64 dblkno 11"
+	box height fieldht invis "	0 65548"
+	box height fieldht invis "	1 67597"
+	box height fieldht invis "	2 69645"
 	box height fieldht invis "."
 	box height fieldht invis "."
-	"Block 67608 contents" at Bound.nw + 0,0.1i ljust
+	"Block 67596 contents" at Bound.nw + 0,0.1i ljust
 }
 right
 move 4*boxwid
@@ -581,11 +528,11 @@
 	down
 	{ Bound: box height 3*bigboxht width 3.3*boxwid }
 	move 0.1i
-	box height fieldht invis "Tdata 64 22 2048"
+	box height fieldht invis "Tdata qid.path 64 dblkno 11 len 2048"
 	box height fieldht invis " 0123456789"; {"more content" at last box.e + 1i,0 ljust}
 	box height fieldht invis "."; {"of big.file" at last box.e + 1i,0 ljust}
 	box height fieldht invis "."
-	"Block 65560 contents" at Bound.nw + 0,0.1i ljust
+	"Block 65548 contents" at Bound.nw + 0,0.1i ljust
 }
 .PE
 .sp
@@ -598,19 +545,19 @@
 =
 Block	Description
 0	magic dir entry and data
-2	/adm/config dir entry
-4	/adm/super dir entry
+1	/adm/config dir entry
+2	/adm/super dir entry
 _
-6	/adm/ dir entry
-8	/adm/users/ dir entry
-10	/adm/bkp/ dir entry
+3	/adm/ dir entry
+4	/adm/users/ dir entry
+5	/adm/bkp/ dir entry
 _
-12	/adm/users/inuse dir entry
-14	/adm/frees dir entry
-16	/adm/ctl dir entry -- virtual file, empty contents
+6	/adm/users/inuse dir entry
+7	/adm/frees dir entry
+8	/adm/ctl dir entry -- virtual file, empty contents
 _
-18	/adm/users/staging dir entry
-20	/ direntry
+9	/adm/users/staging dir entry
+10	/ direntry
 _
 .TE
 .ta 5n 10n 15n 20n 25n 30n 35n 40n 45n 50n 55n 60n 65n 70n 75n 80n
@@ -633,16 +580,16 @@
 l a a .
 Block	Description	Backup Block
 _
-2	/adm/config	last block number -2
-4	/adm/super	last block number -4
-20	/	last block number -6
+1	/adm/config	last block number -1
+2	/adm/super	last block number -2
+10	/	last block number -3
 .TE
 .ta 5n 10n 15n 20n 25n 30n 35n 40n 45n 50n 55n 60n 65n 70n 75n 80n
 .sp
-Mafs needs atleast Nminblocks=28 blocks (14 KiB).
+Mafs needs atleast Nminblocks=14 blocks (7 KiB).
 .fi
 .sp
-kfs and cwfs use 8192 byte blocks. Hence, they store multiple directory entries (Dentry) per block. They use slot numbers to identify a particular directory entry in a block of directory entries. Mafs avoids that by using 512 byte blocks thus having only one directory entry per block. This avoids locking up other sibling directory entries on access and better throughput for large files but also slows down walk()'s as mafs would be using a read() per directory entry.
+kfs and cwfs use 8192 byte blocks. Hence, they store multiple directory entries (Dentry) per block. They use slot numbers to identify a particular directory entry in a block of directory entries. Mafs avoids that by using 512 byte blocks thus having only one directory entry per block. This avoids locking up other sibling directory entries on access, more compact disk usage and better throughput for large files but also slows down walk()'s as mafs would be using a read() per directory entry.
 .sp
 .sp
 .ne 4
@@ -689,11 +636,11 @@
 	Iobuf *back;	/* for lru */
 	union{
 		u8	*xiobuf;	/* "real" buffer pointer */
+		u64	*xiobuf64;
 		Data *io;
-		Metadata *m;
+		Dentry *d;
+		Indirect *i;
 	};
-	Metadataunit *cur;	/* this has the current Indirect or Dentry values */
-	Metadataunit *new;	/* use this unit for Indirect or Dentry changes */
 
 	u8 *append;		/* appended data added not yet written to disk */
 	u64 appendsize;
@@ -700,6 +647,7 @@
 	u8 freshalloc;	/* uninitialized blocks on the disk */
 	u64 atime;		/* to find old buffers to flush to the disk */
 	u8 tag;
+	u64 callerpc;	/* when locked, the locker pc for debugging */
 };
 .fi
 .sp
@@ -791,17 +739,18 @@
 .nf
 struct Extent {
 	struct Extent *low, *high;	/* sorted by start */
-	u64 start;				/* where this extent starts from */
-	u64 len; 				/* how many units in this extent */
+	struct Extent *small, *big;	/* sorted by the number of blocks in this extent */
+	u64 start;					/* where this extent starts from */
+	u64 len; 					/* how many units in this extent */
 
 	/* circular least recently used linked list limited to Nlru items */
 	struct Extent *prev, *next;
 };
 struct Extents {
-	Extent *head;	/* find the first block in a jiffy */
+	Extent *lowest;	/* find the first block number in a jiffy */
 	QLock lck;
-	u32 n;			/* number of extents */
-	Rendez isempty;	/* fully used, nothing available */
+	u64 n;			/* number of extents */
+	Rendez isempty; /* fully used, nothing available */
 
 	u8 nlru;		/* number of items in the lru linked list */
 	Extent *lru;	/* least recently used extent in the circular lru linked list */
@@ -1081,6 +1030,7 @@
 Program	Description
 _
 disk/mafs	Start mafs on a disk.
+disk/fsck	Check file system on an improper shutdown.
 disk/free	List the free blocks. It reads the contents of /adm/frees.
 disk/used	List the used blocks by traversing all directory entries.
 disk/block	Show the contents of a block.