フラグメントとは

また、fsck を使うと、

% fsck
(中略)
33527 files, 581040 used, 1491171 free
(17803 frags, 184171 blocks, 0.9% fragmentation)
↑これ

などと表示されますが、これは「どれくらいファイルブロックが分散してしまったか」を表すものではなく、「ディスク領域を有効に使うために、どれくらいファイルブロックを分割しているか」というものを意味しています。この値が高いからと言って、パフォーマンスの低下につながるわけではありません。

http://www.jp.freebsd.org/QandA/HTML/457.html

fsck で表示される fragment って一つのディスクブロック(4, 8kぐらい)をまるごと使わずにフラグメント単位(512 or 1024byteが多い)で利用している割合の表示だったかも知れない(うろ覚えモード)

http://home.jp.freebsd.org/cgi-bin/showmail/FreeBSD-users-jp/20973

fsck だかが出力するフラグメンテーション率は「フラグメントしたファイル/前ファイル数」である.

http://tiki.is.os-omicron.org/tiki.cgi?c=v&p=FedoraJP%CA%D9%B6%AF%B2%F1%2F7

これらのページにある通り、fsck したときの「fragmentation」は、Windowsデフラグの「フラグメンテーション」とは異なる。
以下は、これについて調べたときのメモ。
間違っているところがあるかもしれないので、気づいたら指摘してください。

フラグメントとは?

ブロックサイズ4096バイト、フラグメントサイズ1024バイトのファイルシステムで11000バイトのファイルを格納するには、まずブロック2つを丸ごと使い、さらに残りの2808バイトを格納するために1ブロックを 3072, 1024 と2つのフラグメントに分け、3072 の方を使う。(3072バイトで1つのフラグメントという。これを3つのフラグメントと数える文脈もあるようだ?)


fsck の出力やソースに出てくる frag とは fragment のことらしい。


参考:
Fsck - The UNIX File System Check Program
http://docs.freebsd.org/44doc/smm/03.fsck/paper.pdf
※このドキュメントには、fsck がチェックすること、出力するメッセージの意味が全て書かれている。

ファイルシステムのフラグメントサイズを知るには?

これがそうなのか確信がないが、newfs -N を使うと「fragment size」という値が出てくる。

$ newfs -N /dev/ad0s1d
/dev/ad0s1d: 256.0MB (524288 sectors) block size 16384, fragment size 2048
        using 4 cylinder groups of 64.02MB, 4097 blks, 8256 inodes.
