cwfs の研究 Study of cwfs

目次 table of contents

2012/10/20 2012/10/20
2013/03/14 更新 2013/03/14 renewal
2013/03/28 更新 Updated on March 20, 2013
2013/04/02 更新 Updated 2013/04/02
2013/04/10 更新 Updated 2013/04/10
2013/04/24 更新 2013/04/24 Update

2012年の夏休みは、9front の cwfs を試していた。 For the summer vacation in 2012, I was trying 9front's cwfs. cwfs は fscache と fsworm で構成されているが、fsworm の方から調べることとした。 cwfs consists of fscache and fsworm, but we decided to look it up from fsworm. fsworm の方に関心がある理由は、ファイルの履歴等の情報は fsworm に置かれ、また fscache がクラッシュした時のリカバリーも 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. fsworm に対してもバックアップが必要である。 Backup is necessary for fsworm. cwfs 自体を RAID に置くことも考えられようが、僕には大げさすぎる。 It may be possible to put cwfs itself in RAID, but it's too overkill for me. もう一つ HDD を追加して、そこに fsworm のコピーを持ちたい。 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.

9front 付属の cwfs は cwfs64x である。 The cwfs attached to 9front is cwfs64x. そこで、ここでは 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.

cwfs とは What is cwfs

この節は未完成である。 This section is incomplete. 暇な時に書く事とする。 I will write it in my spare time.

注意: あなたのブラウザは SVG をサポートしていません。 Note: Your browser does not support SVG. 最新のブラウザをお使いください。 Please use the latest browser.
図1. layer Figure 1. layer

Sean Quinlan (Ph.D) Sean Quinlan (Ph.D)
Ken Thompson (Ken's fs) Ken Thompson (Ken's fs)
Plan9 2nd edition (1995) Plan 9 2nd edition (1995)
Geoff Collyer (2007/03/27 mail) Geoff Collyer (2007/03/27 mail)
9front (2011) 9front (2011)
過去の履歴 Past History
WORM (write once read many) WORM (write once read many)
消えない(消せない) It will not disappear (can not be erased)
dump dump

Mac/OSX の time machine との比較 Comparison with Mac / OSX time machine
pdumpfs pdumpfs

以前はサーバのために1台を割り当てていた。 Previously we had one assigned for the server.
memory: ファイルサーバ専用機の中のメモリー memory: Memory in the dedicated file server
disk: disk cache disk: disk cache
WORM: 光ディスク WORM: Optical disc

現在は Plan9 の基で動くユーザープログラム cwfs Currently it runs under Plan 9 user program cwfs
ユーザプログラムである事の利点: 仕組みを調べやすい。 Advantages of being a user program: It is easy to check the mechanism.
memory: cwfs daemon 中のメモリー memory: memory in cwfs daemon
disk: ファイルサーバの fscache パーティション disk: fscache partition of file server
WORM: ファイルサーバの fsworm パーティション WORM: File server fsworm partition

cwfs (or cwfs32) cwfs (or cwfs32)
cwfs64 cwfs64
cwfs64x cwfs64x

cwfs console cwfs console

概要 Overview

cwfs に関する僕のパーティションのサイズは次の通りである。 The size of my partition on cwfs is as follows.

 term% ls -l /dev/sdC0/fs* term% ls - l / dev / sdC 0 / fs *
--rw-r----- S 0 arisawa arisawa 22848146432 Sep 13 09:50 /dev/sdC0/fscache - 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/sdC0/fsworm - rw - r ----- S 0 arisawa arisawa 114240734208 Sep 13 09: 50 / dev / sdC 0 / fsworm
term% term%

cwfs コンソールはコマンド The cwfs console uses commands

  con -C /srv/cwfs.cmd con -C /srv/cwfs.cmd
で使えるようになる。 You will be able to use with.

注意: ウィンドを新たに1つ作って Note: Create one new window
  cat /srv/cwfs.cmd cat /srv/cwfs.cmd
を実行しておいて、他のウィンドウから Run it from another window
  echo statw >> /srv/cwfs.cmd echo statw >> /srv/cwfs.cmd
を実行してもよい。 May be executed. 配布版はこの方法を想定していると思われる。 Distribution seems to assume this method.

cwfs コンソールでstatwを実行すると、fsworm の利用統計が出力される。 Running statw on the cwfs console will output usage statistics for fsworm. 次にその出力例を示す。 Next, an example of the output is shown.

 > statw > statw
cwstats main cwstats main
	filesys main filesys main
		maddr = 3 maddr = 3
		msize = 10313 msize = 10313
		caddr = 1035 caddr = 1035
		csize = 1392255 csize = 1392255
		sbaddr = 1755217 sbaddr = 1755217
		craddr = 1755389 1755389 craddr = 1755389 1755389
		roaddr = 1755392 1755392 roaddr = 1755392 1755392
		fsize = 1755394 1755394 0+25% fsize = 1755394 1755394 0 + 25%
		slast = 1754642 slast = 1754642
		snext = 1755393 snext = 1755393
		wmax = 1755392 0+25% wmax = 1755392 0 + 25%
		wsize = 6972701 1+ 0% wsize = 6972701 1 + 0%
		  8600 none 8600 none
		230005 dirty 230005 dirty
		     0 dump 0 dump
		1153555 read 1153555 read
		    95 write 95 write
		     0 dump1 0 dump1
		cache 17% full cache 17% full
> >

図2. cwfs コンソールでのstatwの出力例。 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.

maddrからwsizeまでの、等号の右の数字(1列目と2列目)は、サイズを表している。 The numbers on the right of the equal sign ( maddr to wsize ) (the first and second columns) represent the size. 1列目の数字の情報は、fscache のTcache block (block address 2) から得られる。 The information of the number in the first column is obtained from Tcache block (block address 2) of Tcache . 2列目は fsworm から得られる注1 The second column is obtained from fsworm Note 1 . これらの単位はmsizeを除けば block である。 These units are block except for msize . msizeだけは bucket 数である。 Only msize is a bucket number.

注1: この部分は正しくない。 Note 1: This part is incorrect. 2列目も fscache から得られている。 The second row is also obtained from fscache. fsworm の最後の super block の cache が fscache の中に含まれ、これを表示している。 The cache of the last super block of fsworm is included in fscache and this is displayed. fsizeを除いて、2列目の情報は、最後の super block から得られる情報と一致している。 fsize for fsize , the information in the second column matches the information obtained from the last super block. fsizestatwコマンドを実行した時点での値であり、これは fscache のTcache block から得られるfsizeと一致している。 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) (2013/04/24)

fsworm には、fsworm のパーティションサイズに関する情報は含まれない事に注目しよう。 Notice that fsworm does not include information on fsworm's partition size. fsworm が満杯になった時に、もっと大きなパーティションに置き換えられる可能性があるので、その場合には、単に満杯になったパーティションの内容を新しいパーティションにコピーすればよいように設計されているのであろう。 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 .

fscache も fsworm も block を単位として管理されている注2 Both fscache and fsworm are managed in block units. cwfs64x の場合には 1 block は 16KB である。 In the case of cwfs64x, 1 block is 16 KB. 以下、block をアドレスで表すこととする。 Hereinafter, block is represented by an address. ba[0]は 最初の block をba[1]は第2 block を意味する。 ba[0] means the first block, and ba[1] means the second block.

wsize6972701/dev/sdC0/fswormの大きさを block 数で表している。 wsize 6972701 /dev/sdC0/fsworm the size of /dev/sdC0/fsworm the number of blocks.

  6972701*16*1024 == 114240733184 6972701 * 16 * 1024 == 114240733184
これは実際の/dev/sdC0/fswormの大きさ114240734208よりも1024だけ少ないが、block を単位として使用されている為に、使用できない領域が発生したのである。 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.

fsworm にはフォーマットの概念が存在しない事に注意すべきである。 It should be noted that there is no concept of format in fsworm. なぜなら Write Once だから、フォーマットしたらデータを書き込めない! 注3 Because it is Write Once, after formatting it can not write data! 3

fsworm には先頭 block から順に書き込まれる。 It is written to fsworm in order from the top block. snext (next super block) は、次に書き込まれる block を示している。 snext (next super block) indicates the next block to be written. dump を行うと、最初に super block と呼ばれる block が書き込まれ、それに続いてデータの本体が書き込まれる。 When you dump, a block called super block is written first, followed by the body of the data. Super block は、dump 毎の境界として、fsworm においては基本的な役割を果たしている。 Super block serves as a boundary for every dump and plays a fundamental role in fsworm.

