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