super-block backups (for fsck -b #) at:
 160, 131264, 262368, 393472

ブロックサイズもこれでわかる。
1セクタのサイズは、256MB/524288=512バイトとわかる。
8256 inodes とは???


Linux なら mkfs.ext3 -n。
http://www.atmarkit.co.jp/flinux/rensai/linuxtips/728fixpartition.html

dumpe2fs の方がよさそう。dumpe2fs は BSD の dumpfs と同等らしい。

wikipedia ファイルシステム
http://ja.wikipedia.org/wiki/%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0
によると、FreeBSD が採用している UFS2 は可変ブロックサイズに対応しているそうだが、これについてはよくわからない。

fsck 出力の見方

$ fsck /dev/ad0s1d
5190 files, 29020 used, 97819 free (1211 frags, 12076 blocks, 1.0% fragmentation)

(A)ファイル数, (B)使用中ブロック数?, (C)空きフラグ数+1ブロック中のフラグ数*空きブロック数
(D)空きフラグ数, (E)空きブロック数, (F)空きフラグ数 * 100.0 / データブロック数


(A) ファイル数は "find マウントポイント |wc -l" とほぼ一致するはず。/tmp では完全に一致したが、/var は fsck の出力の方が3多かった。ハードリンクの分は find の方が多くなるだろうし、なぜ?
(B) fsck.h のコメントには使用中ブロック数とあるけど、使用中フラグ数という方が正しい気がする。B / C を計算すると、df の "Capacity" とほぼ一致する。
(C) C = D + 8 * E (ここで 8 = 16384 / 2048 = ブロックサイズ/フラグサイズ)。
(D) これによると 2048 バイト以下の小さなファイル 1211 個をこれらのフラグに収めることができるはず?
(E) これによると 12076*16*1024 バイトのファイルを1個格納できるはず?
(F) データブロックのうち、空きフラグがあるものの割合。

df

df で Used と Avail を足しても 1K-blocks に一致しないのは、8%を MINFREE として使用しているため。
これによって fragmentation をある程度回避している。
http://home.jp.freebsd.org/cgi-bin/showmail/FreeBSD-users-jp/20966

$ df |awk '{printf("%7d %s\n", $2-($3+$4),$0)}'
      1 Filesystem  1K-blocks     Used   Avail Capacity  Mounted on
  20294 /dev/ad0s1a    253678   121204  112180    52%    /
      0 devfs               1        1       0   100%    /dev
  20294 /dev/ad0s1e    253678     5384  228000     2%    /tmp
1414142 /dev/ad0s1f  17676782 15108726 1153914    93%    /usr
  20294 /dev/ad0s1d    253678    57942  175442    25%    /var
      0 linprocfs           4        4       0   100%    /usr/compat/linux/proc
↑minfree

-m free-space
通常のユーザからは保護されている領域のパーセンテージを指定します。これは最低限の空き領域のしきい値となります。デフォルト値は にて MINFREE と定義され、現在 8% です。このオプションの詳細については、 tunefs(8) を参照してください。
man newfs より

df は基本的に statfs(2) で情報を取得する。

used = sfsp->f_blocks - sfsp->f_bfree;
availblks = sfsp->f_bavail + used;
if (hflag) {
	prthuman(sfsp, used);
} else {
	(void)printf(" %*jd %*jd %*jd",
	    mwp->total, fsbtoblk(sfsp->f_blocks, sfsp->f_bsize, blocksize),
	    mwp->used,  fsbtoblk(used, sfsp->f_bsize, blocksize),
	    mwp->avail, fsbtoblk(sfsp->f_bavail, sfsp->f_bsize, blocksize));
}
(void)printf(" %5.0f%%",
    availblks == 0 ? 100.0 : (double)used / (double)availblks * 100.0);
  • fsck は内部で fsck_ufs, fsck_msdosfs などを呼んでいる。
  • fsck_ufs, fsck_ffs, fsck_4.2bsd はハードリンク。
8358 -r-xr-xr-x  3 root  wheel  70052 11 11  2004 fsck_ufs*
8359 -r-xr-xr-x  1 root  wheel  27216 11 11  2004 fsck_msdosfs*
8358 -r-xr-xr-x  3 root  wheel  70052 11 11  2004 fsck_ffs*
8358 -r-xr-xr-x  3 root  wheel  70052 11 11  2004 fsck_4.2bsd*
8357 -r-xr-xr-x  1 root  wheel  14524 11 11  2004 fsck*
  • fsck に -b オプションはないが、fsck_ufs にはある。

今回の調査で回り道している途中に見つけたもの

ファイルがn個に分断されれば、アクセスにかかる時間はn倍になる。
http://www.biznix.org/whylinux/windows/fragment.html
ヘッドの移動時間が0〜10ms、回転待ち時間が0〜5ms、データ読み書き時間が0.1ms以下だそうなので、原理的には間違いなさそう。
http://www.sslab.ics.keio.ac.jp/~kono/os/12-fs/12-fs.pdf


ext2 の解説およびベンチマーク。図が分かりやすい。
ベンチマークを見ると、FreeBSD UFS より明らかに優れているが…?
fsck でチェックする事も書いてある。
http://e2fsprogs.sourceforge.net/ext2intro.html
ext2用のデフラグツールは存在する。
http://e2fsprogs.sourceforge.net/ext2.html


external fragment と internal fragment という用語も存在するらしい。

4.0BSD でブロックサイズは512バイトから1024バイトに変わった。これによって internal fragmentation は増加したが、スループットは増加した。この考えは後に System V でも採用された。

cylinder group によりディスクのヘッドの移動量を小さくすることができる。
http://codex.cs.yale.edu/avi/os-book/os7/online-dir/UnixBSD.pdf


fsck が報告する方を「内部フラグメンテーション」、Windowsデフラグで解消する方を「外部フラグメンテーション」という。
http://japan.internet.com/linuxtutorial/20011208/1.html


df の avail が 0 でないにもかかわらずファイルシステムがあふれる (渡辺克宏氏のニュース投稿記事)
http://katsu.watanabe.name/article/144.txt


UNIXファイルシステム ufs。
http://www.wakhok.ac.jp/~maruyama/Super/chapter2.7.html


「A Fast File System for UNIX」のサーベイ
http://www.spa.is.uec.ac.jp/~kinuko/survey/body/ffs.html

他にわからないこと

  • quot(8) の出力の見方
  • スーパーブロックおよびそのバックアップブロックのありか

スーパーブロックのバックアップを見ようとして、

dd if=/dev/ad0s1d bs=16k count=1 skip=1 | xxd
dd if=/dev/ad0s1d bs=16k count=1 skip=160 | xxd

としてみたが、中身はまったく違っていた。なぜ?

[追記:2007-05-06]
スーパーブロックのマスターは64KB目に。
UFS2 の alternate super block
http://bloghome.lovepeers.org/daymemo2/20050918.html#p02


[追記]
結局、Fast File System に関することは今日買ってきた「BSDカーネルの設計と実装 −FreeBSD詳解−」が一番詳しい。


ext2」も場合によってはデフラグしたほうが良い
http://www.pochi.cc/~sasaki/chalow/2005-04-21-9.html
Linuxファイルシステム技術解説
http://www.atmarkit.co.jp/flinux/index/indexfiles/index-linux.html#linuxfs
詳解ファイルシステム
http://wiki.livedoor.jp/linuxfs/d/FrontPage

702 From:名無しさん@お腹いっぱい。 Date:2007/05/07(月) 01:09:17 Mail:sage
ファイルをコピーしたり移動させた後にdfで空きサイズを確認すると
マイナスになってる事があるんだけど、これって何?('A`)

ちゃんと 'spaceが足りない' って言われる事もあるので、エラーが出
てなければコピー/移動自体は成功してるの?

              • -

704 From:名無しさん@お腹いっぱい。 Date:2007/05/07(月) 02:33:11 Mail:sage
>>702
えーとですねぇ、
man 8 tunefs
とコマンドを打ってですねぇ
-m minfree
の項目を見てみると理解できるかもしれませんです。


もしこの値を現在の空き領域より大きな値に引き上げると、ファイルを
削除してその値を満たすだけの空き領域を用意するまで、ユーザはファ
イルを作成することができなくなります。