sbaddr (super block address) は、最後に書き込んだ super block のアドレスである。 sbaddr (super block address) is the address of the super block written last. また、 slastは、その1つ前の super block のアドレスである。 Also, slast is the address of the preceding super block.

注2: cwfs が管理する block は、ドライバが管理する読み書き単位としてのブロックとは別のものである。 Note 2: The block managed by cwfs is different from the block as the unit of reading / writing managed by the driver.
注3: 最近では本来の意味での WORM を使う事はないであろう。 Note 3: WORM in its original meaning will not be used recently. バックアップメディアとしての光ディスクの存在意義は無くなっており、ハードティスクで WORM を代用する方が低コストで、かつ使い勝手も良い。 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.

fsworm のバックアップ Backup of fsworm

2013/03/06 改訂 Revised 2013/03/06

fsworm は(その仕組み上)非常に堅牢ではあるが、それでもハードウェアクラッシュによるデータ消失のリスクを負っている。 Although fsworm is very robust (in its mechanism), it still has the risk of data loss due to hardware crashes. バックアップを行うには、fsworm のコピー(例えば fsworm-bak)を持てばよい。 To do the backup you have a copy of fsworm (eg fsworm-bak).

dump 毎に、fsworm の中に新たに生成された block だけをコピーして行けばよいと考えるかも知れないが、話はそんなに簡単ではない。 For each dump, you might think that you can copy only the newly created block in fsworm, but the story is not that easy. なぜなら、書き込まれていない block が最後に dump された super block の下に存在するからである。 This is because unwritten blocks exist under the last dumped super block. 筆者の観察ではそれらには2種類ある。 In my observation there are two kinds of them.
(a) reserved block 注1 (a) reserved blockNote 1
(b) free block (b) free block
である。 .
(a)は、fscache の中で使用されているが、まだ dump が完了していない fsworm の block である。 (a) is a block of fsworm that is used in fscache, but has not yet completed dump.
(b)は、今後 fscache が使用可能な fsworm の block である。 (b) is a block of fsworm that fscache can use in the future.

注1: “reserved block” は筆者が勝手に使っている用語である。 Note 1: "reserved block" is a term that I am using arbitrarily. この用語は文献には存在しない。 This term does not exist in the literature.

fsworm の構造 Structure of fsworm

Block Block

fscache も fsworm も block を単位として管理されている。 Both fscache and fsworm are managed in units of block. cwfs64x の場合には 1 block は 16KB である。 In the case of cwfs64x, 1 block is 16 KB. 以下、block をアドレスで表すこととする。 Hereinafter, block is represented by an address. ba[0]は 最初の block をba[1]は第2プロックを意味する。 ba[0] means the first block and ba[1] means the second block. 共に、先頭の 2 block は特殊である。 Together, the first two blocks are special. block のアドレスは 8 B のデータで指定される。 The address of block is specified by 8 B data. プログラムの中ではデータ型がOffで示されている。 In the program, the data type is indicated by Off .

fscache の場合には、 ba[0]には config 情報が置かれている。 In the case of fscache, ba[0] contains config information. ba[1]は使われていないようである。 ba[1] seems not to be used.
fsworm の場合にも先頭の 2 block が使用されている気配はない。 In the case of fsworm, there is no indication that the first 2 blocks are used.

どの block もTagを持っている。 Each block has Tag . もっとも、全ての block がフォーマットされているのではない注1 However, not all the blocks are formatted.

Tag の大きさは、cwfs64x の場合には 12B であり、block の末尾に置かれる。 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 struct Tag
{ {
	short pad; /* make tag end at a long boundary */ short pad; / * make tag end at a long boundary * /
	short tag; short tag;
	Off path; Off path;
}; };

padの値は 0 である。 The value of pad is 0. tagが block の種類を表している。 tag indicates the type of block. pathの値に関する考え方はtag毎に異なる。 path way of thinking about the value of path is different for each tag .

16KB からTagの 12B を除く領域がデータ領域(以下、Data で表す)であり、block の種類毎の構造を持っている。 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 block = Data + Tag
である。 .

注1: 最近の HD は容量が大きい。 Note 1: Recent HD has large capacity. もしも全ての block をフォーマットすると膨大な時間を要する。 Formatting all the blocks takes a huge amount of time. さらに言えば、WORM デバイスはフォーマットすれば書き込めなくなる! In addition, the WORM device can not write if formatted!

dump stack dump stack

2013/02/28 2013/02/28

dump を繰り返すと、fsworm には、ダンプしたデータが積み重ねられる。 When dump is repeated, dumped data is stacked on fsworm. データは決して上書きされることはない。 Data will never be overwritten. その様子を図3(左)に示す。 The situation is shown in Fig. 3 (left).

注意: あなたのブラウザは SVG をサポートしていません。 Note: Your browser does not support SVG. 最新のブラウザをお使いください。 Please use the latest browser.
図3. dump Figure 3. dump

以下、block address nの block をba[n]で表す。 Hereinafter, the block of block address n is represented by ba[n] . ba[0]ba[1]は使われていない。 ba[0] and ba[1] are not used. cwfs が実行されると、最初に 3 つの block When cwfs is executed, first three blocks

  ba[2]: super block ba [2]: super block
	ba[3]: cfs root block ba [3]: cfs root block
	ba[4]: dump root block ba [4]: ​​dump root block
が作られる。 Is made. この中には fscache の中に含まれるファイルの情報は含まれていない。 It does not contain information on files included in fscache.
注意: “cfs root block” とか “dump root block” とかの言葉は正式なドキュメントやプログラムコードの中には現れない。 Note: The words "cfs root block" or "dump root block" do not appear in formal documents or program code. “cfs root address” と “dump root address” は現れる。 "Cfs root address" and "dump root address" appear.

dump 毎に block が積み上げられる。 Blocks are stacked for each dump. 1回の dump で積み上げられる block を単に dump と呼ぶ事にする。 We call the block that is stacked with one dump simply as dump. 1つの dump の中には必ず3つの block, “super block”, “cfs root block”, “dump root block” が含まれる。 One dump always includes three blocks, "super block", "cfs root block", "dump root block". 図3(右)には、dump の内部構造が示されている。 Figure 3 (right) shows the internal structure of dump.

super block と cfs root block の間の block には、fscache の内容が(前回の 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).

cfs root block と dump root block の間の block には、dump された年月日の情報が含まれる。 The block between the cfs root block and the dump root block contains information on the dumped date. 必要な block 数は dump の回数に依存する。 The required number of blocks depends on the number of dumps.

Super Block Super Block

fsworm の構造を捉える上で、もっとも基本的なのは super block である。 The most basic thing to capture the structure of fsworm is super block. super block のtagTsuper (=1) である。 The tag of super block is Tsuper (= 1). cwfs のコードを読むと、super block のTagの中のpathは、 QPSUPER (=2) となっている。 When we read the code of cwfs, the path the Tag of super block is QPSUPER (= 2).

super block は、fscache をダンプした時に 1 つ作られる。 One super block is created when you dump fscache. まず super block が fsworm に書き込まれ、続いてデータの本体が block 単位に書き込まれる(図3右)。 First, super block is written to fsworm, then the body of the data is written block by block (right in Figure 3).

super block の構造は The structure of super block

 struct Superb struct Superb
{ {
	Fbuf fbuf; Fbuf fbuf;
	Super1; Super 1;
}; };

を持つ。 have.

Fbufは free block のアドレスの配列を内部に保有している。 Fbuf has an array of addresses of free blocks inside. free block に関する解説は後回しにする。 I will postpone commentary on free block.

Super1が重要である。 Super1 is important.

 struct Super1 struct Super 1
{ {
	Off fstart; Off fstart;
	Off fsize; Off fsize;
	Off tfree; Off tfree;
	Off qidgen; /* generator for unique ids */ Off qidgen; / * generator for unique ids * /
	/* / *
	 * Stuff for WWC device * Stuff for WWC device
	 */ * /
	Off cwraddr; /* cfs root addr */ Off cwraddr; / * cfs root addr * /
	Off roraddr; /* dump root addr */ Off roraddr; / * dump root addr * /
	Off last; /* last super block addr */ Off last; / * last super block addr * /
	Off next; /* next super block addr */ Off next; / * next super block addr * /
}; };

