xref: /plan9/sys/doc/fs/p2 (revision 6aeb1f0c04d990a2469d1ed5385e6b7f18c098d6)
1219b2ee8SDavid du Colombier.SH
2219b2ee8SDavid du ColombierThe server processes
3219b2ee8SDavid du Colombier.PP
4219b2ee8SDavid du ColombierThe main file system algorithm is a set
5219b2ee8SDavid du Colombierof identical processes
6219b2ee8SDavid du Colombiernamed
7219b2ee8SDavid du Colombier.CW srv
8219b2ee8SDavid du Colombierthat honor the
9219b2ee8SDavid du Colombier9P protocol.
10219b2ee8SDavid du ColombierEach file system process waits on
11219b2ee8SDavid du Colombiera message queue for an incoming request.
12219b2ee8SDavid du ColombierThe request contains a 9P message and
13219b2ee8SDavid du Colombierthe address of a reply queue.
14219b2ee8SDavid du ColombierA
15219b2ee8SDavid du Colombier.CW srv
16219b2ee8SDavid du Colombierprocess parses the message,
17219b2ee8SDavid du Colombierperforms pseudo-disk I/O
18219b2ee8SDavid du Colombierto the corresponding file system block device,
19219b2ee8SDavid du Colombierformulates a response,
20219b2ee8SDavid du Colombierand sends the
21219b2ee8SDavid du Colombierresponse back to the reply queue.
22219b2ee8SDavid du Colombier.PP
23219b2ee8SDavid du ColombierThe unit of storage is a
24*6aeb1f0cSDavid du Colombierlogical block
25*6aeb1f0cSDavid du Colombier(not physical sector) of data on a device:
26*6aeb1f0cSDavid du Colombier.Ex
27*6aeb1f0cSDavid du Colombier.TA 0.5i 1i 1.5i 2i 2.5i 3i 3.5i 4i 4.5i 5i 5.5i
28219b2ee8SDavid du Colombier	enum
29219b2ee8SDavid du Colombier	{
30*6aeb1f0cSDavid du Colombier		RBUFSIZE = 8*1024
31219b2ee8SDavid du Colombier	};
32219b2ee8SDavid du Colombier
33*6aeb1f0cSDavid du Colombier	typedef vlong Off;
34219b2ee8SDavid du Colombier	typedef
35219b2ee8SDavid du Colombier	struct
36219b2ee8SDavid du Colombier	{
37219b2ee8SDavid du Colombier		short	pad;
38219b2ee8SDavid du Colombier		short	tag;
39*6aeb1f0cSDavid du Colombier		Off	path;
40219b2ee8SDavid du Colombier	} Tag;
41219b2ee8SDavid du Colombier
42219b2ee8SDavid du Colombier	enum
43219b2ee8SDavid du Colombier	{
44219b2ee8SDavid du Colombier		BUFSIZE = RBUFSIZE - sizeof(Tag)
45219b2ee8SDavid du Colombier	};
46219b2ee8SDavid du Colombier
47219b2ee8SDavid du Colombier	typedef
48219b2ee8SDavid du Colombier	struct
49219b2ee8SDavid du Colombier	{
50219b2ee8SDavid du Colombier		uchar	data[BUFSIZE];
51219b2ee8SDavid du Colombier		Tag	tag;
52219b2ee8SDavid du Colombier	} Block;
53*6aeb1f0cSDavid du Colombier.Ee
54219b2ee8SDavid du ColombierAll devices are idealized as a perfect disk
55219b2ee8SDavid du Colombierof contiguously numbered blocks each of size
56219b2ee8SDavid du Colombier.CW RBUFSIZE .
57219b2ee8SDavid du ColombierEach block has a tag that identifies what type
58219b2ee8SDavid du Colombierof block it is and a unique id of the file or directory
59219b2ee8SDavid du Colombierwhere this block resides.
60219b2ee8SDavid du ColombierThe remaining data in the block depends on
61219b2ee8SDavid du Colombierwhat type of block it is.
62219b2ee8SDavid du Colombier.PP
63219b2ee8SDavid du ColombierThe
64219b2ee8SDavid du Colombier.CW srv
65219b2ee8SDavid du Colombierprocess's main data structure is the directory entry.
66219b2ee8SDavid du ColombierThis is the equivalent of a UNIX i-node and
67219b2ee8SDavid du Colombierdefines the set of block addresses that comprise a file or directory.
68219b2ee8SDavid du ColombierUnlike the i-node,
69219b2ee8SDavid du Colombierthe directory entry also has the name of the
70219b2ee8SDavid du Colombierfile or directory in it:
71*6aeb1f0cSDavid du Colombier.Ex
72219b2ee8SDavid du Colombier	enum
73219b2ee8SDavid du Colombier	{
74*6aeb1f0cSDavid du Colombier		NAMELEN = 56,
75*6aeb1f0cSDavid du Colombier		NDBLOCK = 6,
76*6aeb1f0cSDavid du Colombier		NIBLOCK = 4,
77219b2ee8SDavid du Colombier	};
78*6aeb1f0cSDavid du Colombier.Ee
79*6aeb1f0cSDavid du Colombier.Ex
80219b2ee8SDavid du Colombier	typedef
81219b2ee8SDavid du Colombier	struct
82219b2ee8SDavid du Colombier	{
83219b2ee8SDavid du Colombier		char	name[NAMELEN];
84219b2ee8SDavid du Colombier		short	uid;
85219b2ee8SDavid du Colombier		short	gid;
86219b2ee8SDavid du Colombier		ushort	mode;
87219b2ee8SDavid du Colombier		short	wuid;
88219b2ee8SDavid du Colombier		Qid	qid;
89*6aeb1f0cSDavid du Colombier		Off	size;
90*6aeb1f0cSDavid du Colombier		Off	dblock[NDBLOCK];
91*6aeb1f0cSDavid du Colombier		Off	iblocks[NIBLOCK];
92219b2ee8SDavid du Colombier		long	atime;
93219b2ee8SDavid du Colombier		long	mtime;
94219b2ee8SDavid du Colombier	} Dentry;
95*6aeb1f0cSDavid du Colombier.Ee
96219b2ee8SDavid du ColombierEach directory entry holds the file or directory
97219b2ee8SDavid du Colombiername, protection mode, access times, user-id, group-id, and addressing
98219b2ee8SDavid du Colombierinformation.
99219b2ee8SDavid du ColombierThe entry
100219b2ee8SDavid du Colombier.CW wuid
101219b2ee8SDavid du Colombieris the user-id of the last writer of the file
102219b2ee8SDavid du Colombierand
103219b2ee8SDavid du Colombier.CW size
104219b2ee8SDavid du Colombieris the size of the file in bytes.
105*6aeb1f0cSDavid du ColombierThe addresses of the first 6
106219b2ee8SDavid du Colombierblocks of the file are held in the
107219b2ee8SDavid du Colombier.CW dblock
108219b2ee8SDavid du Colombierarray.
109219b2ee8SDavid du ColombierIf the file is larger than that,
110219b2ee8SDavid du Colombieran indirect block is allocated that holds
111219b2ee8SDavid du Colombierthe next
112*6aeb1f0cSDavid du Colombier.CW BUFSIZE/sizeof(Off)
113*6aeb1f0cSDavid du Colombierblock addresses of the file.
114*6aeb1f0cSDavid du ColombierThe indirect block address is held in
115*6aeb1f0cSDavid du Colombier.CW iblocks[0] .
116219b2ee8SDavid du ColombierIf the file is larger yet,
117219b2ee8SDavid du Colombierthen there is a double indirect block that points
118219b2ee8SDavid du Colombierat indirect blocks.
119219b2ee8SDavid du ColombierThe double indirect address is held in
120*6aeb1f0cSDavid du Colombier.CW iblocks[1]
121219b2ee8SDavid du Colombierand can point at another
122*6aeb1f0cSDavid du Colombier.CW (BUFSIZE/sizeof(Off))\u\s-2\&2\s+2\d
123219b2ee8SDavid du Colombierblocks of data.
124*6aeb1f0cSDavid du ColombierThis is extended through a quadruple indirect block at
125*6aeb1f0cSDavid du Colombier.CW iblocks[3]
126*6aeb1f0cSDavid du Colombierbut the code is now parameterised to permit easily changing the
127*6aeb1f0cSDavid du Colombiernumber of direct blocks and the depth of indirect blocks,
128*6aeb1f0cSDavid du Colombierand also the maximum size of a file name component.
129219b2ee8SDavid du ColombierThe maximum addressable size of a file is
130*6aeb1f0cSDavid du Colombiertherefore 7.93 petabytes at a block size of 8k,
131*6aeb1f0cSDavid du Colombierbut 7.98 exabytes (just under $2 sup 63$ bytes) at a block size of 32k.
132*6aeb1f0cSDavid du ColombierFile size is restricted to $2 sup 63 - 1$ bytes in any case
133*6aeb1f0cSDavid du Colombierbecause the length of a file is maintained in a
134*6aeb1f0cSDavid du Colombier(signed)
135*6aeb1f0cSDavid du Colombier.I vlong .
136*6aeb1f0cSDavid du ColombierThese numbers are based on
137*6aeb1f0cSDavid du Colombier.I fs64
138*6aeb1f0cSDavid du Colombierwhich has a block size of 8k and
139*6aeb1f0cSDavid du Colombier.CW sizeof(Off)
140*6aeb1f0cSDavid du Colombieris 8.
141219b2ee8SDavid du Colombier.PP
142219b2ee8SDavid du ColombierThe declarations of the indirect and double indirect blocks
143219b2ee8SDavid du Colombierare as follows.
144*6aeb1f0cSDavid du Colombier.Ex
145219b2ee8SDavid du Colombier	enum
146219b2ee8SDavid du Colombier	{
147*6aeb1f0cSDavid du Colombier		INDPERBUF = BUFSIZE/sizeof(Off),
148219b2ee8SDavid du Colombier	};
149*6aeb1f0cSDavid du Colombier.Ee
150*6aeb1f0cSDavid du Colombier.Ex
151219b2ee8SDavid du Colombier	typedef
152219b2ee8SDavid du Colombier	{
153*6aeb1f0cSDavid du Colombier		Off	dblock[INDPERBUF];
154219b2ee8SDavid du Colombier		Tag	ibtag;
155219b2ee8SDavid du Colombier	} Iblock;
156*6aeb1f0cSDavid du Colombier.Ee
157*6aeb1f0cSDavid du Colombier.Ex
158219b2ee8SDavid du Colombier	typedef
159219b2ee8SDavid du Colombier	{
160*6aeb1f0cSDavid du Colombier		Off	iblock[INDPERBUF];
161219b2ee8SDavid du Colombier		Tag	dibtag;
162219b2ee8SDavid du Colombier	} Diblock;
163*6aeb1f0cSDavid du Colombier.Ee
164219b2ee8SDavid du Colombier.PP
165219b2ee8SDavid du ColombierThe root of a file system is a single directory entry
166219b2ee8SDavid du Colombierat a known block address.
167219b2ee8SDavid du ColombierA directory is a file that consists of a list of
168219b2ee8SDavid du Colombierdirectory entries.
169219b2ee8SDavid du ColombierTo make access easier,
170219b2ee8SDavid du Colombiera directory entry cannot cross blocks.
171*6aeb1f0cSDavid du ColombierIn
172*6aeb1f0cSDavid du Colombier.I fs64
173*6aeb1f0cSDavid du Colombierthere are 47 directory entries per block.
174219b2ee8SDavid du Colombier.PP
175219b2ee8SDavid du ColombierThe device on which the blocks reside is implicit
176219b2ee8SDavid du Colombierand ultimately comes from the 9P
177219b2ee8SDavid du Colombier.CW attach
178219b2ee8SDavid du Colombiermessage that specifies the name of the
179219b2ee8SDavid du Colombierdevice containing the root.
180