ðŸ Archived View for kamalatta.ddnss.de ⺠cwfs2.txt captured on 2021-11-30 at 20:18:30.
â¡ïž Next capture (2024-07-08)
-=-=-=-=-=-=-
Logoaddress Study of cwfs table of contents 1.0.0 What is cwfs 2.0.0 cwfs console 2.1.0 Overview 2.2.0 backup of fsworm 3.0.0 Structure of fsworm 3.1.0 Block 3.2.0 dump stack 3.3.0 Super Block 3.4.0 Directory Entry Block 3.5.0 Indirect Block 3.6.0 File Block 3.7.0 Fsworm Root 3.8.0 Dump order 3.9.0 qid 4.0.0 Structure of fscache 4.1.0 Config Block 4.2.0 Tcache Block 4.3.0 Mapping 4.3.1 bucket 4.3.2 cache entry 4.3.3 age 4.3.4 state 4.4.0 free block and dirty block 4.5.0 msize and csize 4.6.0 Map from Worm to Cache 4.7.0 msize determination algorithm 4.8.0 Fscache Root 5.0.0 Recovery 5.1.0 recovery 5.2.0 Review on recovery 5.3.0 What is lost by Recovery 6.0.0 Other Configurations 6.1.0 pseudo-RAID 1 6.2.0 fake WORM 6.2.1 Creating fake WORM 6.3.0 Tvirgo 7.0.0 Misc. 7.1.0 What did I do that day? 7.2.0 atime 7.2.1 Plan 9 7.2.2 Linux 7.2.3 OSX 8.0.0 cwstudy 8.1.0 usage References 2012/10/20 2013/03/14 renewal Updated on March 20, 2013 Updated 2013/04/02 Updated 2013/04/10 2013/04/24 Update For the summer vacation in 2012, I was trying 9front's cwfs. cwfs consists of fscache and fsworm, but we decided to look it up from fsworm. The reason why you are more interested in fsworm is that information such as file history is placed in fsworm and recovery when fscache crashes is done based on fsworm. Of course, any device eventually will die. Backup is necessary for fsworm. It may be possible to put cwfs itself in RAID, but it's too overkill for me. Add another HDD and want to have a copy of fsworm there. So, how can we copy it in a short time? I wanted to elucidate this problem. The cwfs attached to 9front is cwfs64x. Therefore, we will explain it based on cwfs64x. Note: This article is just my memo so far. Of course, it may contain errors. I would be pleased if you let me know if you find an error. What is cwfs This section is incomplete. I will write it in my spare time. Figure 1. layer Sean Quinlan (Ph.D) Ken Thompson (Ken's fs) Plan 9 2nd edition (1995) Geoff Collyer (2007/03/27 mail) 9front (2011) Past History WORM (write once read many) It will not disappear (can not be erased) dump Comparison with Mac / OSX time machine pdumpfs Previously we had one assigned for the server. memory: Memory in the dedicated file server disk: disk cache WORM: Optical disc Currently it runs under Plan 9 user program cwfs Advantages of being a user program: It is easy to check the mechanism. memory: memory in cwfs daemon disk: fscache partition of file server WORM: File server fsworm partition cwfs (or cwfs32) cwfs64 cwfs64x cwfs console Overview The size of my partition on cwfs is as follows. term% ls - l / dev / sdC 0 / fs * - rw - r ---- - S 0 arisawa arisawa 22848146432 Sep 13 09: 50 / dev / sdC 0 / fscache - rw - r ----- S 0 arisawa arisawa 114240734208 Sep 13 09: 50 / dev / sdC 0 / fsworm term% The cwfs console uses commands con -C /srv/cwfs.cmd You will be able to use with. Note: Create one new window cat /srv/cwfs.cmd Run it from another window echo statw >> /srv/cwfs.cmd May be executed. Distribution seems to assume this method. Running statw on the cwfs console will output usage statistics for fsworm. Next, an example of the output is shown. > statw cwstats main filesys main maddr = 3 msize = 10313 caddr = 1035 csize = 1392255 sbaddr = 1755217 craddr = 1755389 1755389 roaddr = 1755392 1755392 fsize = 1755394 1755394 0 + 25% slast = 1754642 snext = 1755393 wmax = 1755392 0 + 25% wsize = 6972701 1 + 0% 8600 none 230005 dirty 0 dump 1153555 read 95 write 0 dump1 cache 17% full > Figure 2. Example of statw output from the cwfs console. The prompt " > " is not issued in the official distribution version. I am trying to go out with a modified version by the author. The numbers on the right of the equal sign ( maddr to wsize ) (the first and second columns) represent the size. The information of the number in the first column is obtained from Tcache block (block address 2) of Tcache . The second column is obtained from fsworm Note 1 . These units are block except for msize . Only msize is a bucket number. Note 1: This part is incorrect. The second row is also obtained from fscache. The cache of the last super block of fsworm is included in fscache and this is displayed. fsize for fsize , the information in the second column matches the information obtained from the last super block. fsize is the value at the time of executing the statw command, which is consistent with fsize obtained from the Tcache block of Tcache . (2013/04/24) Notice that fsworm does not include information on fsworm's partition size. It may be replaced by a larger partition when fsworm is full, so in that case it would be designed to just copy the contents of the full partition to the new partition . Both fscache and fsworm are managed in block units. In the case of cwfs64x, 1 block is 16 KB. Hereinafter, block is represented by an address. ba[0] means the first block, and ba[1] means the second block. wsize 6972701 /dev/sdC0/fsworm the size of /dev/sdC0/fsworm the number of blocks. 6972701 * 16 * 1024 == 114240733184 This is 1024 less than the actual size of /dev/sdC0/fsworm , but since it is being used as a unit, an unusable area has occurred. It should be noted that there is no concept of format in fsworm. Because it is Write Once, after formatting it can not write data! 3 It is written to fsworm in order from the top block. snext (next super block) indicates the next block to be written. When you dump, a block called super block is written first, followed by the body of the data. Super block serves as a boundary for every dump and plays a fundamental role in fsworm. sbaddr (super block address) is the address of the super block written last. Also, slast is the address of the preceding super block. Note 2: The block managed by cwfs is different from the block as the unit of reading / writing managed by the driver. Note 3: WORM in its original meaning will not be used recently. The significance of the existence of an optical disk as a backup medium has disappeared, substituting WORM for a hard task is low cost and easy to use. The following explanation also assumes the use of a hard disk. Backup of fsworm Revised 2013/03/06 Although fsworm is very robust (in its mechanism), it still has the risk of data loss due to hardware crashes. To do the backup you have a copy of fsworm (eg fsworm-bak). For each dump, you might think that you can copy only the newly created block in fsworm, but the story is not that easy. This is because unwritten blocks exist under the last dumped super block. In my observation there are two kinds of them. (a) reserved blockNote 1 (b) free block . (a) is a block of fsworm that is used in fscache, but has not yet completed dump. (b) is a block of fsworm that fscache can use in the future. Note 1: "reserved block" is a term that I am using arbitrarily. This term does not exist in the literature. Structure of fsworm Block Both fscache and fsworm are managed in units of block. In the case of cwfs64x, 1 block is 16 KB. Hereinafter, block is represented by an address. ba[0] means the first block and ba[1] means the second block. Together, the first two blocks are special. The address of block is specified by 8 B data. In the program, the data type is indicated by Off . In the case of fscache, ba[0] contains config information. ba[1] seems not to be used. In the case of fsworm, there is no indication that the first 2 blocks are used. Each block has Tag . However, not all the blocks are formatted. The size of Tag is 12 B in the case of cwfs 64 x, and it is placed at the end of the block. Its structure is as follows. struct Tag { short pad; / * make tag end at a long boundary * / short tag; Off path; }; The value of pad is 0. tag indicates the type of block. path way of thinking about the value of path is different for each tag . The area excluding Tag 12B is a data area (hereinafter referred to as Data) from 16 KB and has a structure for each type of block. To summarize block = Data + Tag . Note 1: Recent HD has large capacity. Formatting all the blocks takes a huge amount of time. In addition, the WORM device can not write if formatted! dump stack 2013/02/28 When dump is repeated, dumped data is stacked on fsworm. Data will never be overwritten. The situation is shown in Fig. 3 (left). Figure 3. dump Hereinafter, the block of block address n is represented by ba[n] . ba[0] and ba[1] are not used. When cwfs is executed, first three blocks ba [2]: super block ba [3]: cfs root block ba [4]: ââdump root block Is made. It does not contain information on files included in fscache. Note: The words "cfs root block" or "dump root block" do not appear in formal documents or program code. "Cfs root address" and "dump root address" appear. Blocks are stacked for each dump. We call the block that is stacked with one dump simply as dump. One dump always includes three blocks, "super block", "cfs root block", "dump root block". Figure 3 (right) shows the internal structure of dump. In the block between super block and cfs root block, the content of fscache is saved (only the difference updated from the previous dump). The block between the cfs root block and the dump root block contains information on the dumped date. The required number of blocks depends on the number of dumps. Super Block The most basic thing to capture the structure of fsworm is super block. The tag of super block is Tsuper (= 1). When we read the code of cwfs, the path the Tag of super block is QPSUPER (= 2). One super block is created when you dump fscache. First, super block is written to fsworm, then the body of the data is written block by block (right in Figure 3). The structure of super block struct Superb { Fbuf fbuf; Super 1; }; have. Fbuf has an array of addresses of free blocks inside. I will postpone commentary on free block. Super1 is important. struct Super 1 { Off fstart; Off fsize; Off tfree; Off qidgen; / * generator for unique ids * / / * * Stuff for WWC device * / Off cwraddr; / * cfs root addr * / Off roraddr; / * dump root addr * / Off last; / * last super block addr * / Off next; / * next super block addr * / }; Figure 4. Structure of Super1 As can be seen, each super block has the address ( next ) of the next super block. And the first super block starts with ba[2] . Therefore, if you follow the super block from ba[2] order, you will know the address to be dumped next. Next, an example of the output result is shown. (This tool will be introduced later) super blocks: 2 Five 69908 85793 104695 222009 ... 1751346 1754278 1754381 1754569 1754642 1755217 1755393 The last 1755393 is the super block address to be made next. The contents of Super1 ba[1755217] are (for example) as follows. super1 fstart: 2 super1 fsize: 1755394 super1 tfree: 92 super1 qidgen: 6d76e super1 cwraddr: 1755389 super1 roraddr: 1755392 super1 last: 1754642 super1 next: 1755393 Some of these information is also obtained from the cwfs console. sbaddr 1755217 : current super block (last written super block) snext 1755393 : The next dump schedule address (that is, the super block address to be created next) slast 1754642 : super block address one before the sbaddr Directory Entry Block Updated 2013/03/02 Next is the directory entry block. Tag.tag of this block is Tdir . Also, Tag.path matches the Tag.path of the parent directory. The directory entry block contains one or more of the following directory entries (Dentry) (up to 62 in the case of cwfs64x). struct Dentry { char name [NAMELEN]; Userid uid; Userid gid; ushort mode; #define DALLOC 0x8000 #define DDIR 0x4000 #define DAPND 0x2000 #define DLOCK 0x1000 #define DTMP 0x0800 #define DREAD 0x4 #define DWRITE 0x2 #define DEXEC 0x1 Userid muid; Qid 9 p 1 qid; Off size; Off dblock [NDBLOCK]; Off iblocks [NIBLOCK]; long atime; long mtime; }; Figure 5. Directory entry Since the names of files and directories are included here, the size of NAMELEN-1 depends on the allowable name length ( NAMELEN-1 ). The dump root block is one of directory entry blocks. In the case of my system at home, you can see the dumped date as follows. term% ls / n / dump / n / dump / 2012/0801 / n / dump / 2012/0802 / n / dump / 2012/0804 / n / dump / 2012/0813 .... / n / dump / 2013/0121 / n / dump / 2013/0127 / n / dump / 2013/0128 / n / dump / 2013/0205 .... The first line is generated for the first time on dump (August 1, 2012). ls - l / n / dump / 2012/0801 You can access the files on this day as follows. maia% ls - l / n / dump / 2012/0801 d-rwxrwxr-x M 495 sys sys 0 Jul 31 2012 / n / dump / 2012/0801/386 d-rwxrwxr-x M 495 sys sys 0 Jul 31 2012 / n / dump / 2012/0801/68000 d-rwxrwxr-x M 495 sys sys 0 Jul 31 2012 / n / dump / 2012/0801/68020 d-rwxrwxr-x M 495 sys sys 0 Jul 31 2012 / n / dump / 2012/0801 / acme d-rwxrwxr-x M 495 adm adm 0 Jul 31 2012 / n / dump / 2012/0801 / adm .... d-rwxrwxr-x M 495 sys sys 0 Jan 18 2012 / n / dump / 2012/0801 / mnt d-rwxrwxr-x M 495 sys sys 0 Jan 18 2012 / n / dump / 2012/0801 / n d-rwxrwxr-x M 495 sys sys 0 Jul 31 2012 / n / dump / 2012/0801 / power d-rwxrwxr-x M 495 sys sys 0 Jul 31 2012 / n / dump / 2012/0801 / power64 d-rwxrwxr-x M 495 sys sys 0 Jul 31 2012 / n / dump / 2012/0801 / rc d-rwxrwxr-x M 495 sys sys 0 Jul 31 2012 / n / dump / 2012/0801 / sparc d-rwxrwxr-x M 495 sys sys 0 Jul 31 2012 / n / dump / 2012/0801 / sparc 64 d-rwxrwxr-x M 495 sys sys 0 Jul 31 2012 / n / dump / 2012/0801 / sys dr-xr-xr-x M 495 sys sys 0 Jan 18 2012 / n / dump / 2012/0801 / tmp d-rwxrwxr-x M 495 sys sys 0 Aug 1 2012 / n / dump / 2012/0801 / usr maia% Figure 6. ls / n / dump The dumped date information ( YYYY/MMDD ) is between dump root address and cfs root address. (Figure 3) In this case, blocks are connected as shown in the next figure 7. Figure 7. Connection of directory entry block A rectangle represents one block. In this figure, none is a directory entry block. Since the number of dumps is still small, the date information of 2013 can be made in time with one directory entry block, but multiple blocks will be required within the time. In Plan 9, as you can see from the Dentry structure in Figure 5, the name of directory and the information such as mode live in the same block. On UNIX, on the other hand, information such as mode is placed in the inode and is a block different from the list of names (Fig. 8). The origin of this difference seems to be that in UNIX, in order to support hard link, it is necessary to have the link counter in another block (specifically, inode) different from the name. Figure 8. In the conceptual diagram of unix inode, we write contents as contents of file or other directory. Qid9p1 's Qid9p1 structure struct Qid 9 p 1 { Off path; / * was long * / ulong version; / * should be Off * / }; However, this path is set to 1 in the first bit when mode is a directory (that is, when mode&DDIR != 0 ). (I'm not sure about the reason why I designed this way.) The official qid, ie the command ls - ql The qid displayed is the one with the first bit of this qid.path , that is, qid.path&~DDIR . In the case of cwfs 64 x, one Dentry is 260 B. Therefore, one block can hold up to 62 Dentry . name contains the file name and directory name. NAMELEN is 144 in the case of cwfs NAMELEN x. Since the name ends with '\0' , the maximum length of the name is 143 characters. In addition to the name, basic information for directories and files is included in this. Dentry mode&DDIR == 0 represents a file ( mode&DDIR == 0 ), the block dblock[NDBLOCK] the file contents can be traced based on direct block ( dblock[NDBLOCK] ) and indirect block ( iblocks[NIBLOCK] ). The block containing the file contents is tagged with Tfile . Dentry mode&DDIR != 0 is a directory ( mode&DDIR != 0 ), the mode&DDIR != 0 in which the directory contents (the information of the files and directories contained therein) is placed is set to direct block ( dblock[NDBLOCK] ) and indirect block ( iblocks[NIBLOCK] ). The block containing the directory contents is tagged with Tdir . In the case of NDBLOCK the value of NDBLOCK is 6 and the value of NIBLOCK is 4. Data is directly written to 6 direct blocks. Because 16 * 1024 - 12 B data can be written in one direct block, 6 direct blocks can be written with a total of 6 * (16 * 1024 - 12) B data. In the case of a directory, up to 372 (= 62 * 6) Dentry can be handled. Indirect Block For the block indicated by iblocks[0] included in the iblocks[0] structure of the directory entry block, (16 * 1024 - 12) / 8 = 2046 Block addresses. Here, 8 is the size of one block address. ) These block addresses indicate the location of the data (ie direct block). Therefore 2046 * (16 * 1024 - 12) = 33497112 B Can be written. Let's say that such block information is the primary indirect block. iblocks[1] , a secondary indirect block is written. In other words, the block addresses are written in this block, but these addresses are the primary indirect block addresses (not the data location). Therefore 2046 * 2046 * (16 * 1024 - 12) = 68535091152 B Can be written. Likewise, iblocks[2] has 2046 * 2046 * 2046 * (16 * 1024 - 12) = 140222796496992 B And iblocks[3] has 2046 * 2046 * 2046 * 2046 * (16 * 1024 - 12) = 286895841632845632 B . The tag of indirect block iblocks [0] Tind 1 iblocks [1] Tind 2 iblocks [2] Tind 3 iblocks [3] Tind 4 . Also, any of these Tag.paths matches the qid of the parent directory. File Block The block containing the contents of the file is tagged with Tfile . Tag.path of this block matches the qid of the directory to which this file belongs. One file block has a maximum 16 * 1024 - 12 B File data can be saved. The contents of the file are managed in block unit. Will all blocks be rewritten when the contents of the file is updated? According to my experiment, it is not. If you add data to the end of a file larger than one block, only the last block is updated. Other blocks are used as they are. However, this experiment (a) The append attribute is specified in the file (b) writing at the end of the file by seeking at the end of the experiment under either condition. If I open a large file larger than 16 KB with a text editor and add data to the end, I think that it can be completely rewritten. (I have not done an experiment though ...) Characteristics of cwfs in which only rewritten blocks are newly generated is particularly important in servers. On my server, the log file of web server is 1.7 GB. 1757143424 Oct 18 17: 13 http It will not go on to keep copying files of this size every day1. Note 1: On Mac / OSX's Time Machine or Linux pdumpfs, if the file has been updated, a new copy of it will be made. If we try to realize the function of TimeMachine with only hard links, copy will be inevitable specification. Since the server carries a large log file which is updated day by day, it should not be suitable for server use at all. In the case of database files, even cwfs should be removed from daily dump. It is safer to log transactions. Fsworm Root 2013/03/09 All information on fsworm can be traced from the dump root block at the top of the dump stack. You can find out this address from roaddr of cwfs console. Figures 6 and 7 are the first part of the path seen from here. Actually roaddr is a root block managed by fscache, but it matches dump root block of fsworm. Dump order The dump is done based on the current fscache. First, super block is written to fsworm. Following this, the information at the end of the directory tree is written in order. Thus, in fsworm, for example / 2012/0925 / .... Is created, the last / before 2012 , before 0925 before that ... qid From the user, you can see the qid of the file or directory by adding q option to ls command. For example maia% ls - ql (000000000009 baa2 6 00) - rw - rw - r - M 326 web web 33597 Mar 8 15: 01 bucket.png (000000000009 baa 3 300) - rw - rw - r - M 326 web web 13693 Mar 8 15: 02 bucket.svg (0000000000089b8c 2 00) - rw - rw - r - M 326 arisawa web 782 Sep 28 10: 11 console.txt (0000000000089b8d 2 00) - rw - rw - r - M 326 arisawa web 2401 Oct 15 21:21 cwfs.svg ... maia% As shown in FIG. The part of hexadecimal notation in the head () is qid, and the next digit is qid version. According to the manual qid is unique within the file system. If it is unique, the qid must be managed. It seems that qidgen in super block is there for that (Figure 4). You can tell by experimenting but qid does not change by changing file name. Version changes when content changes. So, when creating an editor, you can use it to know whether or not you have changed by something else at the time of saving, but time stamp is easier, so I used qid so far There is nothing. (The qid of unix seems to be different) Except in fsworm and fscache, qid and its version are included in the directory entry (Figure 5), and you can see that the block concerning the contents is the same qid. That is, it seems to be used to confirm the affiliation of block. Structure of fscache ba [0] config ba [1] - ba [2] Tcache ba [maddr] map ... ba [caddr] cache ... Config Block 2013/03/05 As far as cwfs64x is concerned, the following data was written in the text format from the beginning in my config block ( ba[0] ). (This content can also be seen with the printconf command of cwfs console) service cwfs filsys main c (/ dev / sdC 0 / fscache) (/ dev / sdC 0 / fsworm) filsys dump o filsys other (/ dev / sdC 0 / other) noauth newcache blocksize 16384 daddrbits 64 indirblks 4 dirblks 6 namelen 144 noauth means allowing access to cwfs without authentication. noauth should be noted that noauth is a special setting only allowed at the experimental level in a secure environment. What I use at university is the February version of this year, which is not noauth . (2013/04/10) In addition, this block is tagged as follows. pad: 0000 tag: 10 (Tconfig) path: 0 The source code has the following structured data. struct Conf { ulong nmach; / * processors * / ulong nuid; / * distinct uids * / ulong nserve; / * server processes * / ulong nfile; / * number of fid - system wide * / ulong nwpath; / * number of active paths, derived from nfile * / ulong gidspace; / * space for gid names - derived from nuid * / ulong nlgmsg; / * number of large message buffers * / ulong nsmmsg; / * number of small message buffers * / Off recovcw; / * recover addresses * / Off recovro; Off firstsb; Off recovsb; ulong configfirst; / * configure before starting normal operation * / char * confdev; char * devmap; / * name of config-> file device mapping file * / uchar nodump; / * no periodic dumps * / uchar dumpreread; / * read and compare in dump copy * / uchar newcache; }; Data in this is given (in the source code) for each type of cwfs during the initialization process. Tcache Block Tcache block manages basic information about cwfs. You can see this in the cwfs console. struct Cache { Off maddr; / * cache map addr * / Off msize; / * cache map size in buckets * / Off caddr; / * cache addr * / Off csize; / * cache size * / Off fsize; / * current size of worm * / Off wsize; / * max size of the worm * / Off wmax; / * highwater write * / Off sbaddr; / * super block addr * / Off cwraddr; / * cw root addr * / Off roraddr; / * dump root addr * / Timet toytime; / * somewhere convienent * / Timet time; }; Each block of fscache is cached in memory. Every ten seconds the cache of memory is written to fscache (if there is an update). Mapping Updated 2013/03/08 Each block of fsworm is mapped to the cache block of the cache area of ââFIG. Let cba be the cache block address of cba , cba caddr <= cba <caddr + csize . A block of fsworm 0 to wsize is mapped to this area of ââfscache. The total number of cache blocks is indicated by csize (in the cwfs console). caddr all remaining caddr starting with caddr are not cache blocks. In the example of my system, the number of blocks of fsworm is 6972701, whereas the number of cache blocks of fscache is 1392255. Therefore, it has about 1/5 cache capacity. Also, 13604540 blocks can be taken in fscache, but only 1035 + 1392255 (= 1393290) are actually used. The unused area is about 0.1%. Just thinking about it might think of mapping as shown in Table 1. Table 1. a simple but problematic mapping from fsworm to cache Here, cache is written in fscache's cache area. The address shown is counted from caddr . However, this mapping suffers from problems. If an fsworm block is cached, there may be cases where other fsworm blocks that are mapped to the same cache block can not enter cache. So cwfs keeps bucket in between, giving flexibility to mapping. The situation is shown in Table 2. Table 2. real mapping implementation of cwfs. For ease of explanation, block address of fsworm is set to wa and cache address counted from caddr to ca wa%msize that wa%msize with the same wa%msize is ca%msize to ca of ca%msize . The state of actual mapping is managed by bucket in map block of fscache. bucket A block from caddr to caddr in maddr is a map block, and its tag is Tbuck . The map block is a collection of buckets, and the bucket contains the state of cache and the block address of the corresponding fsworm. Each bucket has the following structure. struct Bucket { long agegen; / * generator for ages in this bkt * / Centry entry [CEPERBK]; }; Each map block can hold up to BKPERBLK (= 10) BKPERBLK . Figure 9. Structure of fscache (cwfs64x) The total number of msize included in msize is given by msize . In the following, bucket is numbered from 0 to msize - 1 in ascending order of block address, and it is called bucket address. cache entry Each bucket has CEPERBK (= 135) Cache Entries. Each Cache Entry represents the state of the current map. struct Centry { ushort age; short state; Off waddr; / * worm addr * / }; In order to find the block address cba of the corresponding fscache from the block address ba cba , first bn = ba% msize . Then check the waddr of 135 cache entries in bucket[bn] . If the block of block address ba of fsworm is cached, there should be some matching ba it. Letting this cache entry be entry[ce] cba = msize * ce + bn + caddr Can be obtained with. Details are explained in "Map from Worm to Cache". Conversely, to obtain the block address ba of cba from the block address cba fscache currently being cached, first bn = (cba - caddr)% msize # bucket addr ce = (cba - caddr) / msize # entry addr The bucket address bn can be found by looking up the waddr of the cache entry ce in it. The cache area block of fscache has "state" by cache entry. In the following, let's say that the state of the cache block is â¯â¯ or the worm address corresponding to the cache block is â¯â¯. age age represents the age of the cache block. Small values ââare old. So it is conceptually close to birth day rather than age. When it becomes necessary to cache newly, the small cache of age is preferentially discarded (when Cnone does not exist). And the value of agegen of bucket becomes the value of age be newly allocated. If data is allocated to cache, agegen increases by 1. The maximum value MAXAGE=10000 age exists. When it exceeds it, reallocation of age is necessary, but details are not understood because I have not read the code well. state The cache state is the state of the corresponding Centry and has the following values. Cnone = 0 Cdirty = 1 Cdump = 2 Cread = 3 Cwrite = 4 Cdump 1 = 5 The state of an Cnone cache block is Cnone to Cnone . In my observation, waddr in this case seems to be garbage and has no meaning. In the case of cache which reads data from worm, waddr is the address itself of the original worm. The state of cache is Cread . In this case the contents of the cache block are the same as the corresponding block of fsworm. (Naturally because it is a cache) When an existing directory or file is changed, the Cread tag of that cache changes to Cwrite . And waddr is not changed. Of course it will not go overwrite on dump, so at that time it will be saved in the new worm address and waddr in the cache entry should be updated at the same time. If abnormally dumped, the state will be Cread . When creating a new directory or file, wba corresponding to that cache block is assigned an unused address of worm. The state is Cdirty . When dump is completed it should be Cread . The cache of the state Cnone and Cread does not need to reflect the change in waddr . Therefore, it means that the block of fscache corresponding to this Centry may be discarded (if necessary). By the way, when you run the cwfs console statw command 8600 none 230005 dirty 0 dump 1153555 read 95 write 0 dump1 We examine Centry directly and display the distribution (number) of values ââof state . free block and dirty block 2013/03/11 2013/03/14 revision 2013/03/29 Correction 2013/04/10 added It is better to classify as follows. (a) unwritten block (b) dirty block (c) free block The unwritten block in (a) is an unwritten block existing in the dumped area. The dirty block in (b) is a block which is called Cdirty in fscache. When cwfs creates a new file or directory, it associates worm's address with cache, and Cdirty cache's state to Cdirty . This worm address is an unused address, and if unwritten block is available, use it. Immediately after dump (a) â (b) . (c) free block is a block that is registered as a free block in fscache among dirty blocks. They are not linked to the file tree. Linked dirty blocks are subject to dump, but blocks deviated from link are not dumped. cwfs ã¯ãããããŽããšããŠæšãŠãã®ã§ã¯ãªããæ°ãã« dirty block ãäœãæã«å©çšããã cwfs 㯠free block ã® list ãæã£ãŠãããfree block list 㯠supper block ã®äžãšãfscache ã®Tfree㧠tag ä»ãããã block ã«ååšãããsupper block ããã³Tfree block ã«ã¯ 2037 åã® block address æ å ±ãä¿æã§ããã åŸã£ãŠ (b) â (c) . fscache ã® Cwrite ã®ç¶æ ã® block ã¯ãå®éã« dump ãããæã«åã㊠dump å ã® address ã確å®ããããããã® address ã¯æåŸã® dump ã®äžã«ç©ã¿äžãããããä»æ¹ Cdirty ã®ç¶æ ã® block ã«ã¯ãåãããã fsworm ã® address ãšé¢ä¿ä»ããããã ãããã free block ãªã©çºçãããªãããã«å·§ããããªãã®ã? ããããèããããçµæ§é£ãããã§ãããfile ã directory ã®åé€ãåé¡ã§ãããdump ãæ¯æ¥æ5æã«è¡ããããšããããæŒéã®äœæ¥ã§ããã€ãã® directory ã file ãæ°ãã«äœã£ããšãããããããC1,C2,...,Cnãšãããfscache å ã®ãããã® block ã¯ã©ããCdirtyã®ç¶æ ã«çœ®ãããfsworm ã® address ãšé¢ä¿ä»ããããããããã®å ã®ããã€ãã¯ãã®æ¥ã®å ã«åé€ãããããšãããã ãããåé€ããããã®ãD1,D2,...,Dmãšããã C1,C2,...,CnããD1,D2,...,Dmãå·®ãåŒããéšåã dump ãããã®ã§ããããdump ã§çæããã fsworm ã® address ãé£ç¶ããŠããäºã¯æåŸ ããããããç©Žããæã€äºãšãªããããã㯠free block ãšããŠå°æ¥ã®å©çšã®ããã«äºçŽãããã¯ãã§ããã ãã¡ãããåé€ãã file ã directory ã¯çŽã¡ã«èŠª directory ã® entry ããåé€ããããããã® contents ã®ç¶æ ã¯Cdirtyã®ãŸãŸã«ãªã£ãŠããã Cdirtyåé¡ã¯åã«ã¯ãŸã åãããªãäºãå€ããåã® fscache ã¯å€§éã®Cdirty block ãæ±ããŠãããã©ãããããã®ç¶æ ã¯ç°åžžããããåå ã¯äœã? èããããã®ã¯ cwfs console ã® clri ã³ãã³ãã§å€§ã㪠directory ãåé€ããããšã«ãcheck free ã³ãã³ããè¡ããªãã£ãäºãrm ã³ãã³ãã«ãã£ãŠãã¡ã€ã«ãåé€ããå Žåã«ã¯ãäžèŠã«ãªã£ã block 㯠free block list ã«å ¥ã£ãŠè¡ãããclri ã®å Žåã«ã¯å ¥ããªããããããããã¯å©çšãããªã block ãšããŠæšãŠããããããã super block ã«ã¯ free block list ãæã¡ã2037 åã® free block ãç»é²ã§ããããããè¶ ãã free block ã® address ã¯ã Tfreeã§ã¿ã°ä»ãããã fscache ã® block ã«èšé²ãããŠããã Tfree block 㯠super block ãšåæ§ã« free block list ãæã£ãŠãããfree block list ã®æ§é äœã¯äž¡è ãšãåãã§ããã super block ãTfree block ã«å«ãŸãã free block ãfree[n] ( n=0,1,... ) ãšããããœãŒã¹ããã°ã©ã ãè¿œã£ãŠè¡ããšã free[0]ã¯ç¹æ®ã§ããããšãåãããããã¯Tfree block ãžã® pointer ãªã®ã§ããããã£ãšæ£ç¢ºã«èšãã°ã free[0]ã«å¯Ÿå¿ãã fscache ã® address ãTfree block ã«ãªã£ãŠããã¯ãã§ããã(å³10) å³10. freelist chaine msize ãš csize msizeåã® bucket ã®äžã«ã¯msize*CEPERBKåã® cache entry ãååšãããçè ã®ã±ãŒã¹ã§ã¯ã msizeã 10313 ãªã®ã§ããã®èšç®çµæ㯠1392255 ãšãªãããã®æ°åã¯csizeã«äžèŽããã In other words, csize = msize*CEPERBK ã®é¢ä¿ãæç«ããã1ã€ã® Cache Entry 㯠1ã€ã® cache block ã管çããŠããã®ã§ããã msizeåã® bucket ãåçŽããã«ã¯ã (msize+BKPERBLK-1)/BKPERBLK åã® block ãå¿ èŠã§ãããå²ãç®ã®åœ¢ãè€éãªã®ã¯ãåãäžããŠããããã§ãããçè ã®ã±ãŒã¹ã§ã¯ã msizeã 10313 ãªã®ã§ããã®èšç®çµæ㯠1032 ãšãªããããã«maddrã® 3 ãå ããŠã caddrã® 1035 ãšäžèŽããã In other words, caddr = (msize+BKPERBLK-1)/BKPERBLK + maddr ã®é¢ä¿ãæç«ããã Map from Worm to Cache bnã bucket addressã ceãããã® bucket ã®äžã® cache entry ã®ã¢ãã¬ã¹ãšããã bnãšceã¯æ¬¡ã®ç¯å²ã«ããã 0 <= bn < msize 0 <= ce < CEPERBK bnãšceãåºã«ãcache block address ã察å¿ãããªããŠã¯ãªããªãã 2ã€ã®èªç¶ãªèãæ¹ãããã (a) bn*CEPERBK+ce+caddr (b) msize*ce+bn+caddr ãã¡ããä»ã®ãã£ãšè€éãªãããã³ã°ã¯èããããããããããæ¡çšããçç±ã¯ååšããªãã ãããŠãå®éã«ã¯åŸè ã®æ¹åŒ(b)ãæ¡çšãããŠããã å è ã¯æ¡çšããããããªããªãããã¡ã€ã«ã¯ fsworm ã®é£ç¶ãã block ãå ããåŸåããããåŸã£ãŠ (a) ãæ¡çšãããªãã°ãæ°ãã«äœæããã倧ããªãã¡ã€ã«ã®ãã£ã·ã¥æ å ±ã¯1ã€ã® bucket ãå æããããšã«ãªãããããšãã® bucket ã管çãã cache block ã«ã¯ã(fsworm ã« dump ããªãéã)æ°ãã«ãã£ãã·ã¥ã§ããªããªãã ããã«åŸè ã®å Žåã«ã¯ãfsworm ã®é£ç¶ãã block ããã£ãã·ã¥ããå Žåã«ãfscache ã§ãé£ç¶ãã block ã«ãªãå¯èœæ§ãé«ããšããã«ããã(ããŒããã£ã¹ã¯ã® seek time ãç¯çŽã§ããã) msize ã®æ±ºå®ã¢ã«ãŽãªãºã msizeã¯ã©ã®ãããªèšç®ã§æ±ºå®ãããã? map block ãš cache block ã®åèšæ°ãmãšãããšã map block ãnåã«ããå Žåã®å¯èœãªmn (= csize ) ã®å€ã¯ã (n-1)*BKPERBLK*CEPERBK < m - n <= n*BKPERBLK*CEPERBK ãæºããå¿ èŠãããã In other words, 1.0*m/(1 + BKPERBLK*CEPERBK) <= n < 1.0*(m + BKPERBLK*CEPERBK)/(1 + BKPERBLK*CEPERBK) ãå ±ã«æºããå¿ èŠããããããã®ãããªn㯠n = (m + BKPERBLK*CEPERBK)/(1 + BKPERBLK*CEPERBK) ã§åŸãããã That is, m - n = ((m - 1)*BKPERBLK*CEPERBK)/(1 + BKPERBLK*CEPERBK) ãã®ããã«èšç®ãããmnã¯CEPERBKã®åæ°ã§ããä¿èšŒãç¡ããåŸã£ãŠæ¬¡ã®è£æ£ãå ããå¿ èŠãããã msize = (mn)/CEPERBK csize = msize*CEPERBK caddr = (msize + BKPERBLK - 1)/BKPERBLK + maddr ã§èšç®ãããäºã«ãªããã çè ã® fscache 㯠1394540 block 確ä¿ã§ããã®ã§ã m = 1394540 - 3 = 1394537 .ãã®èšç®æ¹åŒã«ããã° msize = 10322 caddr = 1036 csize = 1393470 ãšãªãã caddr + csize㯠1394506 ã§ããããã㯠fscache ã® block æ° 1394540 ãããå°ããã®ã§ãããã§è¯ãã¯ããªã®ã§ããããå®éã® cwfs ã®å€ã¯éããå®éã«ã¯ããã®msizeãããã«èª¿æŽã msize = maxprime(msize - 5) # Ken's value csize = msize*CEPERBK caddr = (msize + BKPERBLK - 1)/BKPERBLK + maddr ãšããŠãã( cw.c )ãããã«maxprime(n)ã¯ã nãè¶ ããªãæ倧ã®çŽ æ°ã§ããããã®èª¿æŽãäœæ å¿ èŠãªã®ã? çè ã«ã¯äžæã§ããã(fsworm ãš fscache ãšã®é¢ä¿ã§ã¯ããã®èª¿æŽã¯äžèŠãªã¯ãã§ããã) Fscache Root 2013/03/09 fsworm ã root ãæã€ããã«ãfscache ã root ãæã£ãŠããã(æããªããã° directory tree ã蟿ããªã) fscache ã® root block ã® address 㯠fsworm ã® dump stack top ã® dump root block ã® address ãåºã«ããŠãéåžžã® mapping rule ã«åŸã£ãŠæ±ºå®ãããŠããã Recovery 埩å (recovery) 2013/02/28 æŽæ° cwfs ã«ç°åžžãããããåå ã¯ããããããããäž»ãªã±ãŒã¹ã¯æ¬¡ã®2ã€ã§ãããã (a) æžã蟌ã¿äžã®åé» (b) ããŒããŠã§ã¢ã¯ã©ãã·ã¥ãããã¯ããã«ãæ§ã ãªã±ãŒã¹ã§çŽ°ååãããããããã§ã¯ fsworm ãå¥å šã§ãã(ãããã¯åããããªããšã§ããããfsworm ã®ããã¯ã¢ãããååšããŠãã)ããšãä»®å®ããããã®å Žåã«ã¯ãfsworm ã«åºã¥ããŠåŸ©å ããããšã«ãªãã 以äžã®ä»®å®ã眮ã: /dev/sdC0/fscache /dev/sdC0/fsworm ãååšãã fswormã¯å¥å šã§ããã fscacheã®å é block ã«ã¯æ£ãã config æ å ±ãå«ãŸããŠããã ãã®å ã§ã¯ãcwfs ã®ã¹ã¿ãŒãã§(9front ã§ã¯) bootargs is (tcp, il, local!device)[local!/dev/sdC0/fscache] ã®ã¡ãã»ãŒãžãã§ãã®ã§ local!/dev/sdC0/fscache -c ã input ãããã®åŸconfig:ã® prompt ã«å¯Ÿã㊠recover main end ã§å¿ããã°ããã(埩å ã¯éåžžã«æ©ãã(1~2ç§?) fscacheã®å é ãããã¯ã¯ãcwfs ã®æŽ»åäžã«ã¯æžã蟌ã¿å¯Ÿè±¡ããå€ãããŠããã®ã§ãããŒããã£ã¹ã¯ãç©ççæå·ãåããŠããªãéããããŒã¿ã®ãã¹ã¯é«ã ãæåŸã® dump 以éã«éããããšèšããã fscache ã®åŸ©å ã«å¿ èŠãªå šãŠã®æ å ±ã fsworm ã® block address ç¯å² 0 ããsnextãŸã§ã®äžã«å«ãŸããŠããã埩å ã«éããŠãfsworm ã®å šãŠã調ã¹ãå¿ èŠã¯ç¡ããæåŸã«ãã³ãããèšé²ãã蟿ãäºãã§ããããã®äœæ¥ã¯ cwfs ãèªåçã«è¡ãã¯ãã§ããããåèã®ããã«ãfsworm ã®æ§é ãããå°ã詳ãã解説ããã Plan9(ãããã¯9front)ã§ã¯ãéå»ã®ãã¡ã€ã«ã®ç¶æ 㯠9fs dump ãå®è¡ã㊠/n/dump 以äžã«èŠããããããã«èŠããå šãŠã®æ å ±ã次ã®ãã³ãã¢ãã¬ã¹snextã®1ã€åã® block ã¢ãã¬ã¹ ( = roaddr = snext - 1 ) ããç°¡åã«èŸ¿ã£ãŠè¡ãããšãã§ããã åŸã«çŽ¹ä»ããããã°ã©ã cwstudy ã¯ãblock ã¢ãã¬ã¹ãæå®ããŠããã®å 容ã衚瀺ããã次㯠cwstudy ã®å®è¡äŸã§ããã cpu% cwstudy 1755392 /dev/sdC0/fsworm tag pad: 0000 tag tag: 11 (Tdir) tag path: 1 name: / uid: -1 gid: -1 mode: 0140555 muid: 0 qid path: 80000001 qid ver.: 0 size: 0 dblock: 1755391 0 0 0 0 0 iblock: 0 0 0 0 atime: 1343737574 // Tue Jul 31 21:26:14 JST 2012 mtime: 1343737574 // Tue Jul 31 21:26:14 JST 2012 æåã«åŸãããåå㯠â / â ã§ãããäœææ¥ã¯ãfsworm ãäœããã 2012幎7æ31æ¥ãšãªã£ãŠããã dblock[0]ã®1755391ã¯ã" / " ã®äžã® directory entry block ã®ã¢ãã¬ã¹ã§ããã cpu% cwstudy 1755391 /dev/sdC0/fsworm tag pad: 0000 tag tag: 11 (Tdir) tag path: 1 name: 2012 uid: -1 gid: -1 mode: 0140555 muid: 0 qid path: 80000001 qid ver.: 27 size: 0 dblock: 1755390 0 0 0 0 0 iblock: 0 0 0 0 atime: 1348729247 // Thu Sep 27 16:00:47 JST 2012 mtime: 1343797238 // Wed Aug 1 14:00:38 JST 2012 block ã¢ãã¬ã¹1755391ã«å«ãŸãããã£ã¬ã¯ããªã®ååã¯2012ã§ããã1ã€ããçŸããŠããªãã®ã¯ãfsworm ã®éçšéå§ã2012ã ããã§ããã block ã¢ãã¬ã¹1755390ã«ã¯å€æ°ã® directory entry ãå«ãŸããŠããã term% cwstudy 1755390 [äžç¥] name: 0925 uid: -1 gid: -1 mode: 0140555 muid: 0 qid path: 80000001 qid ver.: 27 size: 0 dblock: 1755212 0 0 0 0 0 iblock: 0 0 0 0 atime: 1348584237 // Tue Sep 25 23:43:57 JST 2012 mtime: 1348584237 // Tue Sep 25 23:43:57 JST 2012 name: 0927 uid: -1 gid: -1 mode: 0140555 muid: 0 qid path: 80000001 qid ver.: 27 size: 0 dblock: 1755388 0 0 0 0 0 iblock: 0 0 0 0 atime: 1348729247 // Thu Sep 27 16:00:47 JST 2012 mtime: 1348729247 // Thu Sep 27 16:00:47 JST 2012 ãããã®ååã¯ããã³ãããææ¥ãè¡šããŠããããŸããããã㯠ls /n/dump/2012 ã§è¡šç€ºãããååãšäžèŽããã ããã«é²ãã§ã 2012ã®äžã«ãã0927ã® directory entry ãåæ§ã«èŠã€ããäºãã§ããããããã®åå㯠ls /n/dump/2012/0927 ã§è¡šç€ºãããååãšäžèŽãããããã«ã¯admãsysãusrãªã©ã®ååãèŠããã ããã 0925ã®dblock[0]ã¯1755212ã§ããããã® block ã¢ãã¬ã¹ã¯ 9æ25æ¥ã«ãã³ããã block ã®äžã«å«ãŸããŠããã(ãã®æ¥ã«ã¯1754642ãã1755216ãŸã§ãæ¶è²»ããã) 9æ27æ¥ã®ãã³ãã§ã¯ããã®æ¥ã®ãã¡ã€ã«ãå šãŠæ°ãã«ã³ããŒããã®ã§ã¯ãªããå€æŽãããŠããªãã³ã³ãã³ãã«é¢ããŠã¯ãå€ãã³ã³ãã³ãããã®ãŸãŸäœ¿ããããã§ã¯0925ã«é¢ããŠã¯ã9æ25æ¥ã®ã³ã³ãã³ãããã®ãŸãŸäœ¿ãããŠããã fsworm ã§ã¯ block åäœã®å·®åæ³ã䜿ãããŠããã®ã§ããã(ãã®ä»¶ã«é¢ããŠã¯åŸã«ãŸãåå³ãã) 埩å (recovery)ã«ã€ããŠåå³ fsworm ãå¥å šã§ããã°ãsuper block ãsnextãŸã§èŸ¿ãã°ã snextãåºã«åŸ©å ã§ãããã§ã¯ç¢ºå®ã«snextãŸã§èŸ¿ããã®ã? fsworm ãæ¬åœã® WORM ãããã¯æ°åã®ããŒããã£ã¹ã¯ã§ããã°åé¡ã¯ãªãã§ãããã snextã®å ã«ã TagãããããŒã¿ã¯ç¡ãã®ã§ããããééãäœå°ã¯ç¡ããããã䜿ãå€ãã®ããŒããã£ã¹ã¯ã§ããã°ã©ãã ãã? Tagãé Œãã« super block ã蟿ãéã«ããŽããTagãšåéããããããããªããsuper block ã®Tagæ§é äœã¯ struct Tag { short pad; /* make tag end at a long boundary */ short tag; Off path; }; ã§ããã pad㯠0ã tag㯠1ã path㯠2 ã§ããããŽãã®äžã§ããã® 12Bãå®å šã«äžèŽãã確ç㯠2 -96ã§æ³š1 ãååã«å°ãããšèãããããããªããäœãããfscache ãã¯ã©ãã·ã¥ãã確çèªäœã極ããŠå°ãããŠããµãŒãã®ã©ã€ãã¿ã€ã (5幎çšåºŠã?)ã®äžã«ããããç¡ããã ã ã ããããããã確çã®èšç®ã¯ãã©ã³ãã ãªããŒã¿ãæžã蟌ãŸããŠããäºãåæã«ããŠããããã®äœ¿ãå€ãã®ããŒããã£ã¹ã¯ã® fscache ããŒãã£ã·ã§ã³ãã以åã« fscache ããŒãã£ã·ã§ã³ãšããŠå©çšãããŠãããã®ãããã®ãŸãŸäœ¿ã£ããã©ãã ãã? 誀èªããã確ç㯠fsworm ã®äžã§ã® super block ã®å²åãŸã§ã«äžããã®ã§ãç¡èŠã§ããªããããããªããåŸã£ãŠãfscache ã®ããŒãã£ã·ã§ã³ãäœãå Žåã«æ³šæããæ¹ãè¯ãã ããã(ããŒãã£ã·ã§ã³ã®å é ã¢ãã¬ã¹ãå°ãããããšã...) fscache ã® Tcache block ã®äžã«ã¯ fsworm ã®æåŸã® super block ãšã®æŽåæ§ã確èªã§ããæ å ±ãå«ãŸããŠãããåŸã£ãŠéåžžã® recovery ã«ãããŠã¯ãã®ãããªå¿é ã¯ãããªãã¯ãã§ããã 泚1: å®éã«ã¯ã tagãšpathã ãã§èŸ¿ã£ãŠããã®ã§ã確ç㯠2 -80ã§ããããã®ç¢ºçãå°ããããããã«ã¯ãä»ã«slastã®æ å ±ã䜿ãæãããããããããŸã§ã®äŸ¡å€ããããã¯æªããã Recovery ã«ãã£ãŠå€±ããããã® 2013/03/28 free block ã§å€±ããããã®ãããã free block ãšã¯æ¢ã« dump ãããé åã«ååšããããŸã æžã蟌ãŸããŠããªã block ã§ãããcwfs ã¯ãããã« data ãæžã蟌ãæ©äŒãããã°æžã蟌ãããšãããèšæ¶ã¹ããŒã¹ãæå¹ã«äœ¿ãããšããŠããã®ã§ãããfree block ã®ãã¡ 2037 å㯠superblock ã管çããŠããããã®æ å ±ã¯ fsworm ã«ããã®ã§å€±ãããªããããã 2037 åãè¶ ããéšåã® free block list 㯠fscache ã® Tfree block ã«ååšããŠãããTfree block 㯠fsworm ã«ã³ããŒãããªããããã㯠Recovery ã§å€±ãããã Other Configurations 2013/04/02 pseudo-RAID1 çµå±çŸåšã® cwfs configuration filsys main c(/dev/sdC0/fscache)(/dev/sdC0/fsworm) ã®äžã§ã¯ fsworm ã® backup ãåãã®ã¯è³é£ã®æã§ãããšè«ŠããŠãä»ã® configuration filsys main c(/dev/sdC0/fscache){(/dev/sdC0/fsworm)(/dev/sdD0/fsworm)} ãæ¡çšããããšãšããã ãã㯠pseudo-RAID1 ã® configuration ã§ãããããã€ã¹ãŸãããšã§ã¯ãªããfsworm partition ã ãã RAID1 颚ã«åŠçããŠãããã /dev/sdC0/fswormãš/dev/sdD0/fswormã¯ãµã€ãºãç°ãªã£ãŠãæ§ããªãããã®å Žåã«ã¯å°ããæ¹ã«åãããããã æžã蟌ã¿ã®é åºã¯ã(ãã®å Žåã«ã¯) D0 â C0ã§ãããèªã¿åãã¯C0ã§è¡ãããã ãã£ã¹ã¯ç·šæã®å€æŽã«ããã£ãŠã¯ãæºåãå¿ èŠã§ããã ã³ããŒãåããªããŠã¯ãªããªããpartition ãŸãããšã¯æéãããããããã®ã§ãæåŸã® super block ãŸã§ã®ã³ããŒã«å¶éããå¿ èŠãããã ããã§ããŸã æéãæãããããããç¥ããªãã®ã§ããã®éã® auto dump ãæ¢ããå¿ èŠãããããã®ããã«ã¯ãcwfs ã«ããããããŠãªããšãããªãã ãã£ãšããRAID ã¯åã家åºã§äœ¿ãã«ã¯å€§ãããªã®ã§ããã... 家ã§äœ¿ã£ãŠããéãé 調ã«åããŠããã倧åŠã®ãµãŒããŒãããã§ããããšã«ããã fake WORM Cinap ã«ãããš fake WORM ã®äžã«ã¯ written block ã® bit map ãããããã§ããããã®å ŽåãHDD ã WORM ã®ä»£ããã«äœ¿ãã®ã ãããçŸåšã®å©çšç¶æ ã瀺ã bit map ãæã€äºã¯å¯èœãªã®ã§ããããã®å Žåã® configuration 㯠filsys main c(/dev/sdC0/fscache)f(/dev/sdC0/fsworm) . ããã䜿ãã°ãæ®æ®µã¯ 1 åã® disk ã䜿ããæ°ã®åããæã« backup disk ãè¿œå ããŠããã¯ã¢ãããåãåã®ãããªæ°ãŸãããªäººéã«é©ããåŠçãå¯èœã§ããããšæããã fake WORM ã®äœæ å ã® WORM ã¯éåžžã® WORM ãªã®ã§ãfake WORM ãäœãå Žåã«ã¯ãdevice ã®ã³ããŒãšããèš³ã«ã¯è¡ããªãã¯ããŠãããæ°ãã«æ§æããäºãšããå®å šã®ããã«ãPXE ã§ç«ã¡äžãã端æ«ã§äœæ¥ããããšãšãããlocal disk ã«ã¯ããããã cached fake WORM ãæ§æãã plan9 partition ãæºåããŠããã /dev/sdC0/fscache /dev/sdC0/fsworm ãã®äžã§ cwfs64x -c -f /dev/sdC0/fscache ãå®è¡ãã泚1 ã 泚1: cwfs ã®ã³ãã³ãã®äœ¿ãæ¹ã¯ãBell-labs ç(Geoff ã®ãªãªãžãã«ç)ãš 9front çã§ã¯ç°ãªããããã§ã¯ 9front çã«åºã¥ãã9front çã§ã¯ãkfs ã fossil ãªã©ãä»ã®ãã¡ã€ã«ã·ã¹ãã ãš -f ãªãã·ã§ã³ã®äœ¿ãæ¹ã®çµ±äžãèšã£ãŠããã 9front çã§ã¯-c option 㧠config mode ã«å ¥ãã configã® prompt ã«å¯ŸããŠæ¬¡ã®ããŒã¿ã input ããã service cwfs filsys main c(/dev/sdC0/fscache)f(/dev/sdC0/fsworm) filsys dump o filsys other (/dev/sdC0/other) ream other ream main end 以äžã¯äžåéãã§ããã 次㫠cwfs console ãžã®ã³ãã³ããš shell ã¬ãã«ã®ã³ãã³ããçºçãããããã§ã¯ cwfs console ãžã®ã³ãã³ããfscons>ã§è¡šãã 以äžã®æäœã¯æ°ãã window ã®äžã§è¡ãã®ãç¡é£ã§ããã fscons> users default fscons> newuser arisawa fscons> allow term% mount -c /srv/cwfs /n/cwfs term% mkdir /n/cwfs/adm term% cp /adm/users /n/cwfs/adm fscons> users 泚æ: newuser arisawaã¯ãçè ã®ã·ã¹ãã ã® system owner ã¯glendaã§ã¯ãªãarisawaã ããå¿ èŠã«ãªã£ãã®ã§ããã glendaã®ãŸãŸã§ããã°äžèŠã§ããã ãã®ããšã¯ãçè ã®cpdirã䜿ãã®ãæ©ãã cpdir -mvug /root /n/cwfs adm 386 acme cfg cron lib mail rc sys /rootã®äžã«ããfd ã mnt ã n ã tmp ã usrã¯åå¥ã«ç¢ºèªããæ¹ãç¡é£ã§ããã ç¹ã«ã /root/n/ã®äžã«ã¯cwfsãèŠããŠããã¯ãã§ããã Tvirgo fakeworm ã®å Žåã«ã¯ cwfs console ã® statw ã§ï¿œï¿œï¿œç€ºãããwsizeããã Tvirgo block ãå§ãŸãã Tvirgo block 㯠fsworm ã® block 0 ããwsize㟠ã§ã®äœ¿çšç¶æ³ã bitmap ã§è¡šããŠãããæžã蟌ãŸãã block ã«ã¯ bit 1 ãç«ãŠããããŸã æžã蟌ãŸããŠããªã block ã® bit 㯠0 ã§ãããfsworm ã®å é 2 block ã¯æžã蟌ãŸããŠããªãã®ã§ãbitmap ã®æåã® 2 bit 㯠0 ã§ããã fakeworm 㯠fsworm ã®æ«å°Ÿã« bitmap ãå ¥ã蟌ãã®ã§ããã®åã wsizeã¯å°ãããªãã Misc. What did I do that day? 2013/03/18 ããã®æ¥ã¯äœãããŠããã®ã ãã?ããšåãèããå Žåã«ã¯ããã¡ã€ã«ã®ä¿®æ£ãªã©ã®è©±ã§ããã飲ã¿ã«è¡ã£ããšãã®è©±ã§ã¯ãªãã ãã®æ¥ã«å€æŽããããã¡ã€ã«ãå šãŠåæããã«ã¯ãUNIX ã§ã¯ find ã³ãã³ãã䜿ããšæããèšå€§ãªãã¡ã€ã«ã®äžãããå€æŽããããã¡ã€ã«ãæ¢ãåºãäœæ¥ã¯(ãã¡ã€ã«ã®éã«ãããã)å€ãã®æéãèŠãæ°ç§ã§ã¯çµãããªããã¡ãªã¿ã«åã® MacBook ã§ã¯åã®$HOMEã®æ¢çŽ¢ã ãã§ã30ç§çšèŠããŠããã(çµæ§ããããã®ãã¡ã€ã«ãæã£ãŠããããããã) bash$ touch a.txt bash$ time find $HOME -newer a.txt -print find: /Users/arisawa/.emacs.d/auto-save-list: Permission denied /Users/arisawa/Library/Application Support/Google/Chrome/Default/Cookies ... ... find: /Users/arisawa/src/rminnich-vx32-17a064eed9c2/src/9vx/osx/9vx.app: Permission denied real 0m28.372s user 0m0.783s sys 0m18.783s bash$ ããã§çŽ¹ä»ããã®ã¯åã®äœã£ã lr ã³ãã³ãã§ãããfind ã® -newer ãªãã·ã§ã³ã«çžåœãããªãã·ã§ã³ãååšãããããã䜿ã£ãŠæšæ¥ã«å€æŽããããã¡ã€ã«ããµãŒããŒã®å šãŠã®ãã¡ã€ã«ã®äžããèŠã€ããã«ã¯æ¬¡ã®ããã«ããã term% cpu -h ar ar% 9fs dump mounting as arisawa mounting as arisawa ar% ls /n/dump/2013|tail -2 /n/dump/2013/0317 /n/dump/2013/0318 ar% mtime /n/dump/2013/0317 1363498134 /n/dump/2013/0317 ar% time lr -lt 1363498134 /n/dump/2013/0318 ... ... --rw-rw-rw- web arisawa 5819730 2013/03/18 12:54:03 /n/dump/2013/0318/usr/cpa/www/log/dict d-rwxrwxrwx arisawa arisawa 0 2013/03/17 21:51:56 /n/dump/2013/0318/usr/cpa/www/users ... ... 0.01u 0.18s 1.91r lr -lt 1363498134 /n/dump/2013/0318 ar% ãã®æ¥ã«ã¯33åã®ãã¡ã€ã«ã®å€æŽããã£ããå€ã㯠log ãã¡ã€ã«ã§ãããå€æŽããããã¡ã€ã«ã®äžã«ã¯ web ã® cgi ã«æ ããã®ããããã·ã¹ãã ã®å šãŠã®ãã¡ã€ã«ãæ¢ããŠããã®ã ã2ç§åŒ±ã§æ¢çŽ¢ãå®äºããŠãããåã¯èšå€§ãªãã¡ã€ã«ããµãŒããŒäžã«æã£ãŠããã«ãä¿ããã㧠ãã! ãªããããªã«é«éã«å€æŽã調ã¹ãããã®ã? æ¢çŽ¢ã«atimeãå©çšãããŠããããã§ããã atimeãšã¯ access time ã®æå³ã§ãããããã¥ã¢ã«ãèŠãŠããã以äžã«è©³ãã説æã¯ãªãã(Plan9 ã®ããã¥ã¢ã«ã«ã¯ read time ãšæžããŠããããwrite ã«å¯ŸããŠãatimeãæŽæ°ããã) 泚: lr 㯠http://plan9.aichi-u.ac.jp/netlib/cmd/lr/ ã«çœ®ãããŠããã atime 2013/06/06 å®éã®åäœãèŠãŠãããšãPlan9 ãš UNIX(MacOSX ã Linux) ã§æ¯ãèããç°ãªãã Plan9 ã®å Žåã«ã¯ããã¡ã€ã«ãµãŒãããã¡ã€ã«ãæ¢ãåºãããã«èŸ¿ã£ãã«ãŒãã«ååšããå šãŠã®ãã£ã¬ã¯ããªã®atimeãæŽæ°ãããŠãããèšå€§ãª directory tree ã®äžã§ãæå®ãããæ¥ã«å®éã«ãã¡ã€ã«ãµãŒãã蟿ã£ãéã¯æ¥µã極ãå ãã§ãããåŸã£ãŠatimeãèŠãŠããã°ãå¿ èŠãªæ¢çŽ¢ã®ã«ãŒããå€§å¹ ã«æžããäºãå¯èœã§ããã UNIX ã§ã¯éãããã¡ã€ã«ãµãŒãããã¡ã€ã«ãæ¢ãåºãããã«èŸ¿ã£ãã«ãŒãã«ååšãããã£ã¬ã¯ããªã®atimeã¯æŽæ°ãããŠããªããå€æŽãå®éã«çºçãããã£ã¬ã¯ããªããã¡ã€ã«ã®atimeã ããæŽæ°ãããŠãããåŸã£ãŠã atimeãé Œãã«ãæŽæ°ãå¹ççã«æ¢ãåºãäºã¯ã§ããªãã 以äžã«ãPlan9 ãš UNIX ã® atime ã®éããå ·äœäŸã§ç€ºãã Plan9 # Plan9 term% date; touch $home/doc/x;ls -dlu /usr $home/doc Wed Jun 5 07:58:17 JST 2013 d-rwxrwxr-x M 20 sys sys 0 Jun 5 07:58 /usr d-rwxrwxr-x M 20 arisawa arisawa 0 Jun 5 07:58 /usr/arisawa/doc term% Linux # UNIX (Linux) hebe$ date; touch $HOME/doc/x; ls -dlu /home $HOME/doc Wed Jun 5 07:56:41 JST 2013 drwxr-xr-x 3 root root 4096 Jun 4 09:49 /home drwxr-xr-x 9 arisawa arisawa 4096 Jun 5 07:46 /home/arisawa/doc hebe$ OSX # UNIX (OSX) -bash$ date; touch $HOME/doc/x; ls -dlu /Users $HOME/doc Wed Jun 5 08:08:27 JST 2013 drwxr-xr-x 6 root admin 204 May 31 07:51 /Users drwxr-xr-x 3 arisawa staff 102 Jun 5 08:03 /Users/arisawa/doc -bash$ cwstudy This section is incomplete. usage cwstudy block_address cwstudy -C block_address cwstudy path cwstudy super æç® [1] Sean Quinlan âA Cached WORM File Systemâ Softw., Pract. Exper., vol. 21 (1991), pp. 1289-1299 http://plan9.bell-labs.com/who/seanq/cw.pdf [2] Ken Thompson, Geoff Collyer âThe 64-bit Standalone Plan 9 File Serverâ http://plan9.bell-labs.com/sys/doc/fs/fs.pdf