図4. Super1 の構造 Figure 4. Structure of Super1

ここで分かるように、各々の super block は、次の super block のアドレス( next )を保有している。 As can be seen, each super block has the address ( next ) of the next super block. そして 最初の super block はba[2]から始まる。 And the first super block starts with ba[2] . 従ってba[2]から順に super block を辿れば、次にダンプされるアドレズが分かることになる。 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: super blocks:
2 2
5 Five
69908 69908
85793 85793
104695 104695
222009 222009
... ...
1751346 1751346
1754278 1754278
1754381 1754381
1754569 1754569
1754642 1754642
1755217 1755217
1755393 1755393

最後の1755393は、次に作られる予定の super block アドレスである。 The last 1755393 is the super block address to be made next. ba[1755217]の中のSuper1の内容は(例えば)次のようなものである。 The contents of Super1 ba[1755217] are (for example) as follows.

 super1 fstart: 2 super1 fstart: 2
super1 fsize: 1755394 super1 fsize: 1755394
super1 tfree: 92 super1 tfree: 92
super1 qidgen: 6d76e super1 qidgen: 6d76e
super1 cwraddr: 1755389 super1 cwraddr: 1755389
super1 roraddr: 1755392 super1 roraddr: 1755392
super1 last: 1754642 super1 last: 1754642
super1 next: 1755393 super1 next: 1755393

これらの情報の一部は cwfs のコンソールからも得られる。 Some of these information is also obtained from the cwfs console.

sbaddr 1755217 : 現在の super block (最後に書き込まれた super block) sbaddr 1755217 : current super block (last written super block)
snext 1755393 : 次のダンプ予定のアドレス(つまり、次に作られる予定の super block アドレス) snext 1755393 : The next dump schedule address (that is, the super block address to be created next)
slast 1754642 : sbaddrより一つ手前の super block アドレス slast 1754642 : super block address one before the sbaddr

Directory Entry Block Directory Entry Block

2013/03/02 更新 Updated 2013/03/02

次に基本的なのは directory entry block である。 Next is the directory entry block. この block のTag.tagTdirである。 Tag.tag of this block is Tdir . また、 Tag.pathは、親ディレクトリの qid に一致する。 Also, Tag.path matches the Tag.path of the parent directory.

directory entry block には次の directory entry ( Dentry ) が1個以上(cwfs64x の場合、最大62個)含まれている。 The directory entry block contains one or more of the following directory entries (Dentry) (up to 62 in the case of cwfs64x).

 struct Dentry struct Dentry
{ {
	char name[NAMELEN]; char name [NAMELEN];
	Userid uid; Userid uid;
	Userid gid; Userid gid;
	ushort mode; ushort mode;
		#define DALLOC 0x8000 #define DALLOC 0x8000
		#define DDIR 0x4000 #define DDIR 0x4000
		#define DAPND 0x2000 #define DAPND 0x2000
		#define DLOCK 0x1000 #define DLOCK 0x1000
		#define DTMP 0x0800 #define DTMP 0x0800
		#define DREAD 0x4 #define DREAD 0x4
		#define DWRITE 0x2 #define DWRITE 0x2
		#define DEXEC 0x1 #define DEXEC 0x1
	Userid muid; Userid muid;
	Qid9p1 qid; Qid 9 p 1 qid;
	Off size; Off size;
	Off dblock[NDBLOCK]; Off dblock [NDBLOCK];
	Off iblocks[NIBLOCK]; Off iblocks [NIBLOCK];
	long atime; long atime;
	long mtime; long mtime;
}; };

図5. Directory entry Figure 5. Directory entry

ここにはファイルやディレクトリの名前( name )が含まれているので、 Dentryのサイズは許容する名前の長さ( NAMELEN-1 )に依存する。 Since the names of files and directories are included here, the size of NAMELEN-1 depends on the allowable name length ( NAMELEN-1 ).

dump root block は directory entry block の 1 つである。 The dump root block is one of directory entry blocks. 筆者の家庭でのシステムの場合には次のように dump した日付が見える。 In the case of my system at home, you can see the dumped date as follows.

 term% ls /n/dump term% ls / n / dump
/n/dump/2012/0801 / n / dump / 2012/0801
/n/dump/2012/0802 / n / dump / 2012/0802
/n/dump/2012/0804 / n / dump / 2012/0804
/n/dump/2012/0813 / n / dump / 2012/0813
.... ....
/n/dump/2013/0121 / n / dump / 2013/0121
/n/dump/2013/0127 / n / dump / 2013/0127
/n/dump/2013/0128 / n / dump / 2013/0128
/n/dump/2013/0205 / n / dump / 2013/0205
.... ....

最初の行は初めて dump を行った時に(2012年8月1日)生成されている。 The first line is generated for the first time on dump (August 1, 2012).

  ls -l /n/dump/2012/0801 ls - l / n / dump / 2012/0801
を実行すると次のように、この日のファイルにアクセスできる。 You can access the files on this day as follows.
 maia% ls -l /n/dump/2012/0801 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/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/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/68020
d-rwxrwxr-x M 495 sys sys 0 Jul 31 2012 /n/dump/2012/0801/acme 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 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 / 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 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 / 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 / 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 / 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
d-rwxrwxr-x M 495 sys sys 0 Jul 31 2012 /n/dump/2012/0801/sparc64 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 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 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 d-rwxrwxr-x M 495 sys sys 0 Aug 1 2012 / n / dump / 2012/0801 / usr
maia% maia%

図6. ls /n/dump Figure 6. ls / n / dump

dump した年月日情報 ( YYYY/MMDD ) は dump root address と cfs root address の間にある。 The dumped date information ( YYYY/MMDD ) is between dump root address and cfs root address. (図3) (Figure 3)

このケースでは次の図7に示すように block が繋がっている。 In this case, blocks are connected as shown in the next figure 7.

注意: あなたのブラウザは SVG をサポートしていません。 Note: Your browser does not support SVG. 最新のブラウザをお使いください。 Please use the latest browser.
図7. directory entry block の繋がり Figure 7. Connection of directory entry block

長方形が1つのブロックを表している。 A rectangle represents one block. この図ではどれも directory entry block である。 In this figure, none is a directory entry block. dump の回数がまだ少ないので、2013年の月日の情報は1個の directory entry block で間に合っているが、そのうちに複数の 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.

Plan9 では図5のDentry構造体を見れば分かるように、directory の名前と、mode などの情報が同じ block に同居している。 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. 他方 UNIX では mode などの情報は、inode に置かれ、名前の一覧とは別の block になっている(図8)。 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). この違いの起源は UNIX では hard link のサポートのために、link counter を名前とは別の block (具体的には inode) に持たなくてはならないからだと思える。 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.

注意: あなたのブラウザは SVG をサポートしていません。 Note: Your browser does not support SVG. 最新のブラウザをお使いください。 Please use the latest browser.
図8. unix inode の概念図で contents と書いたのは、file の中身であったり、他の directory であったりする。 Figure 8. In the conceptual diagram of unix inode, we write contents as contents of file or other directory.

DentryQid9p1構造体は Qid9p1 's Qid9p1 structure

 struct Qid9p1 struct Qid 9 p 1
{ {
	Off path; /* was long */ Off path; / * was long * /
	ulong version; /* should be Off */ ulong version; / * should be Off * /
}; };

であるが、このpathは、 modeがディレクトリの場合(つまりmode&DDIR != 0の場合)には先頭ビットに 1 が立てられている。 However, this path is set to 1 in the first bit when mode is a directory (that is, when mode&DDIR != 0 ). (このように設計した理由に関しては僕は今のところ解らない。) 正式な qid、すなわち、コマンド (I'm not sure about the reason why I designed this way.) The official qid, ie the command

  ls -ql ls - ql
で表示される qid は、このqid.pathの先頭ビットを落としたもの、すなわちqid.path&~DDIRである。 The qid displayed is the one with the first bit of this qid.path , that is, qid.path&~DDIR .

cwfs64x の場合、1つのDentryは 260 B である。 In the case of cwfs 64 x, one Dentry is 260 B. 従って、1つの block には最大 62 個のDentryを保持できる。 Therefore, one block can hold up to 62 Dentry .

nameには、ファイル名やディレクトリ名が入る。 name contains the file name and directory name. NAMELENは cwfs64x の場合には 144 である。 NAMELEN is 144 in the case of cwfs NAMELEN x. 名前は'\0'で終わるので、名前の最大長は 143 文字である。 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 )、ファイルコンテンツの置かれている block は direct block ( dblock[NDBLOCK] ) と indirect block ( iblocks[NIBLOCK] ) を基に辿る事ができる。 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] ). ファイルコンテンツを含む block はTfileでタグ付けられている。 The block containing the file contents is tagged with Tfile .

