code: mafs

Download patch

ref: ae0459c6e838ef75cba4b3ee59921896fb618ca0
parent: 47d0983b3531256bf4c1a7dd469860a57fc213a0
author: 9ferno <gophone2015@gmail.com>
date: Fri Oct 21 02:31:49 EDT 2022

update documentation to reflect the current data structures

--- a/docs/mafs.ms
+++ b/docs/mafs.ms
@@ -15,10 +15,11 @@
 .\" Introduction
 .\" .ft R
 .sp
-Mafs wants you to be able to understand it, so you can be self-sufficient and fix a crash at two in the morning or satisfy your desire for speed or a feature. This empowerment is priceless as software literacy rises.
+Mafs wants you to be able to understand it, so you can be self-sufficient and fix a crash at two in the morning or satisfy your desire for speed or a feature. This empowerment is priceless as software literacy rises and leaner teams dominate.
 .sp
 Mafs is a user space file system to provide system stability and security. It is based on kfs.
 .sp
+As a goal of this document is to build up technical expertise, it gratuitously uses the actual commands and C data structure definitions to convey information.
 .sp
 .ft B
 Workflow
@@ -44,17 +45,22 @@
 	{ "Directory" "File" at Abstractions.s }
 	move 0.75*boxwid
 	Datastructures: box invis "Data Structures"
-	{ "Dentry" "Span" at Datastructures.s }
+	{ "Dentry" at Datastructures.s }
 	Buffercache: box invis "Buffer cache" "used blocks" with .sw at Datastructures.ne + 0.5i,0
 	Extents: box invis "Extents" "free blocks" with .nw at Datastructures.se + 0.5i,0
 	move 0.5*boxwid
-	Disk: box "Disk" "blocks" height 2*boxht with .nw at Buffercache.e + 0.4i,0
+	Writer: box invis "writer" with .nw at Buffercache.ne + 0.4i,0
+	down
+	move 0.5*boxwid
+	Disk: box "Disk" "blocks" height 1.5*boxht with .sw at Extents.se + 0.4i,0
 }
 	line <-> from Multiple.e to Abstractions.w - 0.1i,0
 	line <-> from Abstractions.e + 0.1i,0 to Datastructures.w - 0.2i,0
 	line <-> from Datastructures.e + 0,0.1i to Buffercache.w - 0.1i,0
 	line <-> from Datastructures.e - 0,0.1i to Extents.w
-	line <-> from Buffercache.e + 0.1i,0 to Disk.w
+	line <- from Buffercache.se + 0.1i,0 to Disk.w
+	line -> from Buffercache.e + 0.1i,0 to Writer.w
+	line -> from Writer.s + 0,0.1i to Disk.n
 	line <-> from Extents.e to Disk.w
 	line <-> from Buffercache.s to Extents.n
 .PE
@@ -66,12 +72,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 512 byte logical blocks. For optimum throughput, file data blocks are logically grouped into Spans.
+The unit of storage is a logical block (not physical sector) of data. Disk space is split into 512 byte logical blocks.
 .sp
-A Tag identifies a Span written to the disk. A continuous space of Tag.len blocks makes up each Span. To efficiently manage system memory across numerous users and files, the size of each Span is constrained.
-.sp
 .ne 14
-A sample disk of 2048 bytes with 4 blocks and 2 Spans
+A sample disk of 2048 bytes with 4 blocks.
 .PS
 right
 {
@@ -100,27 +104,6 @@
 	"2  " at Block2.w rjust
 	"3  " at Block3.w rjust
 }
-move; move; move; move
-{
-	down;
-	{
-		Block0: box dashed "Tag.len 2";
-		Block1: box dashed; {line from Block1.sw to Block1.se;}
-		Block2: box dashed "Tag.len 1"; {line from Block2.sw to Block2.se;}
-		Block3: box dashed;
-	}
-	box height 4*boxht;
-	move 0.2i;
-	"disk of" " 2048 bytes"
-	"Block  " at Block0.nw rjust
-	"0  " at Block0.w rjust
-	"1  " at Block1.w rjust
-	"2  " at Block2.w rjust
-	"3  " at Block3.w rjust
-	" Span" at Block0.ne ljust
-	"  0" at Block0.se ljust
-	"  1" at Block2.e ljust
-}
 .PE
 .ne 20
 .sp
@@ -136,7 +119,9 @@
 	Tind0,		/* list of Tdata Spans for files or Tdentry Spans for directories.*/
 	Tind1,		/* list of Tind0 blocks */
 	Tind2,		/* list of Tind1 blocks */
-	Tind3,		/* list of Tind2 blocks. we can have a 11 TB file */
+	Tind3,		/* list of Tind2 blocks */
+	Tind4,		/* list of Tind3 blocks */
+	Tind5,		/* list of Tind4 blocks */
 };
 .sp
 A Span is stored to the disk with a Tag.
@@ -148,11 +133,10 @@
 	u8 dirty;	/* is 1, when being written to.
 				Identifies dirty data on a crash.
 				This byte position is denoted by the enum Nthdirty. */
-	u16 len;	/* number of blocks in this Span */
 };
 .fi
 .sp
-Every file or directory is represented on the disk by a directory entry (Dentry). Every directory entry uses a 1-block Span (Tag.type = Tdentry) and is uniquely identifiable by a Qid.
+Every file or directory is represented on the disk by a directory entry (Dentry). Every directory entry uses a block (Tag.type = Tdentry) and is uniquely identifiable by a Qid.
 .sp
 Mafs does not store the last access time of a file or directory.
 .sp