Dentryがディレクトリの場合( mode&DDIR != 0 )には、そのディレクトリコンテンツ(中に含まれているファイルやディレクトリの情報)の置かれている block は、ファイルの場合と同様に、direct block ( dblock[NDBLOCK] ) と indirect block ( iblocks[NIBLOCK] ) を基に辿る事ができる。 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] ). ディレクトリコンテンツを含む block はTdirでタグ付けられている。 The block containing the directory contents is tagged with Tdir .

cwfs64x の場合にはNDBLOCKの値は 6、 NIBLOCKの値は 4 である。 In the case of NDBLOCK the value of NDBLOCK is 6 and the value of NIBLOCK is 4.

6 個の direct block には、データが直接書かれる。 Data is directly written to 6 direct blocks. 1つの direct block には 16*1024 - 12 B のデータが書き込めるので、6 個の direct block には合計 6*(16*1024 - 12) B のデータを書き込める。 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. ディレクトリの場合には 372(=62*6)個までのDentryが扱える事となる。 In the case of a directory, up to 372 (= 62 * 6) Dentry can be handled.

Indirect Block Indirect Block

directory entry block のDentry構造体に含まれるiblocks[0]によって示される block には、 For the block indicated by iblocks[0] included in the iblocks[0] structure of the directory entry block,

  (16*1024 - 12)/8 = 2046 (16 * 1024 - 12) / 8 = 2046
個の block アドレスが含まれる。 Block addresses. ここの 8 は 1 個の block アドレスの大きさである。 Here, 8 is the size of one block address. ) これらの block アドレスは、データの場所(つまり direct block)を示している。 ) These block addresses indicate the location of the data (ie direct block). 従って Therefore
  2046 * (16*1024 - 12) = 33497112 B 2046 * (16 * 1024 - 12) = 33497112 B
のデータを書き込める。 Can be written. このような block 情報を 1 次の indirect block と言うこととしよう。 Let's say that such block information is the primary indirect block.

iblocks[1]には、2 次の indirect block が書かれる。 iblocks[1] , a secondary indirect block is written. つまり、この block には block アドレスが書かれているのであるが、それらのアドレスは(データの場所ではなく) 1 次の indirect block アドレスである。 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 2046 * 2046 * (16 * 1024 - 12) = 68535091152 B
のデータを書き込める。 Can be written.

同様に、 iblocks[2]には Likewise, iblocks[2] has

  2046 * 2046 * 2046 * (16*1024 - 12) = 140222796496992 B 2046 * 2046 * 2046 * (16 * 1024 - 12) = 140222796496992 B
そしてiblocks[3]には And iblocks[3] has
  2046 * 2046 * 2046 *2046 * (16*1024 - 12) = 286895841632845632 B 2046 * 2046 * 2046 * 2046 * (16 * 1024 - 12) = 286895841632845632 B
となる。 .

indirect block のタグは The tag of indirect block

  iblocks[0] Tind1 iblocks [0] Tind 1
	iblocks[1] Tind2 iblocks [1] Tind 2
	iblocks[2] Tind3 iblocks [2] Tind 3
	iblocks[3] Tind4 iblocks [3] Tind 4
となっている。 . また、これらのTag.pathはどれも親ディレクトリの qid に一致する。 Also, any of these Tag.paths matches the qid of the parent directory.

File Block File Block

ファイルの内容を含む block はTfileのタグが付けられている。 The block containing the contents of the file is tagged with Tfile . この block のTag.pathは、このファイルが属するディレクトリの qid に一致する。 Tag.path of this block matches the qid of the directory to which this file belongs.

1つの file block には、最大 One file block has a maximum

  16*1024 - 12 B 16 * 1024 - 12 B
のファイルデータを保存できる。 File data can be saved.

ファイルの内容は block 単位で管理されている。 The contents of the file are managed in block unit. ファイルの内容が更新された時には全ての block が書き換えられるのだろうか? 筆者の実験によると否である。 Will all blocks be rewritten when the contents of the file is updated? According to my experiment, it is not. 1ブロックよりも大きなファイルの末尾にデータを追加すると、最後の block だけが更新される。 If you add data to the end of a file larger than one block, only the last block is updated. 他の block は、そのまま利用される。 Other blocks are used as they are. もっとも、この実験は However, this experiment
(a) ファイルに append 属性を指定している (a) The append attribute is specified in the file
(b) ファイルの末尾に seek して書き込んでいるのいずれかの条件の下で実験している。 (b) writing at the end of the file by seeking at the end of the experiment under either condition.

16KB を超える大きなファイルをテキストエディタで開いて、末尾にデータを追加した場合には、完全に書き換えられると思う。 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 ...)

書き換えられた block だけが新たに生成される cwfs の特性は、特にサーバで重要である。 Characteristics of cwfs in which only rewritten blocks are newly generated is particularly important in servers. 筆者のサーバではウェブのサーバのログファイルは 1.7GB にも上る。 On my server, the log file of web server is 1.7 GB.

  1757143424 Oct 18 17:13 http 1757143424 Oct 18 17: 13 http
この大きさのファイルのコピーを毎日作り続けるわけには行かないであろう注1 It will not go on to keep copying files of this size every day1.

注1: Mac/OSX の TimeMachine や Linux の pdumpfs では、ファイルが更新されていれば、そのコピーが新たに作られていく。 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. ハードリンクだけで TimeMachine の機能を実現しようとすれば、コピーは不可避な仕様になるはずである。 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. データベースファイルの場合には、cwfs と言えども日々の dump から外さなくてはならないだろう。 In the case of database files, even cwfs should be removed from daily dump. トランザクションのログを採る方が安全である。 It is safer to log transactions.

Fsworm Root Fsworm Root

2013/03/09 2013/03/09

fsworm の全ての情報は dump stack のトップにある dump root block から辿る事ができる。 All information on fsworm can be traced from the dump root block at the top of the dump stack. このアドレスは cwfs console のroaddrから知ることができる。 You can find out this address from roaddr of cwfs console. 図6および図7は、ここから辿って見えるパスの最初の部分である。 Figures 6 and 7 are the first part of the path seen from here.

実はroaddrは fscache が管理している root block であるが、fsworm の dump root block と一致している。 Actually roaddr is a root block managed by fscache, but it matches dump root block of fsworm.

ダンプの順序 Dump order

ダンプは現在の fscache に基づいて行われる。 The dump is done based on the current fscache. そして、まず最初に super block が fsworm に書き込まれる。 First, super block is written to fsworm. これに続いて、ディレクトリツリーの末端の情報から順に書き込まれる。 Following this, the information at the end of the directory tree is written in order. 従って、fsworm の中に、例えば Thus, in fsworm, for example

  /2012/0925/.... / 2012/0925 / ....
が作成される場合には、一番最後に /、その前に2012 、さらにその前に0925が... Is created, the last / before 2012 , before 0925 before that ...

qid qid