@@ -160,8 +144,8 @@
 .nf
 enum {
 	Rawblocksize= 512,	/* real block size */
-	Ndspanid	= 24,	/* number of direct Span identifiers in a Dentry */
-	Niblock	= 4,		/* max depth of indirect blocks */
+	Ndblock		= 32,	/* number of direct blocks in a Dentry */
+	Niblock		= 6,	/* max depth of indirect blocks */
 };
 struct Qid9p1
 {
@@ -168,11 +152,6 @@
 	u32 version;
 	u64 path;		/* unique identifier */
 };
-struct Spanid		/* Span identifier */
-{
-	u64 blkno;	/* starting block number */
-	u16 len;		/* number of blocks */
-};
 struct Dentry1
 {
 	Qid9p1	qid;
@@ -184,7 +163,7 @@
 	s16 uid;
 	s16 gid;
 	s16 muid;
-	Spanid dspans[Ndspanid];/* direct Span identifiers */
+	u64 dblocks[Ndblock];	/* direct blocks */
 						/* Tag.type = Tdentry for directories and Tdata for files */
 	u64 iblocks[Niblock];	/* indirect blocks */
 };
@@ -193,17 +172,13 @@
  * derived constants
  * Ndentriesperblock: number of Dentry's per block
  * Nindperblock: number of block pointers per block
- * Nspanidperblock: number of Span identifiers per a Tind0 block
  */
 enum {
 	Blocksize	= Rawblocksize - sizeof(Tag),
 	Namelen	= (Blocksize-sizeof(Dentry1)),		/* max size of file name components */
-	Maxspanlen	= MB/Rawblocksize,			/* in blocks */
-	Maxspansize	= (Maxspanlen*Rawblocksize)-sizeof(Tag), /* in bytes */
 
 	Ndentryperblock	= 1, 					/* Blocksize / sizeof(Dentry), */
 	Nindperblock	= Blocksize / sizeof(u64),
-	Nspanidperblock	= Blocksize / sizeof(Spanid),
 };
 struct Dentry
 {
@@ -210,7 +185,37 @@
 	struct Dentry1;
 	char name[Namelen];
 };
+.sp
+: mafs ; tests/6.sizes # shows the values of the above derived variables.
+Namelen 144 Ndblock 32 Niblock 6
+Blocksize 502 Nindperblock 62
+A Tind0 unit points to 1 data blocks (502 bytes)
+		block points to 62 data blocks
+		reli start 32	max 93
+		max size 94*Blocksize = 47188 bytes
+A Tind1 unit points to 62 data blocks (31124 bytes)
+		block points to 3844 data blocks
+		reli start 94	max 3937
+		max size 3938*Blocksize = 1976876 bytes	= 1 MiB
+A Tind2 unit points to 3844 data blocks (1929688 bytes)
+		block points to 238328 data blocks
+		reli start 3938	max 242265
+		max size 242266*Blocksize = 121617532 bytes	= 115 MiB
+A Tind3 unit points to 238328 data blocks (119640656 bytes)
+		block points to 14776336 data blocks
+		reli start 242266	max 15018601
+		max size 15018602*Blocksize = 7539338204 bytes	= 7 GiB
+A Tind4 unit points to 14776336 data blocks (7417720672 bytes)
+		block points to 916132832 data blocks
+		reli start 15018602	max 931151433
+		max size 931151434*Blocksize = 467438019868 bytes	= 435 GiB
+A Tind5 unit points to 916132832 data blocks (459898681664 bytes)
+		block points to 56800235584 data blocks
+		reli start 931151434	max 57731387017
+		max size 57731387018*Blocksize = 28981156283036 bytes	= 26 TiB
 .fi
+.sp
+reli is the relative index within a directory entry. A zero reli is first data block in the directory entry and a reli of 1 is the second data block of the directory entry.
 .PS
 right
 bigboxht = boxht
@@ -518,7 +523,7 @@
 }
 .PE
 .sp
-kfs and cwfs do not use Spans. They use blocks but with a size of 8192 bytes to avoid dealing with small data blocks (less system calls, context switches, etc). 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. Instead, we use variable length Span's for Tdata. All other types of data use 1 block Span's. This makes us use bigger sized content for data blocks (lesser system calls, context switches, etc.).
+kfs and cwfs use blocks but with a size of 8192 bytes. 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.
 .sp
 iblocks[0] contains the block number of a Tind0 Span(1 block). A Tind0 Span is a list of Span identifiers with the block numbers of Tdata Span's for files and Tdentry Span's for directories.
 .sp
binary files a/docs/mafs.pdf b/docs/mafs.pdf differ
--- a/tests/sizes.c
+++ b/tests/sizes.c
@@ -23,7 +23,9 @@
 		print("		max size %llud*Blocksize = %llud bytes",
 				maxblocks(t),
 				maxblocks(t)*Blocksize);
-		if(maxblocks(t)*Blocksize/(GiB) > 0)
+		if(maxblocks(t)*Blocksize/(TiB) > 0)
+			print("	= %llud TiB\n",maxblocks(t)*Blocksize/(TiB));
+		else if(maxblocks(t)*Blocksize/(GiB) > 0)
 			print("	= %llud GiB\n",maxblocks(t)*Blocksize/(GiB));
 		else if(maxblocks(t)*Blocksize/(MiB) > 0)
 			print("	= %llud MiB\n",maxblocks(t)*Blocksize/(MiB));