ユーザからは ls command に q option を添えてファイルやディレクトリの 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 maia% ls - ql
(000000000009baa2 6 00) --rw-rw-r-- M 326 web web 33597 Mar 8 15:01 bucket.png (000000000009 baa2 6 00) - rw - rw - r - M 326 web web 33597 Mar 8 15: 01 bucket.png
(000000000009baa3 3 00) --rw-rw-r-- M 326 web web 13693 Mar 8 15:02 bucket.svg (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 (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 (0000000000089b8d 2 00) - rw - rw - r - M 326 arisawa web 2401 Oct 15 21:21 cwfs.svg
... ...
maia% maia%
のように表示される。 As shown in FIG. 先頭の ( ) の中の 16 進数表示の部分が qid であり、その次の数字が qid version である。 The part of hexadecimal notation in the head () is qid, and the next digit is qid version.
マニュアルによると qid はfile system の中でユニークであると言う。 According to the manual qid is unique within the file system.

ユニークであるならば、qid が管理されなくてはならない。 If it is unique, the qid must be managed. super block の中の qidgen が、そのためにあると思える(図4)。 It seems that qidgen in super block is there for that (Figure 4).

実験をして見れば分かるが qid はファイル名の変更によっては変わらない。 You can tell by experimenting but qid does not change by changing file name. 内容が変わると version が変わる。 Version changes when content changes.
そうであるから、エディタを作る場合には、保存時に他の何かによって変更を受けたか否かを知るために使えるのであるが、time stamp の方が手軽なので僕はこれまでに qid を利用した事は無い。 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. (なお unix の qid は、違うものらしい) (The qid of unix seems to be different)

fsworm や fscache の中を除くと、qid とその version は directory entry の中に含まれ(図5)、その contents に関する block が同じ qid となっていることが分かる。 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. つまり block の所属を確認するために使われていると思われる。 That is, it seems to be used to confirm the affiliation of block.

fscache の構造 Structure of fscache

  ba[0] config ba [0] config
	ba[1] - ba [1] -
	ba[2] Tcache ba [2] Tcache

  ba[maddr] map ba [maddr] map
	... ...
	ba[caddr] cache ba [caddr] cache
	... ...

Config Block Config Block

2013/03/05 2013/03/05

cwfs64x を見る限り、筆者の config block ( ba[0] ) には、テキスト形式で次のようなデータが先頭から書き込まれていた。 As far as cwfs64x is concerned, the following data was written in the text format from the beginning in my config block ( ba[0] ). (この内容は cwfs console の printconf コマンドでも見える) (This content can also be seen with the printconf command of cwfs console)

 service cwfs service cwfs
filsys main c(/dev/sdC0/fscache)(/dev/sdC0/fsworm) filsys main c (/ dev / sdC 0 / fscache) (/ dev / sdC 0 / fsworm)
filsys dump o filsys dump o
filsys other (/dev/sdC0/other) filsys other (/ dev / sdC 0 / other)
noauth noauth
newcache newcache
blocksize 16384 blocksize 16384
daddrbits 64 daddrbits 64
indirblks 4 indirblks 4
dirblks 6 dirblks 6
namelen 144 namelen 144

noauthは、認証をしないで cwfs へのアクセスを許す事を意味している。 noauth means allowing access to cwfs without authentication. noauthは安全な環境での実験レベルでしか許されない特殊な設定である事に注意すべきである。 noauth should be noted that noauth is a special setting only allowed at the experimental level in a secure environment.
大学で使っているのは、今年の2月の版であり、これはnoauthにはなっていない。 What I use at university is the February version of this year, which is not noauth . (2013/04/10) (2013/04/10)

さらに、この block は次のように tag 付けられている。 In addition, this block is tagged as follows.

  pad: 0000 pad: 0000
	tag: 10 (Tconfig) tag: 10 (Tconfig)
	path: 0 path: 0

ソースコードには、次の構造化データがある。 The source code has the following structured data.

 struct Conf struct Conf
{ {
	ulong nmach; /* processors */ ulong nmach; / * processors * /
	ulong nuid; /* distinct uids */ ulong nuid; / * distinct uids * /
	ulong nserve; /* server processes */ ulong nserve; / * server processes * /
	ulong nfile; /* number of fid -- system wide */ ulong nfile; / * number of fid - system wide * /
	ulong nwpath; /* number of active paths, derived from nfile */ ulong nwpath; / * number of active paths, derived from nfile * /
	ulong gidspace; /* space for gid names -- derived from nuid */ ulong gidspace; / * space for gid names - derived from nuid * /

	ulong nlgmsg; /* number of large message buffers */ ulong nlgmsg; / * number of large message buffers * /
	ulong nsmmsg; /* number of small message buffers */ ulong nsmmsg; / * number of small message buffers * /

	Off recovcw; /* recover addresses */ Off recovcw; / * recover addresses * /
	Off recovro; Off recovro;
	Off firstsb; Off firstsb;
	Off recovsb; Off recovsb;

	ulong configfirst; /* configure before starting normal operation */ ulong configfirst; / * configure before starting normal operation * /
	char *confdev; char * confdev;
	char *devmap; /* name of config->file device mapping file */ char * devmap; / * name of config-> file device mapping file * /

	uchar nodump; /* no periodic dumps */ uchar nodump; / * no periodic dumps * /
	uchar dumpreread; /* read and compare in dump copy */ uchar dumpreread; / * read and compare in dump copy * /
	uchar newcache; uchar newcache;
}; };

この中のデータは、初期化過程の中で、cwfs の種類毎に(ソースコードの中で)与えられている。 Data in this is given (in the source code) for each type of cwfs during the initialization process.

Tcache Block Tcache Block

Tcache block は cwfs に関する基本情報を管理している。 Tcache block manages basic information about cwfs. この内容は cwfs コンソールで見ることができる。 You can see this in the cwfs console.

 struct Cache struct Cache
{ {
	Off maddr; /* cache map addr */ Off maddr; / * cache map addr * /
	Off msize; /* cache map size in buckets */ Off msize; / * cache map size in buckets * /
	Off caddr; /* cache addr */ Off caddr; / * cache addr * /
	Off csize; /* cache size */ Off csize; / * cache size * /
	Off fsize; /* current size of worm */ Off fsize; / * current size of worm * /
	Off wsize; /* max size of the worm */ Off wsize; / * max size of the worm * /
	Off wmax; /* highwater write */ Off wmax; / * highwater write * /

	Off sbaddr; /* super block addr */ Off sbaddr; / * super block addr * /
	Off cwraddr; /* cw root addr */ Off cwraddr; / * cw root addr * /
	Off roraddr; /* dump root addr */ Off roraddr; / * dump root addr * /

	Timet toytime; /* somewhere convienent */ Timet toytime; / * somewhere convienent * /
	Timet time; Timet time;
}; };

fscache の各ブロックはメモリーにキャッシュされている。 Each block of fscache is cached in memory. 10秒毎にメモリーのキャッシュは、(更新があれば) fscache に書き込まれる。 Every ten seconds the cache of memory is written to fscache (if there is an update).

Mapping Mapping

2013/03/08 更新 Updated 2013/03/08

fsworm の各 block は、図9の cache area の cache block に mapping される。 Each block of fsworm is mapped to the cache block of the cache area of ​​FIG.

fscache の cache block のアドレスをcbaとするとcba Let cba be the cache block address of cba , cba

  caddr <= cba < caddr + csize caddr <= cba <caddr + csize
の範囲にある。 . fsworm の 0 からwsizeの block が fscache のこの領域に map される。 A block of fsworm 0 to wsize is mapped to this area of ​​fscache.

cache block の総数は(cwfs コンソールでは) csizeで表示されている。 The total number of cache blocks is indicated by csize (in the cwfs console). caddrから始まる、残りの全ての block が cache block ではない事に注意する。 caddr all remaining caddr starting with caddr are not cache blocks.

筆者のシステムの例では fsworm の block 数は 6972701 であるのに対して、fscache の cache block 数は 1392255 である。 In the example of my system, the number of blocks of fsworm is 6972701, whereas the number of cache blocks of fscache is 1392255. 従って 1/5 程度のキャッシュ能力を持っている。 Therefore, it has about 1/5 cache capacity. また、fscache には 1394540 個の block が採れるが、実際に使われているのは、1035+1392255(=1393290) に過ぎない。 Also, 13604540 blocks can be taken in fscache, but only 1035 + 1392255 (= 1393290) are actually used. 未使用領域は 0.1% 程度である。 The unused area is about 0.1%.

単純に考えると表1に示すような mapping を思い浮かべるかも知れない。 Just thinking about it might think of mapping as shown in Table 1.

注意: あなたのブラウザは SVG をサポートしていません。 Note: Your browser does not support SVG. 最新のブラウザをお使いください。 Please use the latest browser.
表1. a simple but problematic mapping from fsworm to cache Table 1. a simple but problematic mapping from fsworm to cache

ここに、cache と書いたのは fscache の cache area である。 Here, cache is written in fscache's cache area. 示されている address はcaddrから数えている。 The address shown is counted from caddr .

しかし、この mapping は問題を孕んでいる。 However, this mapping suffers from problems. ある fsworm block が cache されていると、同じ cache block に map される他の fsworm block が cache に入り込めない場合がある。 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.

そこで cwfs では、間に bucket をかませて、mapping に柔軟性を持たせている。 So cwfs keeps bucket in between, giving flexibility to mapping. その様子を表2に示す。 The situation is shown in Table 2.

注意: あなたのブラウザは SVG をサポートしていません。 Note: Your browser does not support SVG. 最新のブラウザをお使いください。 Please use the latest browser.
表2. real mapping implementation of cwfs. Table 2. real mapping implementation of cwfs.

説明を容易にするために fsworm の block address をwaとし、 caddrから数えた cache の address をcaとする。 For ease of explanation, block address of fsworm is set to wa and cache address counted from caddr to ca wa%msizeが同一のwaca%msizecaのどれかに map されると考えるのである。 wa%msize that wa%msize with the same wa%msize is ca%msize to ca of ca%msize . 実際の mapping の状態は fscache の map block にある bucket によって管理されている。 The state of actual mapping is managed by bucket in map block of fscache.

bucket bucket

fscache のmaddrからcaddrまでの block は map block で、その tag はTbuckである。 A block from caddr to caddr in maddr is a map block, and its tag is Tbuck . map block は bucket の集まりで、bucket には cache の状態と、対応する fsworm の block address が含まれている。 The map block is a collection of buckets, and the bucket contains the state of cache and the block address of the corresponding fsworm.

各 bucket は次の構造を持っている。 Each bucket has the following structure.

 struct Bucket struct Bucket
{ {
	long agegen; /* generator for ages in this bkt */ long agegen; / * generator for ages in this bkt * /
	Centry entry[CEPERBK]; Centry entry [CEPERBK];
}; };

各 map block は最大BKPERBLK (=10) 個の bucket を保有できる。 Each map block can hold up to BKPERBLK (= 10) BKPERBLK .

注意: あなたのブラウザは SVG をサポートしていません。 Note: Your browser does not support SVG. 最新のブラウザをお使いください。 Please use the latest browser.
図9. fscache の構造 (cwfs64x) Figure 9. Structure of fscache (cwfs64x)

fscache に含まれる bucket の総数はmsizeで与えられている。 The total number of msize included in msize is given by msize . 以下、bucket に block address の小さい方から順に 0 からmsize - 1 までの番号を付け、それを bucket address と言う。 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 cache entry

各 bucket はCEPERBK (=135) 個の Cache Entry を持っている。 Each bucket has CEPERBK (= 135) Cache Entries. 各 Cache Entry は、現在のマップの状態を表している。 Each Cache Entry represents the state of the current map.

 struct Centry struct Centry
{ {
	ushort age; ushort age;
	short state; short state;
	Off waddr; /* worm addr */ Off waddr; / * worm addr * /
}; };

fsworm の block address baから、対応する fscache の block address cbaを見つけるには、まず In order to find the block address cba of the corresponding fscache from the block address ba cba , first

  bn = ba % msize bn = ba% msize
を計算する。 . そしてbucket[bn]の中の 135個の cache entry のwaddrを調べる。 Then check the waddr of 135 cache entries in bucket[bn] . もしも、fsworm の block address baの block が cache されていれば、その中にbaと一致するものが存在するはずである。 If the block of block address ba of fsworm is cached, there should be some matching ba it. この cache entry をentry[ce]とすると、 Letting this cache entry be entry[ce]
  cba = msize*ce+bn+caddr cba = msize * ce + bn + caddr
で求める事ができる。 Can be obtained with. 詳しくは「Map from Worm to Cache」で解説する。 Details are explained in "Map from Worm to Cache".

逆に、現在 cache されている fscache の block address cbaから fsworm の block address baを求めるには、まず 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 bn = (cba - caddr)% msize # bucket addr
	ce = (cba - caddr) / msize # entry addr ce = (cba - caddr) / msize # entry addr
を計算すれば bucket address bnが求まるので、その中の cache entry cewaddrを見ればよい。 The bucket address bn can be found by looking up the waddr of the cache entry ce in it.

fscache の cache area の block は cache entry によって「状態」を保有していることになる。 The cache area block of fscache has "state" by cache entry. 以下、cache block の状態は◯◯であるとか、cache block に対応する worm address は◯◯であるとか言う事にする。 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

ageは、cache block の古さを表している。 age represents the age of the cache block. 小さい値が古い。 Small values ​​are old. だから概念的には age と言うよりも birth day に近い。 So it is conceptually close to birth day rather than age. 新たに cache する必要が発生した場合には、( Cnoneが存在しない場合には) ageの小さい cache が優先的に捨てられる。 When it becomes necessary to cache newly, the small cache of age is preferentially discarded (when Cnone does not exist). そして bucket のagegenの値が新たに割り当てるageの値となる。 And the value of agegen of bucket becomes the value of age be newly allocated. cache にデータが割り当てられればagegenが 1 つ増加する。 If data is allocated to cache, agegen increases by 1. ageの最大値MAXAGE=10000が存在する。 The maximum value MAXAGE=10000 age exists. それを超えた時には、 ageの再割当が必要になるはずであるが、詳細はコードをよく読んでいないのでわからない。 When it exceeds it, reallocation of age is necessary, but details are not understood because I have not read the code well.

state state

cache の state とは、対応するCentryの状態で、次の値を持つ。 The cache state is the state of the corresponding Centry and has the following values.

  Cnone = 0 Cnone = 0
	Cdirty = 1 Cdirty = 1
	Cdump = 2 Cdump = 2
	Cread = 3 Cread = 3
	Cwrite = 4 Cwrite = 4
	Cdump1 = 5 Cdump 1 = 5

cache されていない cache block の状態はCnoneになっている。 The state of an Cnone cache block is Cnone to Cnone . 僕の観察では、この場合のwaddrはゴミであり意味を持っていないように思える。 In my observation, waddr in this case seems to be garbage and has no meaning.

worm からデータを読み取った cache の場合には、 waddrは元の worm の address そのものである。 In the case of cache which reads data from worm, waddr is the address itself of the original worm. cache の状態はCreadになっている。 The state of cache is Cread . この場合には cache block の内容は対応する fsworm の block と同じである。 In this case the contents of the cache block are the same as the corresponding block of fsworm. (キャッシュであるから当然の事) (Naturally because it is a cache)

既存の directory や file が変更を受けると、その cache のCreadのタグがCwriteに変化する。 When an existing directory or file is changed, the Cread tag of that cache changes to Cwrite . そしてwaddrは変更を受けない。 And waddr is not changed. もちろん dump 時に上書きするわけには行かないのだから、その時には新しい worm address に保存され、同時に cache entry の中のwaddrも更新されるはずである。 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. 異常なく dump されると状態はCreadになるであろう。 If abnormally dumped, the state will be Cread .

新たに directory や file を作成した場合には、その cache block に対応するwbaには worm の未使用の address が割り当てられる。 When creating a new directory or file, wba corresponding to that cache block is assigned an unused address of worm. 状態はCdirtyになる。 The state is Cdirty . dump が完了するとCreadになっているはずである。 When dump is completed it should be Cread .

状態CnoneCreadの cache は、 waddrに変更を反映させる必要は無い。 The cache of the state Cnone and Cread does not need to reflect the change in waddr . 従って、このCentryに対応する fscache の block は(必要に応じて)捨てても構わないことを意味している。 Therefore, it means that the block of fscache corresponding to this Centry may be discarded (if necessary).

ところで cwfs コンソールのstatwコマンドを実行した時の By the way, when you run the cwfs console statw command

  8600 none 8600 none
		230005 dirty 230005 dirty
		     0 dump 0 dump
	       1153555 read 1153555 read
		    95 write 95 write
		     0 dump1 0 dump1
ではCentryを直接調べて、 stateの値の分布(個数)を表示している。 We examine Centry directly and display the distribution (number) of values ​​of state .

free block and dirty block free block and dirty block

2013/03/11 2013/03/11
2013/03/14 改訂 2013/03/14 revision
2013/03/29 訂正 2013/03/29 Correction
2013/04/10 追加 2013/04/10 added

次のように分類するのが良い。 It is better to classify as follows.
(a) unwritten block (a) unwritten block
(b) dirty block (b) dirty block
(c) free block (c) free block

(a) の unwritten block とは dumped area の中に存在する、未書き込みの block。 The unwritten block in (a) is an unwritten block existing in the dumped area.
(b) の dirty block とは fscache の中で Cdirty とされている block。 The dirty block in (b) is a block which is called Cdirty in fscache. cwfs は、新たに file や directory を作成する時に、cache に worm の address を対応付け、cache の block の状態をCdirtyとする。 When cwfs creates a new file or directory, it associates worm's address with cache, and Cdirty cache's state to Cdirty . この worm address は未使用アドレスであり、unwritten block が使えるなら、それを使う。 This worm address is an unused address, and if unwritten block is available, use it.
dump 直後には Immediately after dump

  (a) ⊇ (b) (a) ⊇ (b)
である。 .
(c) の free block とは dirty block のうち、fscache に free block として登録されている block。 (c) free block is a block that is registered as a free block in fscache among dirty blocks. これらは file tree に link されていない。 They are not linked to the file tree. link されている dirty block は dump の対象となるが、link から外れた block は dump されない。 Linked dirty blocks are subject to dump, but blocks deviated from link are not dumped.cwfs rather than discard them as garbage, to use when creating a new dirty block.
cwfs has a list of free block. free block list is and in the supper block, the fscache Tfreeexist to block the attached tag in. supper block and Tfreethe block can hold 2037 pieces of block address information.
 (b) ⊇ (c)
である。 .

block of the state of Cwrite of fscache is, address is determined for the first time dump destination when it is actually dump is. These address are stacked on top of the last of the dump. The block status of the other Cdirty, is associated with the address of the time being Fsworm.

The first place do not do it skillfully so as not to occur, such as free block? I think many, but it is quite difficult likely. Deleting a file or directory is a problem. dump is trying to be made to the five o'clock in the morning every day. And made into new some of the directory and file in the daytime of work. They C1, C2, ..., Cn and. These block in the fscache is none Cdirtyplaced in a state of, is associated with the address of fsworm. Some of these will also be deleted on the same day. Deleted things D1, D2, ..., Dm and. C1, C2, ..., Cn from D1, D2, ..., Dm is the subtraction portion is being dump, that address of fsworm generated by dump is continuous Gataku expect , and to have a "hole". They should be reserved for future use as a free block.

Of course, the deleted file or directory is immediately deleted from the entry of the parent directory, the state of the contents is Cdirtyis left of.

CdirtyThe problem is often that do not know me still. My fscache is a large amount of Cdirty suffer the block. Apparently, this state seems abnormal. Cause after you delete a large directory in clri command of something? Possible for the cwfs console, that you did not check free command. If you delete a file by rm command, block that are no longer needed, but going into the free block list, apparently it does not enter the case of clri. They are likely to be discarded as not used block.

The super block has a free block list, you can register the 2037 single free block. Address of free block beyond this, Tfreein which is recorded in the block tag Tagged Fscache. Tfreeblock has a free block list in the same way as super block. structure of the free block list is the same both.

super block and Tfreea free block that is included in the Block free[n]( n=0,1,...a). As you follow the source program, free[0]it can be seen that is special. This is Tfreethere because the pointer to the block. Rather, free[0]Address of the corresponding fscache to it Tfreeshould have become block. (Figure 10)

注意: あなたのブラウザは SVG をサポートしていません。 Note: Your browser does not support SVG. 最新のブラウザをお使いください。 Please use the latest browser.
図10. freelist chaine

msize と csize

msizeSome of the pieces of the bucket msize*CEPERBKthere is a number of cache entry. In my case, msizebut since the 10313, this calculation result is 1,392,255. This number is csizeconsistent to.つまり、 In other words,

 csize = msize*CEPERBK
Relationship is established of. One of the Cache Entry is're manages one of the cache block.

msizeTo accommodate the number of bucket is,

Number of block is required. The form of the division is complex, it is because they rounded up. In my case, msizebut since the 10313, this calculation result is 1032. To this maddrwas added a 3, caddrconsistent with the 1035.つまり、 In other words,
 caddr = (msize+BKPERBLK-1)/BKPERBLK + maddr
Relationship is established of.

Map from Worm to Cache

bnThe bucket address, ceand the address of the cache entry in the bucket. bnAnd cein the following range.

 0 <= bn < msize
	0 <= ce < CEPERBK
bnBets cebased on, must be made to correspond to cache block address.
There are two natural way of thinking.
(A) bn*CEPERBK+ce+caddr
(B) msize*ce+bn+caddr
of course other more complex mapping is considered, reason for adopting them does not exist.
And, in fact, the latter method (b) is employed.

The former is difficult to adopt. This is because, files tend to occupy a contiguous block of fsworm. Therefore, if adopting (a), cache information for large files newly created will occupy one bucket. Then the cache block in which the bucket is managed, can not be (dump was not as long as in fsworm) newly cache.

Further in the latter case, if a cache consecutive block of Fsworm, there is to likely to be block consecutive even Fscache. (Seek time of a hard disk can be saved.)

Decision algorithm of msize

msizeWhat calculated in either determined? Is
the total number of map block and cache block mWhen,
a map block npossible in the case of the number mn(= csize) has the value,

It is necessary to meet. つまり、 In other words,
It is necessary to satisfy both, but such nis
Obtained by. すなわち、 That is,
In this way calculated mntooth CEPERBKis not a multiple of guarantee. Therefore it is necessary to make the following correction.
 msize = (mn) / CEPERBK
	csize = msize*CEPERBK
	caddr = (msize + BKPERBLK - 1)/BKPERBLK + maddr
In would be calculated.

Author of fscache is

 1394540 block
It is possible to ensure,
 m = 1394540 - 3 = 1394537
である。 .According to this calculation method
 msize = 10322
	caddr = 1036
	csize = 1393470
Next, caddr + csizeit is 1,394,506. Since this is less than the block number 1394540 of fscache, although the supposed good at this, the value of the actual cwfs is different. In fact, this msizefurther to adjust the
 msize = maxprime(msize - 5) # Ken's value
	csize = msize*CEPERBK
	caddr = (msize + BKPERBLK - 1)/BKPERBLK + maddr
Is set to ( cw.c). Here maxprime(n)is, nis the largest prime number that does not exceed. It is unknown to this or adjustment What Why necessary? Author. (The relationship between fsworm and Fscache, this adjustment should be unnecessary.)

Fscache Root


fsworm is to have a root, fscache also have a root. (Not traced the unless the directory tree have)

address of root block of fscache is based on address of the dump root block of dump stack top of Fsworm, it is determined according to conventional mapping rule.


Restoration (recovery)

2013/02/28 update

cwfs cause is a variety that leads to abnormalities in, but the main case will allo 2 Tsude follows.
(a) a power failure during the write
(b) hardware crash They further but is subdivided in various cases, where it is that fsworm is such a healthy (or similar, there is a backup of fsworm in which) it is assumed that. In this case, it will be reconstructed based on the Fsworm.

Put the following assumptions:

There exists,
In its original, at the start of cwfs (in 9front)
 bootargs is (tcp, il, local!device)[local!/dev/sdC0/fscache]
Since the message out
 local!/dev/sdC0/fscache -c
It was input, then config:against the prompt
 recover main
In it Kotaere. (Restoration is very fast. (1 to 2 seconds?)

fscacheThe first block of, because during the activities of cwfs have been removed from the write-target, as long as the hard disk is not susceptible to physical damage, loss of data can be said to be at most, be limited since the last dump.

all the information needed to restore a fscache from the block address range 0 of fsworm snextare included in the up to. During restoration, it is not necessary to examine all of fsworm. It can be traced from the last record that was dumped. This work should cwfs is done automatically, for reference, the commentary a little more detail the structure of the fsworm.

In Plan9 (or 9front), the state of the past file

 9fs dump
And the execution
See below, all of the information that appears here is the next dump address snextone before the block address of ( = roaddr = snext - 1can be traced easily from).

Program cwstudy to introduce later, specify the block address, to display its contents. The following is an example of executing cwstudy.

 cpu% cwstudy 1755392
tag pad: 0000
Tag: 11 (Tdir)
tag path: 1

name: /
uid: -1
Guide: -1
mode: 0140555
other: 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

The name initially obtained " /is". Creation date, and has a July 31, 2012 fsworm was made. dblock[0]The 1755391is, " /is the address of the directory entry block under".

 cpu% cwstudy 1755391
tag pad: 0000
Tag: 11 (Tdir)
tag path: 1

name: 2012
uid: -1
Guide: -1
mode: 0140555
other: 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 address 1755391name of the directory that is included in 2012it. Of not only one appeared, operationalization of fsworm is 2012is so.

block address 1755390contains a large number of directory entry is in.

 term% cwstudy 1755390
name: 0925
uid: -1
Guide: -1
mode: 0140555
other: 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
Guide: -1
mode: 0140555
other: 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

Their names, represents the month and day that you dump. In addition, they

 ls /n/dump/2012
In matches the name that is displayed.

It goes further, 2012below the 0927can find similarly directory entry of. Their names

 ls /n/dump/2012/0927
In matches the name that is displayed. There are admYa sysYa usrwould appear names such as.

0925The dblock[0]will 1755212is. This block address is included in the block that was dumped on September 25. (On this day 1754642Kara 1755216to have been consumed)

In the dump of September 27, all the files of the day rather than new copy, with respect to the content that has not been changed, use as it is the old content. In this 0925regard, the content of September 25 has been used as is.

Difference method of block units in fsworm is the is being used. (Later also be examined with respect to this matter)

Examined for restoration (recovery)

If fsworm is healthy, the super block snextif traced to, snextcan be restored based on. In the certainty snextor traced for up to?

fsworm will not be a problem if it is true WORM or a new hard disk. snextTo the previous, TagRashiki data is no room for mistakes since it is of no. But what about if the worn-out of the hard disk?
TagCounting on when to follow the super block, the dust Tagmight be misunderstood. of the super block Tagstructure

 struct Tag
{ {
	short pad; /* make tag end at a long boundary */
	short tag;
	Off path;
, And the pad0, tag1, pathis 2. In the garbage, the probability that this 12B is an exact match is 2 -96 in Note 1 , it might be considered as a sufficiently small. After all, fscache and the probability to crash itself, very small, in the server of the life time (or about 5 years?), But if not there.

However, the calculation of these probabilities are based on the assumption that the random data is written. fscache partition of this worn-out of the hard disk, the ones that had been used as previously fscache partition, because the probability of being What about? misidentified I use as it is up to until the percentage of the super block of in fsworm, may not be ignored unknown. Therefore, the better to keep in mind when creating a partition of fscache would be better. (Shifting the start address of the partition a little Toka ...)

In the Tcache block of fscache it is included in the information that can verify the integrity of the last of the super block of fsworm. Therefore, you should not need such a worry in the normal recovery.

Note 1: In fact, tagthe pathbecause they follow only, the probability is 2 -80 is. In order to reduce this probability is, on the other slast, but will also hand to use the information of, it is doubtful whether there is a value of up to there.

What is lost by Recovery


There is what is lost in the free block. Already present in the dump area and free block, a block which has not yet been written. cwfs is, to be written if there is an opportunity to write the data here. Than is trying to effectively use a storage space. 2037 one of the free block is managed by the superblock, this information is not lost because it is in fsworm. But free block list of the portion that exceeds the 2037 one is present in Tfree block of fscache. Tfree block is not copied to fsworm. These are lost in Recovery.

Other Configurations



After all of the current cwfs configuration

 filsys main c(/dev/sdC0/fscache)(/dev/sdC0/fsworm)
Under give up and take a backup of fsworm is extremely difficult, other configuration
 filsys main c(/dev/sdC0/fscache){(/dev/sdC0/fsworm)(/dev/sdD0/fsworm)}
It was decided to adopt.
This is the configuration of the pseudo-RAID1. Device instead of a whole, will handle fsworm partition only to RAID1 wind.
/dev/sdC0/fswormAnd /dev/sdD0/fswormit may be different in size. It is matched to the smaller in that case.
The order of writing, (this case) D0 → C0is read is C0carried out at.

When the change of disk organization, there is a need for preparation.

However, although RAID is the grandiose for me it is use at home ...

We are steadily moving as long as you are using at home. I decided to do in this is also the university server.

fake WORM

According to the Cinap Some of the fake WORM is the case there is a bit map of the written block. In this case, because to use the HDD instead of WORM, it is the possible with a bit map indicating the current use state. configuration of this case is

 filsys main c(/dev/sdC0/fscache)f(/dev/sdC0/fsworm)
となる。 .

With it, use one of the disk is usually, by adding a backup disk seems that it would be capable of processing suitable for the whimsical person like me to take a backup when the opposite of mind.

Creating a fake WORM

My WORM is so normal WORM, if you make a fake WORM is, Aru Te supposed to not go to mean that a copy of the device. And that to be newly constructed, for the sake of safety, it was decided to work on the terminal that was launched in PXE. The local disk, prepare the plan9 partition that make up the future cached fake WORM.

In this under
 cwfs64x -c -f /dev/sdC0/fscache
The execution Note 1 .

Note 1: Using the cwfs of command, Bell-labs version (the original version of Geoff) different in 9front version. Here it is based on the 9front version. In 9front version, such as kfs or fossil, which measure the unification of how to use other file systems and the -f option.

In 9front version -center the config mode in the option. configThe next data input with respect to the prompt.

 service cwfs
filsys main c(/dev/sdC0/fscache)f(/dev/sdC0/fsworm)
filsys dump o
filsys other (/dev/sdC0/other)
ream other
ream main
The above is a one-off.

Next command in the command and the shell level to cwfs console occurs. Here is the command to cwfs console fscons>represented by.

The following operation is safe to perform in a new 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

Note: newuser arisawathe, system of the authors of the system owner is glendainstead arisawais a became so necessary, glendais not required if the remains.

After this is, the author cpdiris early to use.

 cpdir -mvug /root /n/cwfs adm 386 acme cfg cron lib mail rc sys
/rootAt the bottom of the fd, mnt, n, tmp, usris a safe is better to independently confirmed.
In particular, /root/n/under the cwfsshould have seen.


In the case of fakeworm it is displayed in statw of cwfs console wsizebecause, TvirgoBlock begins. Tvirgoblock from the block 0 of fsworm wsizeis represented by a bitmap usage between. The written block bit 1 is erected, the bit of the block that has not been written is zero. Since the top 2 block of fsworm has not been written, the first of the 2 bit of the bitmap is 0.

Since fakeworm the bitmap enters at the end of fsworm, that amount wsizeis reduced.


What did I do that day?


In the case that I thought of as a "wonder that day were you doing?" Is a story, such as modification of the file, not the story of the Toka went to drink.
To enumerate all the files that have changed that day, I think I use on UNIX find command. From a large amount of files, working to find the changed file (although it depends on the amount of file) does not end in a few seconds it takes a lot of time. By the way, in my MacBook me $HOMEit takes about 30 seconds in only search for. (Which is also due to have a quite a lot of file)

 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

To introduce here is the lr command made of me, there is an option that corresponds to find -newer options. To find the files that have changed yesterday with it from among all of the file on the server is as follows.

 term% cpu -h ar
ar% 9fs dump
mounting as arisawa
mounting as arisawa
ar% ls /n/dump/2013|tail -2
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
On this day there is a change in the 33 pieces of the file. Many a log file. In the changed files are also those due to the web of cgi. I'm looking for all the files of the system, but have completed the search in two seconds less than. I is despite have a huge file on the server!

Why it is examined the changes in so fast?

The search atimeis because they are used. atimeAnd is a means of access time. There is no detailed explanation on it more than a look at the manual. (Although the Plan9 of the manual is written and read time, even to write atimeis updated)

Note: lr is
It has been placed in.



When looking at the actual operation, the behavior is different in Plan9 and UNIX (MacOSX and Linux).

In the case of Plan9 is, all of the directory where the file server is present in the route followed to locate the file atimehas been updated. Among the huge directory tree, the way to actually file server on the day that has been designated traced is a very very small. Therefore atime, if to look at, it is possible to reduce the root of the required search significantly.

In UNIX different. File server is the directory in the root traced in order to locate the file atimehas not been updated. Of directories and files that change has actually occurred atimeonly it has been updated. Therefore, atimeto rely on, not be able to locate the update efficiently.

It is shown below in specific examples the difference between atime of Plan9 and UNIX.


 # 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% term%


 # 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


-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


この節は未完成である。 This section is incomplete.


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

[2] Ken Thompson, Geoff Collyer “The 64-bit Standalone Plan 9 File Server”

Original text