<!--Chapter 9 The File system-->
<sect>ファイルシステム<label id="chapter_fs">
<p>
<figure><ph vspace="1"><img src="./The-Linux-Kernel-images/penguin2.gif">
</figure>

<!--
This chapter describes how the Linux kernel maintains the files in the file
systems that it supports. It describes the Virtual File System (VFS) and
explains how the Linux kernel's real file systems are supported. 
-->
<p>この章では、Linux カーネルがサポートするファイルシステム内でのファイル管理
の方法や、仮想ファイルシステムの仕組みについて解説する。また、Linux カーネルの
実(real)ファイルシステムがどのようにサポートされているのかについても説明する。

<!--
One of the most important features of Linux is its support for many different
file systems. This makes it very flexible and well able to coexist with many
other operating systems. At the time of writing, Linux supports 15 file
systems; ext, ext2, xia, minix, umsdos, msdos, vfat, proc, smb, ncp,
iso9660, sysv, hpfs, affs and ufs, and no doubt, over time more will be
added. 
-->
<p>Linux の最も重要な特徴のひとつに、サポートするファイルシステムの豊富さがあ
る。このことが、Linux を非常に柔軟なものにし、他の多くのオペレーティングシス
テムとの共存を可能にしている。書き込みに関して、Linux は 15 のファイルシステム
をサポートしている。それらは、<tt>ext, ext2, xia, minix, umsdos, msdos, vfat, 
proc, smb, ncp, iso9660, sysv, hpfs, affs,</tt> それに <tt>ufs</tt> であり、
おそらく今後もっと多くのファイルシステムが追加されるだろう。

<!--
In Linux, as it is for Unix TM, the separate file systems the system may use
are not accessed by device identifiers (such as a drive number or a drive
name) but instead they are combined into a single hierarchical tree structure
that represents the file system as one whole single entity. Linux adds each
new file system into this single file system tree as it is mounted. All file
systems, of whatever type, are mounted onto a directory and the files of the
mounted file system cover up the existing contents of that directory. This
directory is known as the mount directory or mount point. When the file
system is unmounted, the mount directory's own files are once again
revealed. 
-->
<p>Linux では、Unix の場合と同様に、システム上で使用される個別のファイルシステ
ムにアクセスする際、(ドライブ番号やドライブ名といった)デバイス識別子は使われな
い。
それらのファイルシステムは、単一の階層的なツリー構造に統合され、それによって
ファイルシステムは全体でひとつの実体として表現される。
新しいファイルシステムをマウントする場合、Linux は個々のファイルシステムをこの
単一のツリー構造に付け加える。すべてのファイルシステムは、そのタイプに関わら
ず、任意のディレクトリにマウントされ、マウントされたファイルシステムのファイル
がそのディレクトリに現存する内容を包み隠す。
そうしたディレクトリは、マウントディレクトリもしくはマウントポイントと呼ばれ
る。ファイルシステムがマウントを解除されると、そのマウントディレクトリに存在
したファイルが再度出現する。

<!--
When disks are initialized (using fdisk, say) they have a partition structure
imposed on them that divides the physical disk into a number of logical
partitions. Each partition may hold a single file system, for example an EXT2
file system. File systems organize files into logical hierarchical structures
with directories, soft links and so on held in blocks on physical devices.
Devices that can contain file systems are known as block devices. The IDE
disk partition /dev/hda1, the first partition of the first IDE disk drive in 
the system, is a block device. The Linux file systems regard these block 
devices as simply linear collections of blocks, they do not know or care about
the underlying physical disk's geometry. It is the task of each block device 
driver to map a request to read a particular block of its device into terms 
meaningful to its device; the particular track, sector and cylinder of its 
hard disk where the block is kept. A file system has to look, feel and operate
in the same way no matter what device is holding it. Moreover, using Linux's 
file systems, it does not matter (at least to the system user) that these 
different file systems are on different physical media controlled by different
hardware controllers. The file system might not even be on the local system, 
it could just as well be a disk remotely mounted over a network link. Consider
the following example where a Linux system has its root file system on a SCSI 
disk: 
-->
<p>ディスクが(たとえば、<tt>fdisk</tt> を使用して)初期化されるとき、ディスク上
にパーティション構造が設定され、物理ディスクがいくつかの論理パーティションに
分割される。個々のパーティションは、EXT2 ファイルシステムといった単一の
ファイルシステムを保持する。ファイルシステムはファイルを組織し、物理デバイス
のブロック上に保持されたディレクトリやソフトリンク(シンボリックリンク)などによ
る論理的な階層構造を形成する。
ファイルシステムを内包し得るデバイスはブロックデバイスと呼ばれる。
IDE ディスクのパーティション <tt>/dev/hda1</tt> は、システム上の最初の IDE 
ディスクの最初のパーティションであるが、これはブロックデバイスである。Linux 
ファイルシステムは、ブロックデバイスをブロックが単に線形に並んだものと見看して
おり、下位にある物理ディスクのジオメトリに関しては知らないか
もしくは関心を持たない。デバイスの特定ブロックの読み出しリクエストを、その
デバイスにとって意味のある言葉に置き換えこと、すなわち、ブロックが保存されて
いるそのハードディスク上の特定のトラック、セクタ、シリンダなどに置き換えるの
は、個々のブロックデバイスドライバの仕事である。ファイルシステムは、それを
保持しているのがどのようなデバイスであっても、同じ方法でそれを見て、認識し、
操作をする。さらに、Linux のファイルシステムを使用すれば、そうした異なる
ファイルシステムが異なるハードウェアコントローラに制御された異なる物理メディア
上にあるということは、(少なくともシステムのユーザにとっては)問題ではなくなる。
ファイルシステムはローカルシステム上にないことすら可能であり、ネットワーク
リンク越しに遠隔操作でマウントされたディスクであってもよい。Linux システムが
 SCSI ディスク上にルートファイルシステムを持っている次の例で考えてほしい。

<verb>
A         E         boot      etc       lib       opt       tmp       usr
C         F         cdrom     fd        proc      root      var       sbin
D         bin       dev       home      mnt       lost+found
</verb>

<!--
Neither the users nor the programs that operate on the files themselves need
know that /C is in fact a mounted VFAT file system that is on the first IDE
disk in the system. In the example (which is actually my home Linux system),
/E is the master IDE disk on the second IDE controller. It does not matter
either that the first IDE controller is a PCI controller and that the second is
an ISA controller which also controls the IDE CDROM. I can dial into the
network where I work using a modem and the PPP network protocol using a
modem and in this case I can remotely mount my Alpha AXP Linux system's
file systems on /mnt/remote. 
-->
<p>ユーザはもちろん、ファイル自体に操作を加えるプログラムでさえ、上記 <tt>
/C</tt> が実はマウントされた VFAT ファイルシステムであり、システムの第一の 
IDE ディスク上にあることを知る必要はない。上記の例では(これは実際にわたしが
自宅で使用している Linux システムのものなのだが)、<tt>/E</tt> は第二の IDE 
コントローラ上のマスター IDE ディスクである。プライマリ IDE コントローラが PCI 
コントローラで、第二のコントローラが IDE CD-ROM を制御する ISA コントローラで
あるといったことは(ファイルシステム上では)どちらも問題ではない。また、モデムと
そのモデムによる PPP ネットワークプロトコルを使用して、電話で職場のネットワーク
に接続し、この場合、そこにあるわたしの Alpha AXP Linux システム上のファイルシス
テムを <tt>/mnt/remote</tt> に遠隔操作でマウントすることもできる。

<!--
The files in a file system are collections of data; the file holding the 
sources to this chapter is an ASCII file called filesystems.tex. A file system
not only holds the data that is contained within the files of the file system 
but also the structure of the file system. It holds all of the information 
that Linux users and processes see as files, directories soft links, file 
protection information and so on. Moreover it must hold that information 
safely and securely, the basic integrity of the operating system depends on 
its file systems. Nobody would use an operating system that randomly lost data
and files. 
-->
<p>ファイルシステム上のファイルはデータの集合体である。この章の文章(訳注: 
原文のこと)が入った元のソースファイルは <tt>filesystems.tex</tt> というファイル
名の ASCII ファイルである。ファイルシステムは、そのファイルシステム上のファイル
内に含まれるデータを保持するだけでなく、ファイルシステムの構造をも保持してい
る。Linux のユーザやプロセスが、ファイル、ディレクトリ、ソフトリンク(シンボリッ
クリンク)、ファイル保護情報等々として見ている情報はすべて、ファイルシステムに
よって保持されている。
さらに、ファイルシステムはそうした情報を安全、確実に保持しなけれ
ばならない。オペレーティングシステムの基本的な統一性は、ファイルシステムに
依存しているからである。データやファイルの喪失が突発的に起こるオペレーティング
システムを使おうとする人はいないだろう(<ref id="chapter_fs_fn" 
name="脚注1">)。

<!--
Minix, the first file system that Linux had is rather restrictive and lacking 
in performance. Its filenames cannot be longer than 14 characters (which is 
still better than 8.3 filenames) and the maximum file size is 64MBytes. 
64Mbytes might at first glance seem large enough but large file sizes are 
necessary to hold even modest databases. The first file system designed 
specifically for Linux, the Extended File system, or EXT, was introduced in 
April 1992 and cured a lot of the problems but it was still felt to lack 
performance. So, in 1993, the Second Extended File system, or EXT2, was added. 
It is this file system that is described in detail later on in this chapter. 
-->
<p>Linux が最初に採用していた <tt>minix</tt> ファイルシステムは、やや制限が
多く、パフォーマンスにも欠けていた。ファイル名は 14 文字以上になってはなら
ず(これでも、8 文字 + 3文字 というファイル名よりはましである)、最大ファイル
サイズは 64M バイトであった。64 M バイトというと一見充分なサイズのように
思えるが、ちょっとしたデータベースを作ろうとすると大きなファイルサイズは必要
である。Linux 専用にデザインされた最初のファイルシステムである Extended File 
System (EXT) は、1992 年 4 月に発表され、多くの問題が改善されたが、それでも
まだパフォーマンスの欠如が感じられた。それゆえ、1993 年、Second Extended File 
System (EXT2) が登場した。この章で後ほど詳細に述べるのは、このファイルシステム
についてである。

<!--
An important development took place when the EXT file system was added
into Linux. The real file systems were separated from the operating system
and system services by an interface layer known as the Virtual File system,
or VFS. VFS allows Linux to support many, often very different, file systems, 
each presenting a common software interface to the VFS. All of the details of 
the Linux file systems are translated by software so that all file systems 
appear identical to the rest of the Linux kernel and to programs running in the
system. Linux's Virtual File system layer allows you to transparently mount
the many different file systems at the same time. 
-->
<p>EXT ファイルシステムが加わった際、重要な発展があった。実(real)ファイル
システムがオペレーティングシステムやシステムのサービスから分離され、その
インターフェイス層として仮想ファイルシステム(Virtual File System, VFS) が
付加されたことである。VFS によって、Linux は、多くの、しばしば非常に性質の
異なるファイルシステムのサポートが可能になった。そうした個々のファイルシステム
は VFS に対し共通のソフトウェアインターフェイスを提供する。Linux のファイル
システムの詳細のすべてがソフトウェア上で変換されるので、Linux カーネル
の残りの部分やシステム上で実行されているプログラムにとって、あらゆるファイル
システムは全く同じに見える。Linux の仮想ファイルシステムによって、同時に多く
の異なるファイルシステムを透過的にマウントすることが可能になっている。

<!--
The Linux Virtual File system is implemented so that access to its files is as
fast and efficient as possible. It must also make sure that the files and their
data are kept correctly. These two requirements can be at odds with each
other. The Linux VFS caches information in memory from each file system as
it is mounted and used. A lot of care must be taken to update the file system
correctly as data within these caches is modified as files and directories are
created, written to and deleted. If you could see the file system's data
structures within the running kernel, you would be able to see data blocks
being read and written by the file system. Data structures, describing the
files and directories being accessed would be created and destroyed and all
the time the device drivers would be working away, fetching and saving data.
The most important of these caches is the Buffer Cache, which is integrated
into the way that the individual file systems access their underlying block
devices. As blocks are accessed they are put into the Buffer Cache and kept
on various queues depending on their states. The Buffer Cache not only
caches data buffers, it also helps manage the asynchronous interface with
the block device drivers. 
-->
<p>Linux の仮想ファイルシステムは、ファイルへのアクセスを出来るだけ速く効率的
なものにするために実装されている。それはファイルやデータの正確な保存をも確実に
行わなければならない。これらふたつの要求は両立し難いものである。ファイルシス
テムがマウントされて利用される際、Linux の VFS はそれら個々の情報をメモリに
キャッシュする。ファイルやディレクトリに対する作成や書き込み、削除がなされて
そのキャッシュ内のデータが変更された場合、ファイルシステムを正しく更新する
には細かな配慮が必要になる。実行中のカーネル内にあるファイルシステムのデータ
構造を見ることができるとすれば、ファイルシステムによってデータブロックの読み
書きがなされる様子を観察できるだろう。アクセスされているファイルやディレクトリ
を記述するデータ構造体の作成や破棄がなされ、また終始デバイスドライバが動作
していて、データの取り込みや保存を行っている。これらのキャッシュで最も重要な
のが、バッファキャッシュ(buffer cache)であり、それは、個別のファイルシステム
がその基礎であるブロックデバイスにアクセスする仕組みのなかに組み込まれている。
ブロックがアクセスされると、それはバッファキャッシュに入れられ、それらの
状態に応じて様々なキュー上に保持される。バッファキャッシュは、データバッファを
キャッシュするだけではなく、非同期インターフェイスを管理することで、ブロック
デバイスドライバの手助けもしている。



<!--9.1  The Second Extended File system (EXT2)-->
<sect1>Second Extended File System (EXT2)<label id="chapter_fs_sect1">
<p>

<label id="figure9-1">
<!--          Figure 9.1: Physical Layout of the EXT2 File system-->
<#if output="html">
<figure><ph vspace="1"><img src="./The-Linux-Kernel-images/figure9-1.gif">
</figure>
</#if>
<#unless output="html">
<verb>
         +---------------------------------------------+
         |  | Block   |          | Block     | Block   |
         |  | Group 0 |          | Group N-1 | Group N |
         +---------------------------------------------+
                                 |           |
                           +-----+           +-----+
                           |                       |
<--------------------------+                       +-------------->
                           
+------------------------------------------------------------------+
| Super | Group       | Block  | Inode  | Inode |       Data       |
| Block | Descriptors | Bitmap | Bitmap | Table |       Block      |
|       |             |        |        |       |                  |
+------------------------------------------------------------------+
</verb>
</#if>
<p>図表(9.1) EXT2 ファイルシステムの物理的レイアウト

<!--
The Second Extended File system was devised (by Remy Card) as an
extensible and powerful file system for Linux. It is also the most successful
file system so far in the Linux community and is the basis for all of the
currently shipping Linux distributions. 
-->
<p>EXT2 ファイルシステム(Second Extended File System) は、Remy Card によって
考案された Linux 用の拡張性に富むパワフルなファイルシステムである。
それは Linux コミュニティーにおいてこれまでで最も成功したファイルシステムであ
り、現在出荷されているすべての Linux ディストリビューションの基盤でもある。
<newline>[see: fs/ext2/*]
<!--
The EXT2 file system, like a lot of the file systems, is built on the premise
that the data held in files is kept in data blocks. These data blocks are all 
of the same length and, although that length can vary between different EXT2
file systems the block size of a particular EXT2 file system is set when it is
created (using mke2fs). Every file's size is rounded up to an integral number
of blocks. If the block size is 1024 bytes, then a file of 1025 bytes will 
occupy two 1024 byte blocks. Unfortunately this means that on average you waste
half a block per file. Usually in computing you trade off CPU usage for
memory and disk space utilisation. In this case Linux, along with most
operating systems, trades off a relatively inefficient disk usage in order to
reduce the workload on the CPU. 
Not all of the blocks in the file system hold
data, some must be used to contain the information that describes the
structure of the file system. EXT2 defines the file system topology by
describing each file in the system with an inode data structure. An inode
describes which blocks the data within a file occupies as well as the access
rights of the file, the file's modification times and the type of the file. 
Every file in the EXT2 file system is described by a single inode and each 
inode has a single unique number identifying it. The inodes for the file 
system are all kept together in inode tables. EXT2 directories are simply 
special files (themselves described by inodes) which contain pointers to the 
inodes of their directory entries. 
-->
<p>EXT2 ファイルシステムは、多くのファイルシステム同様、ファイルに保持された
データはデータブロックに保存されるという前提のもとに構築されている。これらの
データブロックはすべて同じサイズであり、そのサイズは異なる EXT2 ファイル
システム間で変化することがあるが、特定の EXT2 ファイルシステムにおけるブロック
サイズは(<tt>mke2fs</tt> コマンドを使用した)ファイルシステム作成時に設定さ
れる。ファイルサイズはすべて、ブロックサイズの整数倍に切り上げられる。ブロック
サイズが 1024 バイトの場合、1025 バイトのファイルは 1024 バイトのブロックふたつ
を占有する。残念なことに、これは平均するとファイルごとに半ブロックのディスク
スペースが浪費されることを意味する。( CPU 対記憶装置という二者択一の原理から
すると)コンピュータでは通常、CPU 効率を犠牲にしてメモリとディスクスペース
を有効利用する。しかしこの場合、Linux は、大部分のオペレーティングシステムと
同様、CPU の負荷を減らすために、比較的効率の悪いディスクの使い方をする。
<p>
ファイルシステム上のすべてのブロックがデータを保持しているのではない。ブロック
の一部は、ファイルシステムの構造を記述した情報を保持するために使用されている。
EXT2 はファイルシステムのトポロジーを定義するために、システム上の個々の
ファイルを <tt><ref id="ext2_inode" name="inode"></tt> データ構造体で記述して
いる。
<tt>inode</tt> が記述する事柄には、ファイル内のデータが保持されたブロックの位置
や、ファイルへのアクセス権、ファイルの変更時間、ファイルタイプなどがある。
EXT2 ファイルシステム上のすべてのファイルは、単一の <tt>inode</tt> で記述され、
個々の <tt>inode</tt> は識別のための単一でユニークな番号を持つ。
ファイルシステム上の <tt>inode</tt> は、<tt>inode</tt> テーブル内に保存される。
EXT2 のディレクトリとは(それ自体も <tt>inode</tt> によって記述されている)特殊な
ファイルにすぎず、そのファイルに含まれるのは、そのディレクトリ(が保持する)
エントリの <tt>inode</tt> へのポインタである。

<!--
Figure  9.1 shows the layout of the EXT2 file system as occupying a series of
blocks in a block structured device. So far as each file system is concerned,
block devices are just a series of blocks that can be read and written. A file
system does not need to concern itself with where on the physical media a
block should be put, that is the job of the device's driver. Whenever a file
system needs to read information or data from the block device containing it,
it requests that its supporting device driver reads an integral number of
blocks. The EXT2 file system divides the logical partition that it occupies 
into Block Groups. Each group duplicates information critical to the integrity
of the file system as well as holding real files and directories as blocks of 
information and data. This duplication is neccessary should a disaster occur 
and the file system need recovering. The subsections describe in more detail 
the contents of each Block Group. 
-->
<p><ref id="figure9-1" name="図表(9.1)">は、EXT2 ファイルシステムのレイアウト
を示すものであるが、それらは、ブロック構造を持ったデバイス上で連続したブロック
を占有している。
個々のファイルシステムからすると、ブロックデバイスとは読み書き可能な一連の
ブロックにすぎない。ファイルシステムは物理メディア上のどこにブロックを置くべき
かを気にする必要がない。それはデバイスドライバの仕事である。ファイルシステムが
ブロックデバイスの持つ情報やデータを読み込む必要があるときは、そのデバイスを
サポートするデバイスドライバに対して、ある整数倍の数のブロックを読み込むよう
リクエストをする。
EXT2 ファイルシステムは、ディスク上の論理パーティションを、複数のブロック
グループ(Block Group)に分割する。個々のブロックグループは、実(real)ファイルや
実ディレクトリの情報やデータをブロックとして保持すると同時に、ファイルシステム
の整合性(integrity)を保つために必須の情報を二重化して保持する。二重化が必要なの
は、不具合が生じてファイルシステムを復旧しなければならない場合があるからであ
る。ブロックグループそれぞれの内容については、サブセクションでさらに詳しく説明
する。

<!--9.1.1  The EXT2 Inode-->
<sect2>EXT2 Inode<label id="chapter_fs_sect1-1">
<p>

<label id="figure9-2">
<!--                    Figure 9.2: EXT2 Inode-->
<#if output="html">
<figure><ph vspace="1"><img src="./The-Linux-Kernel-images/figure9-2.gif">
</figure>
</#if>
<#unless output="html">
<verb>
  ext2_inode
+-----------------+                                  +-------+
| Mode            |                      +---------->| Data  |
|-----------------|                      |           +-------+
| Owner info      |                      |           
|-----------------|                      |           +-------+
| Size            |                      |   +------>| Data  |
|-----------------|                      |   |       +-------+
| Timestamps      |                      |   |       +-------+
|-----------------|                      |   |       | Data  |
|                 |----------------------+   |       +-------+
| Direct Blocks   |                          |
|                 |--------------------------+       +-------+
|                 |                               +->| Data  |
|                 |                 +---+         |  +-------+
|                 |         +------>|   |---------+  +-------+
|-----------------|         |       |   |----------->| Data  |
| Indirect blocks |---------+       |   |            +-------+
|-----------------|           +---+ +---+  +---+     +-------+
| Double Indirect |---------->|   |------->|   |---->| Data  |
|-----------------|           |   |-+      |   |     +-------+
| Triple Indirect |           |   | |      |   |-+   +-------+
+-----------------+           +---+ |      +---+ +-->| Data  |
                                    |      +---+     +-------+
                                    +----->|   |     +-------+
                                           |   |---->| Data  |
                                           |   |     +-------+
                                           +---+
</verb>
</#if>
<p>図表(9.2) EXT2 Inode


<!--
In the EXT2 file system, the inode is the basic building block; every file and
directory in the file system is described by one and only one inode. The EXT2
inodes for each Block Group are kept in the inode table together with a bitmap
that allows the system to keep track of allocated and unallocated inodes.
Figure  9.2 shows the format of an EXT2 inode, amongst other information, it
contains the following fields: 
-->
<p>EXT2 ファイルシステムでは、<tt><ref id="ext2_inode" name="inode"></tt> が
基本的な建築材料(building block)である。
ファイルシステム上のすべてのファイルとディレクトリは、それらと一対一の関係
に立つ <tt>inode</tt> によって記述される。ブロックグループごとの EXT2  
<tt>inode</tt> は、<tt>inode</tt> テーブルに保存され、同時に、システムが割り当
てや解放を行った <tt>inode</tt> の状態を監視するためのビットマップ(bitmap)も
そのテーブルに保存される。
図表(9.2)では、EXT2 inode のフォーマットを示していて、その種々の情報の中には、
次のようなフィールドが含まれている。
<newline>[see: <htmlurl 
url="./The-Linux-Kernel-images/linux/include/linux/ext2_fs_i.h" 
name="include/linux/ext2_fs_i.h">]<newline>

<!--
mode This holds two pieces of information; what this inode describes and
      the permissions that users have to it. For EXT2, an inode can
      describe one of file, directory, symbolic link, block device, character
      device or FIFO. 
-->
<label id="chapter_fs_ext2_mode">
<descrip>
<tag>モード (mode)</tag>
このフィールドは 2 種類の情報を保持している。その inode が何を記述しているか
ということと、ユーザがそれに対して持つパーミッションである。
EXT2 の場合、inode が記述できるのは、ファイル、ディレクトリ、シンボリック
リンク、ブロックデバイス、キャラクタデバイス、FIFO のうちのひとつである。

<!--
Owner Information
      The user and group identifiers of the owners of this file or directory.
      This allows the file system to correctly allow the right sort of
      accesses, 
-->
<tag>所有者情報</tag>
そのファイルやディレクトリの所有者(owner)に関するユーザ識別子とグループ識別子。
これによって、ファイルシステムは正しいアクセス権限を適切に判断できる。

<!--
Size The size of the file in bytes, 
-->
<tag>サイズ</tag>
バイト単位で表されるファイルサイズ

<!--
Timestamps
      The time that the inode was created and the last time that it was
      modified, 
-->
<tag>タイムスタンプ(timestamps)</tag>
<tt><ref id="ext2_inode" name="inode"></tt> が作成された時間とそれが最後に修正
された時間

<!--
Datablocks
      Pointers to the blocks that contain the data that this inode is
       describing. The first twelve are pointers to the physical blocks
      containing the data described by this inode and the last three pointers
      contain more and more levels of indirection. For example, the double
      indirect blocks pointer points at a block of pointers to blocks of
      pointers to data blocks. This means that files less than or equal to
      twelve data blocks in length are more quickly accessed than larger
      files. 
-->
<tag>データブロック</tag>
<tt><ref id="ext2_inode" name="inode"></tt> が記述するデータを含んだブロック
に対するポインタ。
最初の 12 個は、その inode が記述するデータを含んだ物理ブロックへのポインタで
あり、最後の 3 つはそれよりも 2 段階間接的なポインタとなっている。たとえば、こ
の二重間接ブロックポインタ(double indirect block pointer)は、物理データブロック
へのポインタ群に対するポインタ群をポイントしている。これは、12 個のデータブロッ
ク以下のサイズしかないファイルは、それより大きいファイルよりも高速にアクセスさ
れることを意味する。
</descrip>

<!--
You should note that EXT2 inodes can describe special device files. These
are not real files but handles that programs can use to access devices. All of
the device files in /dev are there to allow programs to access Linux's
devices. For example the mount program takes as an argument the device file
that it wishes to mount. 
-->
<p>注意すべきなのは、EXT2 inode はスペシャルファイルを表すことができることで
ある。これらは実(real)ファイルではないが、プログラムがそれを使ってデバイスに
アクセスできるようにするためのものである。<tt>/dev</tt> ディレクトリに
すべてのデバイスファイルが存在することによって、プログラムは Linux 上のデバイス
にアクセスできる。たとえば、<tt>mount</tt> プログラムは、マウントしようとする
デバイスファイル名を引数に取る。

<!--9.1.2  The EXT2 Superblock-->
<sect2>EXT2 スーパーブロック(Superblock)<label id="chapter_fs_sect1-2">

<!--
The Superblock contains a description of the basic size and shape of this file
system. The information within it allows the file system manager to use and
maintain the file system. Usually only the Superblock in Block Group 0 is read
when the file system is mounted but each Block Group contains a duplicate
copy in case of file system corruption. Amongst other information it holds the:
-->
<p>スーパーブロック(superblock)には、そのファイルシステムの基本的なサイズと
構造(shape)とを記述した情報が含まれる。そこにある情報によって、ファイルシステム
マネージャは、ファイルシステムの使用と管理が可能となる。通常、ファイルシステム
がマウントされる時、ブロックグループ 0 上のスーパーブロックだけが読み込まれるの
だが、個々のブロックグループにはシステムの破壊に備えた複製が含まれている。
様々な情報のなかには次のようなものがある。
<newline>[see: <htmlurl 
url="./The-Linux-Kernel-images/linux/include/linux/ext2_fs_sb.h" 
name="include/linux/ext2_fs_sb.h">]<newline>
[訳注:ext2_super_block, in <htmlurl 
url="./The-Linux-Kernel-images/linux/include/linux/ext2_fs.h" 
name="include/linux/ext2_fs.h">]
<!--
Magic Number
      This allows the mounting software to check that this is indeed the
      Superblock for an EXT2 file system. For the current version of EXT2
      this is 0xEF53. 
-->
<descrip>
<tag>マジックナンバー(<ref id="magic_number" name="magic number">)</tag>
これは、マウント操作を行うソフトウェアが、そのスーパーブロックが本当に EXT2 
ファイルシステムのものであるかチェックすることを可能にするためにある。EXT2 の
現行バージョンでは、この番号は 0xEF53 である。

<!--
Revision Level
      The major and minor revision levels allow the mounting code to
      determine whether or not this file system supports features that are
      only available in particular revisions of the file system. There are also
      feature compatibility fields which help the mounting code to
      determine which new features can safely be used on this file system, 
-->
<tag>リビジョンレベル(revision level)</tag>
メジャーとマイナーのリビジョンレベルによって、マウント操作を行うコードは、
そのファイルシステムの特定のリビジョンでしか利用できない機能(feature)をサポー
トすべきかどうかを判断する。
また、機能互換性フィールド(feature compatibility field)というのが存在し、その
情報は、マウント操作コードが、そのファイルシステム上で新しい機能を安全に使用
することができるかどうかを判断する際の手助けをする。

<!--
Mount Count and Maximum Mount Count
      Together these allow the system to determine if the file system
      should be fully checked. The mount count is incremented each time
      the file system is mounted and when it equals the maximum mount
      count the warning message ``maximal mount count reached, running
      e2fsck is recommended'' is displayed, 
-->
<tag>マウントカウントと最大マウントカウント(mount count and maximum mount 
count)</tag>
これらふたつは、ファイルシステムの整合性を完全にチェックすべきかどうかを
システムが判断できるようにするために存在する。マウントカウントは、ファイル
システムがマウントされるたびに加算され、最大マウントカウントに達すると、
「最大マウントカウントに達したので、<tt>e2fsck</tt> を実行することを薦めます」
という警告メッセージが表示される。

<!--
Block Group Number
      The Block Group number that holds this copy of the Superblock, 
-->
<tag>ブロックグループ番号(block group number)</tag>
このスーパーブロックのコピーを保持するブロックグループ番号。

<!--
Block Size
      The size of the block for this file system in bytes, for example 1024
      bytes, 
-->
<tag>ブロックサイズ(block size)</tag>
バイト数で表されるそのファイルシステムのブロックサイズ。たとえば、1024 バイト等
と表示される。

<!--
Blocks per Group
      The number of blocks in a group. Like the block size this is fixed
      when the file system is created, 
-->
<tag>グループごとのブロック数</tag>
ひとつのグループのブロック数。これは、ブロックサイズ同様、ファイルシステム作成
時に確定される。

<!--
Free Blocks
      The number of free blocks in the file system, 
-->
<tag>フリーブロック</tag>
ファイルシステム上のフリーブロックの数。

<!--
Free Inodes
      The number of free Inodes in the file system, 
-->
<tag>フリー inode</tag>
ファイルシステム上のフリー inode の数。

<!--
First Inode
      This is the inode number of the first inode in the file system. The first
      inode in an EXT2 root file system would be the directory entry for the
      '/' directory. 
-->
<tag>最初の inode (first inode)</tag>
ファイルシステム上の最初の inode の inode 番号。EXT2 ルートファイルシステム
上での最初の inode は、&dquot;<tt>/</tt>&dquot; ディレクトリのディレクトリ
エントリである。
</descrip>


<!--9.1.3  The EXT2 Group Descriptor-->
<sect2>EXT2 グループディスクリプタ<label id="chapter_fs_sect1-3">

<!--
Each Block Group has a data structure describing it. Like the Superblock, all
the group descriptors for all of the Block Groups are duplicated in each Block
Group in case of file system corruption. 
-->
<p>個々のブロックグループは、それを記述するデータ構造体を持っている。スーパー
ブロックと同様に、全ブロックグループに対するグループディスクリプタはすべて、
ファイルシステムの障害に備えて、個々のブロックグループ内で二重化されている。
<newline>[see: ext2_group_desc, in <htmlurl 
url="./The-Linux-Kernel-images/linux/include/linux/ext2_fs.h"
name="include/linux/ext2_fs.h">]<newline>

<!--
Each Group Descriptor contains the following information: 
-->
<p>個々のグループディスクリプタには、次のような情報が含まれている。

<!--
Blocks Bitmap
      The block number of the block allocation bitmap for this Block Group.
      This is used during block allocation and deallocation, 
-->
<descrip>
<label id="chapter_fs_bitmap">
<tag>ブロックビットマップ(Block Bitmap)</tag>
そのブロックグループに関するブロック割り当てビットマップ(block allocation 
bitmap)のブロック番号。
これは、ブロックの割り当てと解放の際に使用される。

<!--
Inode Bitmap
      The block number of the inode allocation bitmap for this Block Group.
      This is used during inode allocation and deallocation, 
-->
<tag>inode ビットマップ (Inode Bitmap)</tag>
そのブロックグループに対する inode 割り当てビットマップのブロック番号。
これは、inode の割り当てと解放の際に使用される。

<!--
Inode Table
      The block number of the starting block for the inode table for this
      Block Group. Each inode is represented by the EXT2 inode data
      structure described below. 
-->
<tag>inode テーブル(Inode Table)</tag>
そのブロックグループの対する inode テーブルの開始ブロックのブロック番号。
個々の inode は、下記で述べる EXT2 inode データ構造体によって表されている。

<!--
Free blocks count, Free Inodes count, Used directory count
-->
<tag>Free block count, Free Inodes count, Used directory count</tag>
(訳注：これらの項目の説明は原文から省略されています。)
</descrip>

<!--
The group descriptors are placed on after another and together they make the
group descriptor table. Each Blocks Group contains the entire table of group
descriptors after its copy of the Superblock. Only the first copy (in Block
Group 0) is actually used by the EXT2 file system. The other copies are
there, like the copies of the Superblock, in case the main copy is corrupted. 
-->
<p>グループディスクリプタは連続的に配置されているので、全体でグループディスク
リプタテーブルを形成している。個々のブロックグループには、そのスーパーブロッ
クのコピーの後に、グループディスクリプタのテーブル全体が含まれている。
EXT2 ファイルシステムによって実際に使用されるのは、(ブロックグループ 0 にある)
最初のコピーだけである。その他のコピーは、スパーブロックのコピーの場合と同様
に、メインコピーが壊れた場合に備えてのものである。

<!--9.1.4  EXT2 Directories-->
<sect2>EXT2 ディレクトリ<label id="chapter_sect1-4">
<p>

<label id="figure9-3">
<!--                   Figure 9.3: EXT2 Directory-->
<#if output="html">
<figure><ph vspace="1"><img src="./The-Linux-Kernel-images/figure9-3.gif">
</figure>
</#if>
<#unless output="html">
<verb>
 0                   15                        55
+---+---+---+------+---+---+---+--------------+--------------------+
| il| 15|  5|  file| i2| 40| 14|very_long_name|                    |
+---+---+---+------+---+---+---+--------------+--------------------+
  |    |           * |    |                   *
  |    |          /| |    |                  /|
  |    |           | |    |                   |
  |    +-----------+ |    +-------------------+
  |                  |          
  |                  |      inode table
  |                  |     +--------------------+
  |                  |     |                    |
  |                  |     |--------------------|
  |                  |     |                    |
  |                  |     |--------------------|
  |                  +---->|                    |
  |                        |--------------------|
  |                        |                    |
  |                        |--------------------|
  +----------------------->|                    |
                           +--------------------+
</verb>
</#if>
<p>図表(9.3) EXT2 ディレクトリ

<!--
In the EXT2 file system, directories are special files that are used to create
and hold access paths to the files in the file system. Figure  9.3 shows the
layout of a directory entry in memory. A directory file is a list of directory
entries, each one containing the following information: 
-->
<p>EXT2 ファイルシステムにおいて、ディレクトリとは、ファイルシステム上のファイ
ルに対するアクセスパス(access path)の作成と保持のために使用されるスペシャル
ファイルである。図表(9.3)では、メモリ上でのディレクトリエントリのレイアウトが
示されている。ディレクトリファイルは、ディレクトリエントリのリストであり、
個々のエントリには次のような情報が含まれている。
<newline>[see: ext2_dir_entry, in <htmlurl 
url="./The-Linux-Kernel-images/linux/include/linux/ext2_fs.h" 
name="include/linux/ext2_fs.h">]<newline>

<!--
inode The inode for this directory entry. This is an index into the array of
      inodes held in the Inode Table of the Block Group. In figure  9.3, the
      directory entry for the file called file has a reference to inode
      number i1, 
-->
<descrip>
<tag>inode</tag>
そのディレクトリエントリに対する inode 。これは、ブロックグループの inode 
テーブルに保持されている inode 配列へのインデックスになっている。図表(9.3)
では、<tt>file</tt> という名前のファイルに対するディレクトリエントリが inode 
番号 <tt>i1</tt> を参照している。

<!--
name length
      The length of this directory entry in bytes, 
-->
<tag>名前のサイズ (name length)</tag>
バイト数で示されるそのディレクトリエントリのサイズ

<!--
name The name of this directory entry. 
-->
<tag>名前 (name)</tag>
そのディレクトリエントリの名前
</descrip>

<!--
The first two entries for every directory are always the standard ``.'' 
and ``..'' entries meaning ``this directory'' and ``the parent directory'' 
respectively. 
-->
<p>すべてのディレクトリにおける最初のふたつのエントリはいつも、標準となって
いる "<tt>.</tt>" と "<tt>..</tt>" エントリであり、
それらはそれぞれ "現在のディレクトリ" と "親ディレクトリ(parent directory)" 
を意味している。

<!--9.1.5  Finding a File in an EXT2 File System-->
<sect2>EXT2 ファイルシステム上のファイルの検索<label id="chapter_fs_sect1-5">

<!--
A Linux filename has the same format as all Unix TM filenames have. It is a
series of directory names separated by forward slashes (``/'') and ending in
the file's name. One example filename would be /home/rusling/.cshrc
where /home and /rusling are directory names and the file's name is
.cshrc. Like all other Unix TM systems, Linux does not care about the
format of the filename itself; it can be any length and consist of any of the
printable characters. To find the inode representing this file within an EXT2
file system the system must parse the filename a directory at a time until we
get to the file itself. 
-->
<p>Linux のファイル名は、Unix 上のファイル名と同じフォーマットになっている。
それは、スラッシュ("<tt>/</tt>")で区切られた一連のディレクトリ名とその最後
にあるファイルの名前から成る。ファイル名の一例は、<tt>/home/rusling/.cshrc
</tt>であり、ここでの <tt>/home</tt> と <tt>/rusling</tt> はディレクトリ名で
あり、ファイル名は <tt>.cshrc</tt> である。他のすべての Unix システムと同様に、
Linux はファイル名そのもののフォーマットには特別な様式を要求しない。それは任意
の長さで、表示可能な任意の文字であってよい。EXT2 ファイルシステム上の
上記ファイルを表す inode を発見するため、システムは、そのファイル自体の
名前に到達するまでファイル名をディレクトリ単位で分解しなければならない。

<!--
The first inode we need is the inode for the root of the file system and we 
find its number in the file system's superblock. To read an EXT2 inode we must
look for it in the inode table of the appropriate Block Group. If, for example,
the root inode number is 42, then we need the 42nd inode from the inode table
of Block Group 0. The root inode is for an EXT2 directory, in other words the
mode of the root inode describes it as a directory and it's data blocks contain
EXT2 directory entries. 
-->
<p>必要とされる最初の inode は、ファイルシステムのルートディレクトリの inode 
であるので、ファイルシステム上のスーパーブロック内でその番号を見つける。EXT2 
inode を読むためには、適切なブロックグループの inode テーブルでそれを探さなけ
ればならない。たとえば、ルートの inode 番号が 42 である場合、ブロックグループ 
0 の inode テーブルにある 42 番目の inode を必要とする。ルート inode は EXT2 
ディレクトリのものであり、言い換えると、ルート inode のモード(mode)には
ディレクトリと記述されているので、そのデータブロックには EXT2 ディレクトリの
エントリが含まれている。

<!--
home is just one of the many directory entries and this directory entry gives
us the number of the inode describing the /home directory. We have to read
this directory (by first reading its inode and then reading the directory 
entries from the data blocks described by its inode) to find the rusling entry
which gives us the number of the inode describing the /home/rusling directory.
Finally we read the directory entries pointed at by the inode describing the
/home/rusling directory to find the inode number of the .cshrc file and
from this we get the data blocks containing the information in the file. 
-->
<p><tt>home</tt> は多くのディレクトリエントリのひとつにすぎず、このディレクトリ
エントリからは、<tt>/home</tt> ディレクトリが記述する inode の番号が分かる。
<tt>rusling</tt> のエントリを見つけるにはこのディレクトリを読み込まなければ
ならない。(まず、最初にその inode を読み込んで、次にその inode によって記述
されたデータブロックからディレクトリエントリを読み込む。)そして、その中から 
<tt>rusling</tt> エントリが見つかったら、そこから <tt>/home/rusling</tt> 
ディレクトリを記述する inode の番号が分かる。最後に、<tt>/home/rusling</tt> 
ディレクトリを記述する inode によってポイントされたディレクトリエントリを
読んで、<tt>.cshrc</tt> ファイルの inode 番号を発見し、その番号によって
そのファイルの情報を含んでいるデータブロックを取得する。

<!--9.1.6  Changing the Size of a File in an EXT2 File System-->
<sect2>EXT2 ファイルシステム上のファイルサイズの変更<label 
id="chapter_fs_sect1-6">

<!--
One common problem with a file system is its tendency to fragment. The
blocks that hold the file's data get spread all over the file system and this
makes sequentially accessing the data blocks of a file more and more
inefficient the further apart the data blocks are. The EXT2 file system tries 
to overcome this by allocating the new blocks for a file physically close to 
its current data blocks or at least in the same Block Group as its current data
blocks. Only when this fails does it allocate data blocks in another Block
Group. 
-->
<p>ファイルシステムに共通の問題のひとつに、ファイルの断片化(fragment)傾向が
ある。ファイルのデータを保持するブロックはファイルシステム全体に分散して
しまい、そのため、データブロック間の距離が遠くなるにつれて、ファイルのデータ
ブロックに対する連続したアクセスが困難になりアクセス効率が落ちてしまう。
EXT2 ファイルシステムはこの問題を克服するために、ファイルに新しいデータブロック
を割り当てる際、それが現在存在するデータブロックに対し物理的に近接する位置に
割り当てるか、少なくとも元のデータブロックと同じブロックグループ内に割り当て
ようとする。そしてそれが出来ない場合のみ、データブロックを別のブロックグループ
に割り当てる。

<!--
Whenever a process attempts to write data into a file the Linux file system
checks to see if the data has gone off the end of the file's last allocated
block. If it has, then it must allocate a new data block for this file. Until 
the allocation is complete, the process cannot run; it must wait for the file 
system to allocate a new data block and write the rest of the data to it 
before it can continue. The first thing that the EXT2 block allocation 
routines do is to lock the EXT2 Superblock for this file system. Allocating 
and deallocating changes fields within the superblock, and the Linux file 
system cannot allow more than one process to do this at the same time. If 
another process needs to allocate more data blocks, it will have to wait until
this process has finished. Processes waiting for the superblock are suspended,
unable to run, until control of the superblock is relinquished by its current 
user. Access to the superblock is granted on a first come, first served basis 
and once a process has control of the superblock, it keeps control until it 
has finished. Having locked the superblock, the process checks that there are 
enough free blocks left in this file system. If there are not enough free 
blocks, then this attempt to allocate more will fail and the process will 
relinquish control of this file system's superblock. 
-->
<p>プロセスがデータをファイルに書き込もうとするとき、Linux ファイルシステム
は、(データ書き込みの途中で)そのファイルに対して最後に割り当てられたブロック
の終端を越えたかどうかをチェックする。
終端を越えた場合、ファイルシステムはそのファイルに新しいデータブロックを割り
当てる処理をする。割り当てが終わるまで、プロセスは実行を中断する。ファイル
システムが新しいデータブロックを割り当てて、それに残りのデータを書き込むまで
待ってから、プロセスは実行を再開しなければならない。
EXT2 ブロック割り当てルーチンが最初に実行することは、そのファイルシステムに対
する EXT2 スーパーブロックをロック(lock)することである。割り当てと解放は
スーパーブロック内のフィールドの値を変更するので、Linux ファイルシステムは同時
に複数のプロセスがそれをすることを許さない。他のプロセスがさらにデータブロック
を割り当てなければならない場合は、実行中のプロセスが終了するまで待つ必要があ
る。
スーバーブロックのロック解除を待つプロセスはサスペンド状態になり、スーパー
ブロックの制御が現在のユーザによって開放されるまでは実行されない。
スーパーブロックへのアクセスは早い者勝ちの仕組みで許可されるので、プロセスが
いったんスーパーブロックの制御を得た場合、処理の終了までその制御を保持する。
スーパーブロックをロックした後、プロセスはファイルシステム上に充分な空き
ブロックがあるかどうかをチェックする。
充分な空きブロックがない場合、それ以上割り当てようとしても失敗するので、プロ
セスは、そのファイルシステムのスーパーブロックの制御を解放する。

<!--
If there are enough free blocks in the file system, the process tries to 
allocate one. 
If the EXT2 file system has been built to preallocate data blocks then we may
be able to take one of those. The preallocated blocks do not actually exist,
they are just reserved within the allocated block bitmap. The VFS inode
representing the file that we are trying to allocate a new data block for has
two EXT2 specific fields, prealloc_block and prealloc_count, which
are the block number of the first preallocated data block and how many of
them there are, respectively. If there were no preallocated blocks or block
preallocation is not enabled, the EXT2 file system must allocate a new block.
The EXT2 file system first looks to see if the data block after the last data
block in the file is free. Logically, this is the most efficient block to 
allocate as it makes sequential accesses much quicker. If this block is not 
free, then the search widens and it looks for a data block within 64 blocks of
the of the ideal block. This block, although not ideal is at least fairly 
close and within the same Block Group as the other data blocks belonging to 
this file. 
-->
<p>ファイルシステム上に充分な空きブロックがある場合、プロセスはそれを割り当て
ようとする。
<newline>[see:ext2_new_block(), in <htmlurl 
url="./The-Linux-Kernel-images/linux/fs/ext2/balloc.c" 
name="fs/ext2/balloc.c">]<newline>
EXT2 ファイルシステムがデータブロックを先割り当て(preallocate)するようビルド
されている場合、それらの中から割り当てを行うことができる。この先割り当てされた
ブロックは実際には存在せず、割り当てられたブロックビットマップ(<ref 
id="chapter_fs_bitmap" name="block bitmap">)内で予約されているだけである。
ファイルに新しいデータブロックを割り当てようとしている場合、そのファイルを
表す VFS <tt><ref id="inode" name="inode"></tt> には、EXT2 に特有の <tt>
<ref id="ext2_inode_info" name="prealloc_block"></tt> と <tt><ref 
id="ext2_inode_info" name="prealloc_count"></tt> のふたつのフィールドがあり、
それらはそれぞれ、先割り当てされたデータブロックの最初のブロック番号と、
存在するブロック数を表す。
先割り当てされたブロックが存在しないかブロックの先割り当てが無効な場合、EXT2 
ファイルシステムは新しいブロックを割り当てなければならない。まず EXT2 ファイル
システムはファイル内の最後のデータブロックの直後にあるデータブロックが空かどう
かを確認する。理論的には、このブロックは、連続的なアクセスをより高速にできるの
で、割り当てるのに最も効率的なブロックである。このブロックが空でない場合、検索
範囲が広げられ、先ほどの理想的なブロックから 64 ブロック以内にあるブロックを探
す。このブロックは最適ではないにしても、少なくとも非常に近くにあり、そのファイ
ルに属する他のデータブロックと同じブロックグループ内にある。
<newline>[see: ext2_new_block(), in <htmlurl 
url="./The-Linux-Kernel-images/linux/fs/ext2/balloc.c" 
name="fs/ext2/balloc.c">]

<!--
If even that block is not free, the process starts looking in all of the other
Block Groups in turn until it finds some free blocks. The block allocation code
looks for a cluster of eight free data blocks somewhere in one of the Block
Groups. If it cannot find eight together, it will settle for less. If block
preallocation is wanted and enabled it will update prealloc_block and
prealloc_count accordingly. 
-->
<p>そのブロックが空でない場合であっても、プロセスは他のブロックグループを順番
に探して、何らかの空ブロックを見つける。ブロック割り当てコードは、ひとつの
ブロックグループ内のどこかに 8 個の空データブロックのクラスタがあるか調べる。
8 個を一緒に見つけられない場合、それ以下で処理を行う。ブロックの先割り当てが
必要かつ有効とされている場合、当該コードは <tt>prealloc_block</tt> と <tt>
prealloc_count</tt> を適宜更新する。

<!--
Wherever it finds the free block, the block allocation code updates the Block
Group's block bitmap and allocates a data buffer in the buffer cache. That
data buffer is uniquely identified by the file system's supporting device
identifier and the block number of the allocated block. The data in the buffer
is zero'd and the buffer is marked as ``dirty'' to show that it's contents have
not been written to the physical disk. Finally, the superblock itself is marked
as ``dirty'' to show that it has been changed and it is unlocked. If there were
any processes waiting for the superblock, the first one in the queue is allowed
to run again and will gain exclusive control of the superblock for its file
operations. The process's data is written to the new data block and, if that
data block is filled, the entire process is repeated and another data block
allocated. 
-->
<p>空ブロックを見つけた場所に関わりなく、ブロック割り当てコードはブロック
グループのブロックビットマップを更新し、バッファキャッシュにデータバッファを
割り当てる。そのデータバッファは、ファイルシステムがサポートするデバイス識別子
と割り当てられたブロックのブロック番号とによってユニークに識別される。
バッファ内のデータは 0 とされ、バッファの内容が物理ディスクに書き込まれていない
ことを示すためにそのバッファは「ダーティー(dirty)」とマークされる。最後に、
スーパーブロック自身が、変更されてロックを解除されたことを示すために
「ダーティー」とマークされる。スーパーブロックの空きを待つプロセスがある場合、
キューの最初にあるプロセスが再度実行され、ファイル操作のためにスーパーブロック
の排他的な実行制御権を獲得する。プロセスのデータが新しいデータブロックに書き込
まれ、もしそのデータブロックが満杯になると、そのプロセス全体が繰り返されて次の
データブロックが割り当てられる。

<!--9.2  The Virtual File System (VFS)-->
<sect1>仮想ファイルシステム (Virtual File System, VFS)<label 
id="chapter_fs_sect2">
<p>

<label id="figure4-1">
<!--        Figure 9.4: A Logical Diagram of the Virtual File System-->
<#if output="html">
<figure><ph vspace="1"><img src="./The-Linux-Kernel-images/figure9-4.gif">
</figure>
</#if>
<#unless output="html">
<verb>
          +---------+                    +------------+
          |         |<------------------>|   inode    |
          |   VFS   |<----------+        | キャッシュ |
          |         |           |        |            |
          +--*---*--+           |        +------------+
            /|  /|              |
     +-------+   +------+       |
     |/                 |/      |
+----*----+        +----*----+  |
|         |        |         |  |
|  MINIX  |        |  EXT2   |  |        +------------+
|         |        |         |  +------->|ディレクトリ|
+----*----+        +----*----+           | キャッシュ |
    /|                 /|                |            |
     *-------+   +------+                +------------+
             |/  |/
          +--*---*---+
          | バッファ |
          |キャッシュ|
          |          |
          +----*-----+
              /|
               |/
          +----*-----+
          | ディスク |
          | ドライブ |
          |          |
          +----------+
</verb>
</#if>
<p>図表(9.4) 仮想ファイルシステムの論理ダイアグラム

<!--
Figure  9.4 shows the relationship between the Linux kernel's Virtual File
System and it's real file systems. The virtual file system must manage all of
the different file systems that are mounted at any given time. To do this it
maintains data structures that describe the whole (virtual) file system and
the real, mounted, file systems. 
Rather confusingly, the VFS describes the system's files in terms of
superblocks and inodes in much the same way as the EXT2 file system uses
superblocks and inodes. Like the EXT2 inodes, the VFS inodes describe files
and directories within the system; the contents and topology of the Virtual
File System. From now on, to avoid confusion, I will write about VFS inodes
and VFS superblocks to distinquish them from EXT2 inodes and superblocks.
-->
<p>図表(9.4)では、Linux の仮想ファイルシステムと実(real)ファイルシステムとの
関係が示されている。仮想ファイルシステムは任意の時間にマウントされた異なる
ファイルシステムすべてを管理しなければならない。そのために、仮想ファイル
システムは、(仮想)ファイルシステム全体、およびマウントされた実(real)ファイル
システムを記述するデータ構造体を管理している。
<newline>[see: <htmlurl 
url="./The-Linux-Kernel-images/linux/fs" name="fs/*">]<newline>
やや混乱するかもしれないが、VFS は、EXT2 ファイルシステムがスーパーブロックや 
inode を利用する方法と非常に似通った方法で、システムのファイルをスーパーブロッ
クと inode を使って記述している。
EXT2 <ref id="ext2_inode" name="inode"> の場合と同様に、VFS <ref id="inode" 
name="inode"> も、システム上のファイルやディレクトリを記述している。すなわち、
仮想ファイルシステムの内容やトポロジーを VFS inode を使って記述しているわけで
ある。
ここからは、混乱を避けるために、(仮想ファイルシステムの inode やスーパー
ブロックに関しては) VFS inode や VFS スーパーブロックと書くことで、EXT2 の 
inode やスーパーブロックと区別する。

<!--
As each file system is initialised, it registers itself with the VFS. This
happens as the operating system initialises itself at system boot time. The
real file systems are either built into the kernel itself or are built as 
loadable modules. File System modules are loaded as the system needs them, so,
for example, if the VFAT file system is implemented as a kernel module, then 
it is only loaded when a VFAT file system is mounted. When a block device based
file system is mounted, and this includes the root file system, the VFS must
read its superblock. Each file system type's superblock read routine must
work out the file system's topology and map that information onto a VFS
superblock data structure. The VFS keeps a list of the mounted file systems
in the system together with their VFS superblocks. Each VFS superblock
contains information and pointers to routines that perform particular
functions. So, for example, the superblock representing a mounted EXT2 file
system contains a pointer to the EXT2 specific inode reading routine. This
EXT2 inode read routine, like all of the file system specific inode read
routines, fills out the fields in a VFS inode. Each VFS superblock contains a
pointer to the first VFS inode on the file system. For the root file system, 
this is the inode that represents the ``/'' directory. This mapping of 
information is very efficient for the EXT2 file system but moderately less so 
for other file systems. 
-->
<p>個々のファイルシステムが初期化されると、それは VFS に登録される。これは、
システムのブート時、オペレーティングシステムが初期化される際に行われる。
実(real)ファイルシステムは、カーネルに組み込まれているか、ローダブルモジュール
としてビルドされているかのいずれかである。ファイルシステムモジュールは、システ
ムがそれを必要とするときにロードされるので、たとえば、VFAT ファイルシステムが
カーネルモジュールとして実装されている場合、それは VFAT ファイルシステムがマウ
ントされたときにのみロードされる。ブロックデバイスベースのファイルシステムが
マウントされ、ルートファイルシステムに組み込まれると、VFS はそのファイルシステ
ムが持つスーパーブロックのデータ構造体を読み込まなければならない。
ファイルシステムタイプごとのスーパーブロック読み込みルーチンは、そのファイル
システムのトポロジーを読み解いて、その情報を VFS スーパーブロックのデータ構造体
にマップする。
VFS は、VFS スーパーブロックを保持すると同時に、システム上のマウントされた
ファイルシステムに関するリストを保持しなければならない。
個々の VFS スーパーブロックには、特定の機能を担当するルーチンの情報と、その
ルーチンへのポインタが含まれている。それゆえ、たとえば、マウントされた EXT2 
ファイルシステムを表すスーパーブロックには、EXT2 固有の inode 読み込みルーチン
へのポインタが含まれている。
この EXT2 inode 読み込みルーチンは、ファイルシステム固有の inode 読み込みルーチ
ンすべてに共通することでもあるが、VFS inode のフィールドに必要な情報を記入
する。個々の VFS スーパーブロックには、そのファイルシステム上の最初の VFS 
inode へのポインタが含まれている。ルートファイルシステムの場合、それは "<tt>/
</tt>" ディレクトリを表す inode である。こうした情報のマッピングは EXT2 ファイ
ルシステムの場合は非常に効率的に行われるが、他のファイルシステムに対してはやや
効率が落ちる。

<!--
As the system's processes access directories and files, system routines are
called that traverse the VFS inodes in the system. 
For example, typing ls for a directory or cat for a file cause the the Virtual
File System to search through the VFS inodes that represent the file system.
As every file and directory on the system is represented by a VFS inode, then
a number of inodes will be being repeatedly accessed. These inodes are kept
in the inode cache which makes access to them quicker. If an inode is not in
the inode cache, then a file system specific routine must be called in order to
read the appropriate inode. The action of reading the inode causes it to be put
into the inode cache and further accesses to the inode keep it in the cache.
The less used VFS inodes get removed from the cache. 
-->
<p>システム上のプロセスがディレクトリやファイルにアクセスする際、システムの
ルーチンはシステム上の VFS <ref id="inode" name="inode"> を経由して呼び出さ
れる。
<newline>[see: <htmlurl 
url="./The-Linux-Kernel-images/linux/fs/inode.c" 
name="fs/inode.c">]<newline>
たとえば、ディレクトリ上で <tt>ls</tt> とタイプするか、ファイルに対して <tt>cat
</tt> とタイプした場合、仮想ファイルシステムは、そのファイルシステムを表す VFS 
inode 群を検索する。
システム上の全ファイルとディレクトリは VFS inode によって表現されているので、
いくつかの inode が繰り返しアクセスされる。それらの inode は inode キャッシュに
保存されて、それらに対するアクセス速度の向上が図られる。inode キャッシュに 
inode がない場合、適切な inode を読み込むためにファイルシステム固有のルーチンが
呼び出される。inode を読み込む処理によって、inode は inode キャッシュに入れら
れ、その inode への更なるアクセスによってキャッシュに保存されたままとなる。
ほとんど使用されない VFS inode はキャッシュから削除される。

<!--
All of the Linux file systems use a common buffer cache to cache data
buffers from the underlying devices to help speed up access by all of the file
systems to the physical devices holding the file systems. 
This buffer cache is independent of the file systems and is integrated into the
mechanisms that the Linux kernel uses to allocate and read and write data
buffers. It has the distinct advantage of making the Linux file systems
independent from the underlying media and from the device drivers that
support them. All block structured devices register themselves with the Linux
kernel and present a uniform, block based, usually asynchronous interface.
Even relatively complex block devices such as SCSI devices do this. As the
real file systems read data from the underlying physical disks, this results in
requests to the block device drivers to read physical blocks from the device
that they control. Integrated into this block device interface is the buffer
cache. As blocks are read by the file systems they are saved in the global
buffer cache shared by all of the file systems and the Linux kernel. Buffers
within it are identified by their block number and a unique identifier for the
device that read it. So, if the same data is needed often, it will be retrieved
from the buffer cache rather than read from the disk, which would take
somewhat longer. Some devices support read ahead where data blocks are
speculatively read just in case they are needed. 
-->
<p>すべての Linux ファイルシステムは、共通のバッファキャッシュを利用して、基礎
となるデバイスのデータバッファをキャッシュする。これは、ファイルシステムが、そ
のファイルシステムを保持する物理デバイスにアクセスする際、アクセス速度の向上に
役立つ。
<newline>[see: <htmlurl 
url="./The-Linux-Kernel-images/linux/fs/buffer.c" 
name="fs/buffer.c">]<newline>
このバッファキャッシュは、ファイルシステムから独立している。そして、それは、
Linux カーネルがデータバッファの割り当て、読み出し、書き込みのために使用する
メカニズムの中に組み込まれている。これによって Linux のファイルシステムは、
基礎となるメディアやそれをサポートするデバイスドライバから独立できるので、
その仕組みは Linux の明らかな長所となっている。
ブロック構造を持つデバイスはすべて、Linux カーネルに登録され、ブロックベース
の、一般に非同期な、統一的インターフェイスを提供する。SCSI のような比較的複雑な
デバイスでも同様である。実(real)ファイルシステムが基礎となる物理デバイスから
データを読み込む場合、実際にはブロックデバイスドライバにリクエストを送り、ドラ
イバが、その制御するデバイスから物理ブロックを読み込む。このブロックデバイスの
インターフェイスに組み込まれているのが、バッファキャッシュである。
ファイルシステムによってブロックが読み込まれると、それらのブロックは、すべての
ファイルシステムと Linux カーネルによって共有される包括的なバッファに保存され
る。バッファ内の個々のブロックは、ブロック番号とそれを読み込んだデバイス固有の
識別子とによって識別される。したがって、同じデータがしばしば必要とされる場合、
それは、時間のかかるディスクからの読み出しを利用するのではなく、バッファキャッ
シュから取り出される。デバイスの中には先読みをサポートするものがあるが、それは
データブロックが必要とされる場合に備えて、予め予測されるデータブロックを読み込
んでおく機能である。

<!--
The VFS also keeps a cache of directory lookups so that the inodes for
frequently used directories can be quickly found. 
As an experiment, try listing a directory that you have not listed recently. 
The first time you list it, you may notice a slight pause but the second time 
you list its contents the result is immediate. The directory cache does not 
store the inodes for the directories itself; these should be in the inode 
cache, the directory cache simply stores the mapping between the full 
directory names and their inode numbers. 
-->
<p>VFS は、頻繁に使用されるディレクトリをすばやく見つけるために、検索された
ディレクトリのキャッシュをも保持している。
<newline>[see : <htmlurl 
url="./The-Linux-Kernel-images/linux/fs/dcache.c" 
name="fs/dcache.c">]<newline>
実験として、最近表示したことがないディレクトリを表示してみるとそれが分かる。
最初に表示した際、やや時間が掛かるのに気付くが、二度目にその内容が表示される時
は、結果が即座に出る。ディレクトリキャッシュはディレクトリの inode そのものを
保存するのではない。それらは inode キャッシュ内になければならず、ディレクトリ
キャッシュは、完全なディレクトリ名とその inode 番号だけを保存している。

<!--9.2.1  The VFS Superblock-->
<sect2>VFS スーパーブロック<label id="chapter_fs_sect2-1">

<!--
Every mounted file system is represented by a VFS superblock; amongst
other information, the VFS superblock contains the: 
-->
<p>マウントされたすべてのファイルシステムは、VFS スーパーブロックによって
表現される。VFS スーパーブロックは様々な情報を含んでいるが、次にその一部を
示す。
<newline>[see: <htmlurl 
url="./The-Linux-Kernel-images/linux/include/linux/fs.h" 
name="include/linux/fs.h">]<newline>

<!--
Device This is the device identifier for the block device that this file system
      is contained in. For example, /dev/hda1, the first IDE hard disk in
      the system has a device identifier of 0x301, 
-->
<descrip>
<tag>デバイス (device)</tag>
これは、そのファイルシステムが含まれているブロックデバイスのデバイス識別子で
ある。たとえば、システム上の最初の IDE ハードディスクである <tt>/dev/hda1</tt> 
のデバイス識別子は、0x301 である。

<!--
Inode pointers
      The mounted inode pointer points at the first inode in this file
      system. The covered inode pointer points at the inode representing
      the directory that this file system is mounted on. The root file
      system's VFS superblock does not have a covered pointer, 
-->
<tag>inode ポインタ (inode pointer)</tag>
inode ポインタ <tt><ref id="super_block" name="mounted"></tt> は、そのファイ
ルシステムの最初の inode をポイントするポインタである。inode ポインタ <tt><ref 
id="super_block" name="covered"></tt> は、そのファイルシステムがマウントされた
ディレクトリを表す inode をポイントするポインタである。
ルートファイルシステムの VFS スーパーブロックには、<tt>covered</tt> ポインタ
は含まれない。

<!--
Blocksize
      The block size in bytes of this file system, for example 1024 bytes, 
-->
<tag>ブロックサイズ (blocksize)</tag>
バイト単位で表されるそのファイルシステムのブロックサイズ。たとえば、1024 バイ
ト。

<!--
Superblock operations
      A pointer to a set of superblock routines for this file system.
      Amongst other things, these routines are used by the VFS to read and
      write inodes and superblocks. 
-->
<tag>スーパーブロック操作ルーチン (superblock operations)</tag>
そのファイルシステムに対する一連のスーパーブロック操作ルーチンへのポインタ。
それらの中には、VFS が inode とスーパーブロックの読み書きに使用するルーチンが
ある。

<!--
File System type
      A pointer to the mounted file system's file_system_type data
      structure, 
-->
<tag>ファイルシステムタイプ (file system type)</tag>
マウントされたファイルシステムの <tt><ref id="file_system_type" 
name="file_system_type"></tt> データ構造体へのポインタ。

<!--
File System specific
      A pointer to information needed by this file system, 
-->
<tag>ファイルシステム固有の情報 (file system specific)</tag>
そのファイルシステムにとって必要な情報へのポインタ

</descrip>

<!--9.2.2  The VFS Inode-->
<sect2>VFS inode<label id="chapter_fs_sect2-2">

<!--
Like the EXT2 file system, every file, directory and so on in the VFS is
represented by one and only one VFS inode. 
The information in each VFS inode is built from information in the underlying
file system by file system specific routines. VFS inodes exist only in the
kernel's memory and are kept in the VFS inode cache as long as they are
useful to the system. Amongst other information, VFS inodes contain the
following fields: 
-->
<p>EXT2 ファイルシステムと同様に、VFS 上のすべてのファイルやディレクトリ等は
ユニークな VFS <ref id="inode" name="inode"> によって表現される。
<newline>[see: <htmlurl 
url="./The-Linux-Kernel-images/linux/include/linux/fs.h" 
name="include/linux/fs.h">]<newline>
個々の VFS inode 内の情報は、ファイルシステム固有のルーチンによって、その
基礎となるファイルシステム内の情報から組み立てられる。VFS inode はカーネル
メモリ上にしか存在せず、システムにとって有益である間だけ VFS inode キャッシュ
に保存される。VFS inode に含まれる情報には種種のものがあるが、次にその一部を
示す。

<!--
device This is the device identifer of the device holding the file or whatever
      that this VFS inode represents, 
-->
<descrip>
<tag>デバイス (device)</tag>
これは、ファイルか当該 VFS inode が指すものを保持しているデバイスのデバイス
識別子である。

<!--
inode number
      This is the number of the inode and is unique within this file system.
      The combination of device and inode number is unique within the
      Virtual File System, 
-->
<tag>inode 番号 (inode number)</tag>
これは、その inode の番号であり、それはそのファイルシステム内でユニークな値で
ある。デバイスと inode 番号の組み合わせは、その VFS 上において重複することは
ない。

<!--
mode Like EXT2 this field describes what this VFS inode represents as
      well as access rights to it, 
-->
<tag>モード (mode)</tag>
<ref id="chapter_fs_ext2_mode" name="EXT2"> と同様に、このフィールドが示すの
は、その VFS inode が表す対象とそれに対するアクセス権である。

<!--
user ids
      The owner identifiers, 
-->
<tag>ユーザ ID (user ids)</tag>
所有者の識別子。

<!--
times The creation, modification and write times, 
-->
<tag>時間 (times)</tag>
作成、修正、書き込みが起こった時間。

<!--
block size
      The size of a block for this file in bytes, for example 1024 bytes, 
-->
<tag>ブロックサイズ (block size)</tag>
バイト単位で表されるそのファイルのブロックサイズ。たとえば 1024 バイト。

<!--
inode operations
      A pointer to a block of routine addresses. These routines are specific
      to the file system and they perform operations for this inode, for
      example, truncate the file that is represented by this inode. 
-->
<tag>inode 操作 (inode operations)</tag>
ルーチンのアドレス群へのポインタ。それらのルーチンはファイルシステムに固有で
あり、たとえば、その inode が指すファイルを切り縮めるといった、当該 inode に
対する操作を実行する。

<!--
count The number of system components currently using this VFS inode. A
      count of zero means that the inode is free to be discarded or reused, 
-->
<tag>カウント (count)</tag>
現在その VFS inode を使用しているコンポーネントの数。カウント 0 は、その 
inode が使用されておらず、破棄するか再利用されるべきことを意味する。

<!--
lock This field is used to lock the VFS inode, for example, when it is being
      read from the file system, 
-->
<tag>ロック (lock)</tag>
このフィールドは VFS inode をロックする際に使用される。たとえば、ファイルシステ
ムから読み出されている場合など。

<!--
dirty Indicates whether this VFS inode has been written to, if so the
      underlying file system will need modifying, 
-->
<tag>ダーティー (dirty)</tag>
その VFS inode が書き込みをされたかどうかを示す。もしそうである場合、その
基礎となるファイルシステムは適宜修正される必要がある。

<!--
file system specific information
-->
<tag>ファイル (file)</tag>
ファイルシステム固有の情報。

</descrip>

<!--9.2.3  Registering the File Systems-->
<sect2>ファイルシステムの登録<label id="chapter_fs_sect2-3">
<p>

<label id="figure9-5">
<!--                Figure 9.5: Registered File Systems-->
<#if output="html">
<figure><ph vspace="1"><img src="./The-Linux-Kernel-images/figure9-5.gif">
</figure>
</#if>
<#unless output="html">
<verb>
+---file_systems
|
|
|  file_system_type     file_system_type      file_system_type
|  +-------------+      +-------------+      +-------------+
+->|*read_super()|  +-->|*read_super()|  +-->|*read_super()|
   |-------------|  |   |-------------|  |   |-------------|
   | name        |"ext2"| name        |"proc"| name        |"iso9660"
   |-------------|  |   |-------------|  |   |-------------|
   | requires_dev|  |   | requires_dev|  |   | requires_dev|
   |-------------|  |   |-------------|  |   |-------------|
   | next        |--+   | next        |--+   | next        |
   +-------------+      +-------------+      +-------------+
</verb>
</#if>
<p>図表(9.5) ファイルシステムの登録

<!--
When you build the Linux kernel you are asked if you want each of the
supported file systems. When the kernel is built, the file system startup code
contains calls to the initialisation routines of all of the built in file 
systems. 
Linux file systems may also be built as modules and, in this case, they may
be demand loaded as they are needed or loaded by hand using insmod.
Whenever a file system module is loaded it registers itself with the kernel
and unregisters itself when it is unloaded. Each file system's initialisation
routine registers itself with the Virtual File System and is represented by a
file_system_type data structure which contains the name of the file
system and a pointer to its VFS superblock read routine. Figure  9.5 shows
that the file_system_type data structures are put into a list pointed at by
the file_systems pointer. Each file_system_type data structure
contains the following information: 
-->
<p>Linux カーネルをビルドするとき、サポートされている個々のファイルシステム
をカーネルに組み込むかどうか質問がなされる。カーネルがビルドされると、ファイル
システム初期化コードには、組み込まれたファイルシステムすべてに関する初期化
ルーチンへの呼び出しコードが含められる。
<newline>[see: sys_setup(), in <htmlurl 
url="./The-Linux-Kernel-images/linux/fs/filesystems.c" 
name="fs/filesystems.c">]<newline>
Linux のファイルシステムは、モジュールとしてもビルドすることができる。
その場合、それらは必要に応じてオンデマンドでロードされるか、<tt>insmod</tt> 
コマンドを使用して手動でロードされる。
ファイルシステムモジュールがロードされるときはいつも、それがカーネルに登録
され、ロードが解除されると登録が取り消される。
個々のファイルシステムの初期化ルーチンは仮想ファイルシステムに登録され、
<tt><ref id="file_system_type" name="file_system_type"></tt> データ構造体に
よって表現される。その構造体にはファイルシステムの名前と VFS スーパーブロック
読み込みルーチンへのポインタが含まれている。
<ref id="figure9-5" name="図表(9.5)">では、<tt>file_system_type</tt> データ構造
体が、<tt><ref id="file_system_type" name="file_systems"></tt> リストに登録
され、そのポインタによってポイントされる様子が示されている。個々の <tt>
file_system_type</tt> データ構造体には次のような情報が含まれている。
<newline>[see: file_system_type, in <htmlurl 
url="./The-Linux-Kernel-images/linux/include/linux/fs.h" 
name="include/linux/fs.h">]
<!--
Superblock read routine
      This routine is called by the VFS when an instance of the file system
      is mounted, 
-->
<descrip>
<tag>スーパーブロック読み込みルーチン (superblock read routine)</tag>
このルーチンは、具体的なファイルシステムがマウントされたときに VFS によって
呼び出される。

<!--
File System name
      The name of this file system, for example ext2, 
-->
<tag>ファイルシステム名 (file system name)</tag>
ファイルシステムの名前。たとえば、ext2 など。

<!--
Device needed
      Does this file system need a device to support? Not all file system
      need a device to hold them. The /proc file system, for example, does
      not require a block device, 
-->
<tag>必要なデバイス (device needed)</tag>
そのファイルシステムは、サポートするデバイスが必要か？ すべてのファイルシステム
がそれを保持するデバイスを必要とするわけではない。たとえば、<tt>/proc</tt> 
ファイルシステムはブロックデバイスを必要としない。
</descrip>

<!--
You can see which file systems are registered by looking in at
/proc/filesystems. For example: 
-->
<p>どのファイルシステムが登録されているか知るには、<tt>/proc/filesystems</tt> 
を覗けばよい。たとえば、次のように表示されるだろう。

<verb>
      ext2
nodev proc
      iso9660
</verb>

<!--9.2.4  Mounting a File System-->
<sect2>ファイルシステムのマウント<label id="chapter_fs_sect2-4">

<!--
When the superuser attempts to mount a file system, the Linux kernel must
first validate the arguments passed in the system call. Although mount does
some basic checking, it does not know which file systems this kernel has
been built to support or that the proposed mount point actually exists.
Consider the following mount command: 
-->
<p>スーパーユーザがファイルシステムをマウントするとき、Linux はまず、システム
コールに渡される引数の妥当性検査をしなければならない。<tt>mount</tt> コマンド
も基本的なチェックは行うが、現在のカーネルにどのファイルシステムへのサポート
が組み込まれているかや、ユーザによって指定されたマウントポイントが実際に存在
するかといったことは知らないからである。次の <tt>mount</tt> コマンドについて
考えてほしい。

<verb>
$ mount -t iso9660 -o ro /dev/cdrom /mnt/cdrom
</verb>

<!--
This mount command will pass the kernel three pieces of information; the
name of the file system, the physical block device that contains the file
system and, thirdly, where in the existing file system topology the new file
system is to be mounted. 
-->
<p>この <tt>mount</tt> コマンドはカーネルに 3 つの情報を渡す。ファイルシステム
名、ファイルシステムを含んでいる物理ブロックデバイス、そして 3 つ目に、
現存するファイルシステムのトポロジーにおいて、新しいファイルシステムがどこに
マウントされるべきかということである。
<newline>[see: do_mount(), in <htmlurl
url="./The-Linux-Kernel-images/linux/fs/super.c" 
name="fs/super.c">]
<newline>[see: get_fs_type(), in <htmlurl 
url="./The-Linux-Kernel-images/linux/fs/super.c" 
name="fs/super.c">]<newline>
<!--
The first thing that the Virtual File System must do is to find the file 
system. To do this it searches through the list of known file systems by 
looking at each file_system_type data structure in the list pointed at by
file_systems. If it finds a matching name it now knows that this file system 
type is supported by this kernel and it has the address of the file system 
specific routine for reading this file system's superblock. If it cannot find 
a matching file system name then all is not lost if the kernel is built to 
demand load kernel modules (see Chapter  modules-chapter). In this case the 
kernel will request that the kernel daemon loads the appropriate file system 
module before continuing as before. 
-->
<p>仮想ファイルシステムが最初にすべきことは、そのファイルシステムを見つける
ことである。そのために既知のファイルシステムのリストを走査するのだが、それは
 <tt><ref id="file_system_type" name="file_systems"></tt> によってポイントされ
たリストの中にある <tt><ref id="file_system_type" name="file_system_type">
</tt> データ構造体を個別に探すことによってなされる。
そして、該当する名前が見つかった場合、次にそのファイルシステムが現在のカーネル
でサポートされていること、および現在のカーネルにそのファイルシステムのスーパー
ブロックを読み出すためのファイルシステム固有のルーチンのアドレスが含まれている
ことが分かる。
合致するファイルシステム名を見つけられなかった場合でも、カーネルがオンデマンド
でカーネルモジュールをロードするようビルドされているなら(詳細は<ref 
id="chapter_m" name="「モジュール」">を参照のこと)、処理は継続する。その場合、
カーネルは元の作業を続ける前にカーネルデーモンに対して適切なファイルシステム
をデマンドローディングするようリクエストする。

<!--
Next if the physical device passed by mount is not already mounted, it must
find the VFS inode of the directory that is to be the new file system's mount
point. This VFS inode may be in the inode cache or it might have to be read
from the block device supporting the file system of the mount point. Once the
inode has been found it is checked to see that it is a directory and that there
is not already some other file system mounted there. The same directory
cannot be used as a mount point for more than one file system. 
-->
<p>次に、<tt>mount</tt> によって渡された物理デバイスがまだマウントされていない
場合、新しいファイルシステムのマウントポイントとなるディレクトリの VFS inode 
を見つけなければならない。その VFS inode は、inode キャッシュにあるか、マウント
ポイントがあるファイルシステムをサポートするブロックデバイスから読み出すか
される。inode が分かったら、それがディレクトリかどうか、すでに他のファイル
システムがそこにマウントされていないかどうかを確認するためのチェックがなされ
る。複数のファイルシステムに対するマウントポイントとしては、同一のディレクトリ
は使用できないからである。

<!--
At this point the VFS mount code must allocate a VFS superblock and pass it
the mount information to the superblock read routine for this file system. All
of the system's VFS superblocks are kept in the super_blocks vector of
super_block data structures and one must be allocated for this mount. The
superblock read routine must fill out the VFS superblock fields based on
information that it reads from the physical device. For the EXT2 file system
this mapping or translation of information is quite easy, it simply reads the
EXT2 superblock and fills out the VFS superblock from there. For other file
systems, such as the MS DOS file system, it is not quite such an easy task.
Whatever the file system, filling out the VFS superblock means that the file
system must read whatever describes it from the block device that supports
it. If the block device cannot be read from or if it does not contain this 
type of file system then the mount command will fail. 
-->
<p>この時点で、VFS のマウント処理コードは VFS スーパーブロックを割り当てて、
そのファイルシステムのスーパーブロック読み込みルーチンに対してそのマウント
情報を渡さなければならない。VFS スーパーブロックのすべては <tt><ref 
id="super_block" name="super_block"></tt> データ構造体の <tt><ref 
id="super_block" name="super_blocks"></tt> 配列に保存されているので、その
ひとつが、当該マウントのために割り当てられなければならない。スーパーブロック
読み込みルーチンは、それが物理デバイスから読み出しだ情報を基にして VFS 
スーパーブロックのフィールドを適切な情報で埋めなければならない。
EXT2 ファイルシステムに関しては、この情報のマッピングもしくは変換は非常に簡単で
ある。しかし、MS-DOS ファイルシステムのようなその他のファイルシステムに関して
は、それほど簡単なタスクではない。ファイルシステムが何であれ、VFS スーパー
ブロックのフィールドを埋めることは、それをサポートするブロックデバイスから、
それが示すすべての情報を読み出さなければならないことを意味する。
ブロックデバイスから読み出しができない場合、もしくはデバイスがそのタイプの
ファイルシステムを含まない場合は、<tt>mount</tt> コマンドは失敗に終わる。

<label id="figure9-6">
<!--                Figure 9.6: A Mounted File System-->
<#if output="html">
<figure><ph vspace="1"><img src="./The-Linux-Kernel-images/figure9-6.gif">
</figure>
</#if>
<#unless output="html">
<verb>
+---vfsmntlist
|
|
|    vfsmount
|  +-----------+
+->| mnt_dev   | 0x0301
   |-----------|
   |mnt_devname| /dev/hda1
   |-----------|
   |mnt_dirname| /
   |-----------|
   | mnt_flags |
   |-----------|          VFS
   | mnt_sb    |-+    super_block            file_system_type
   |-----------| |  +-------------+          +---------------+
   |           | +->| s_dev       |0x0301 +->| *read_super() |
   |-----------|    |-------------|       |  |---------------|
   | next      |    | s_blocksize |1024   |  | name          |"ext2"
   +-----------+    |-------------|       |  |---------------|
                    | s_type      |-------+  | requires_dev  |
                    |-------------|          |---------------|
                    | s_flags     |          | next          |
                    |-------------|          +---------------+
                    | s_covered   |
                    |-------------|          VFS
                    | s_mounted   |--+      inode
                    |             |  |    +---------+
                    +-------------+  +--->| i_dev   | 0x0301
                                          | i_ino   | 42
                                          |         |
                                          +---------+
</verb>
</#if>
<p>図表(9.6) マウントされたファイルシステム

<!--
Each mounted file system is described by a vfsmount data structure; see
figure  9.6. These are queued on a list pointed at by vfsmntlist. 
Another pointer, vfsmnttail points at the last entry in the list and the
mru_vfsmnt pointer points at the most recently used file system. Each
vfsmount structure contains the device number of the block device holding
the file system, the directory where this file system is mounted and a pointer
to the VFS superblock allocated when this file system was mounted. In turn
the VFS superblock points at the file_system_type data structure for
this sort of file system and to the root inode for this file system. This 
inode is kept resident in the VFS inode cache all of the time that this file 
system is loaded. 
-->
<p>マウントされた個々のファイルシステムは、<tt><ref id="vfsmount" 
name="vfsmount"></tt> データ構造体によって記述される。図表(9.6)を見て欲しい。
それらは <tt><ref id="vfsmount" name="vfsmntlist"></tt> によってポイントされた
リスト上に待ち行列を作っている。
<newline>[see: add_vfsmnt(), in <htmlurl 
url="./The-Linux-Kernel-images/linux/fs/super.c" 
name="fs/super.c">]<newline>
別のポインタである <tt><ref id="vfsmount" name="vfsmnttail"></tt> は、リストの
最後のエントリをポイントしており、<tt><ref id="vfsmount" name="mru_vfsmnt">
</tt> ポインタは最も最近利用されたファイルシステムをポイントしている。
個々の <tt>vfsmount</tt> データ構造体には、そのファイルシステムを保持する
ブロックデバイスのデバイス番号、そのファイルシステムがマウントされている
ディレクトリ、そしてそのファイルシステムがマウントされた時に割り付けられた VFS
 スーパーブロックへのポインタが含まれている。さらに、VFS スーパーブロックは、
該当する種類のファイルシステムに関する <tt><ref id="file_system_type" 
name="file_system_type"></tt> データ構造体とそのファイルシステムのルート inode 
をポイントしている。この inode は、そのファイルシステムがロードされている間は、
 VFS inode キャッシュのなかに保存される。

<!--9.2.5  Finding a File in the Virtual File System-->
<sect2>仮想ファイルシステム内でのファイルの検索<label 
id="chapter_fs_sect2-5">

<!--
To find the VFS inode of a file in the Virtual File System, VFS must resolve
the name a directory at a time, looking up the VFS inode representing each of
the intermediate directories in the name. Each directory lookup involves
calling the file system specific lookup whose address is held in the VFS inode
representing the parent directory. This works because we always have the
VFS inode of the root of each file system available and pointed at by the VFS
superblock for that system. Each time an inode is looked up by the real file
system it checks the directory cache for the directory. If there is no entry in
the directory cache, the real file system gets the VFS inode either from the
underlying file system or from the inode cache. 
-->
<p>仮想ファイルシステム上でファイルの VFS <ref id="inode" name="inode"> を探す
ためには、VFS は、名前に含まれる個々のディレクトリを表す VFS inode を問い合わせ
ながら、ディレクトリごとにその名前解決をしなければならない。
個々のディレクトリ問い合わせの際には、ファイルシステム固有の問い合わせルーチン
が呼び出される。そのルーチンのアドレスはその親ディレクトリを表す VFS inode 内に
保持されている。これが上手くいくのは、個々のファイルシステムのルートディレクト
リの VFS inode は、そのシステムの VFS スーパーブロックによってポイントされてい
るので、必ず知ることができるからである。
実(real)ファイルシステムによって inode が問い合わせされるたびに、ディレクトリ
用のディレクトリキャッシュがチェックされる。ディレクトリキャッシュにエントリが
ない場合、実ファイルシステムは VFS inode を基礎となるファイルシステムからか、
inode キャッシュからのいずれかから取得する。

<!--9.2.6  Creating a File in the Virtual File System-->
<sect2>仮想ファイルシステム上でのファイルの作成<label id="chapter_fs_sect2-6">
<p>(訳注: この部分の原文が存在しません。)

<!--9.2.7  Unmounting a File System-->
<sect2>ファイルシステムのマウント解除<label id="chapter_fs_sect2-7">

<!--
The workshop manual for my MG usually describes assembly as the reverse
of disassembly and the reverse is more or less true for unmounting a file
system. 
A file system cannot be unmounted if something in the system is using one of
its files. So, for example, you cannot umount /mnt/cdrom if a process is
using that directory or any of its children. If anything is using the file 
system to be unmounted there may be VFS inodes from it in the VFS inode cache,
and the code checks for this by looking through the list of inodes looking for
inodes owned by the device that this file system occupies. If the VFS
 superblock for the mounted file system is dirty, that is it has been modified,
then it must be written back to the file system on disk. Once it has been
written to disk, the memory occupied by the VFS superblock is returned to
the kernel's free pool of memory. Finally the vfsmount data structure for
this mount is unlinked from vfsmntlist and freed. 
-->
<p>わたしの愛車である MG の整備マニュアルにはたいていの場合「組み立ては
分解の逆である」としか説明されていないが、これはファイルシステムの
アンマウントに関する説明にも程度の差はあれ言えることだろう。
<newline>[see: do_unmount(), in <htmlurl 
url="./The-Linux-Kernel-images/linux/fs/super.c" 
name="fs/super.c">]<newline>
システム上のファイルシステム内にあるファイルのひとつが何らかのかたちで使用され
ている場合、そのファイルシステムはアンマウントできない。それゆえ
たとえば、プロセスが <tt>/mnt/cdrom</tt> のディレクトリやその子ディレクトリを
使用している場合、そのディレクトリはアンマウントできない。アンマウントすべき
ファイルシステムが何らかのかたちで使用されている場合、そのファイルシステムの 
VFS inode が VFS inode キャッシュにあるかもしれないので、コードはそれをチェック
するために、inode リストを走査し、そのファイルシステムがあるデバイスによって
所有されている inode を探す。マウントされたファイルシステムに関する VFS 
スーパーブロックがダーティー(dirty)な場合、それは修正されているということなの
で、修正されたの内容をディスク上のファイルシステムに書き込まれなければならな
い。ディスクへの書き込みが終了したら、VFS スーパーブロックに占有されていた
メモリは、カーネルの空きメモリのプールに戻される。最後に、そのマウントに関する 
<tt><ref id="vfsmount" name="vfsmount"></tt> データ構造体は、<tt><ref 
id="vfsmount" name="vfsmntlist"></tt> からのリンクを外され、解放される。
<newline>[see: remove_vfsmnt(), in <htmlurl 
url="./The-Linux-Kernel-images/linux/fs/super.c" 
name="fs/super.c">]

<!--9.2.8  The VFS Inode Cache-->
<sect2>VFS inode キャッシュ<label id="chapter_fs_sect2-8">

<!--
As the mounted file systems are navigated, their VFS inodes are being
continually read and, in some cases, written. The Virtual File System
maintains an inode cache to speed up accesses to all of the mounted file
systems. Every time a VFS inode is read from the inode cache the system
saves an access to a physical device. 
-->
<p>マウントされたファイルシステムを操作する際には、そのファイルシステム
の VFS inode が何度も読み出されたり、ある場合には書き込まれたりする。
仮想ファイルシステムは、inode キャッシュを管理して、マウントされたすべての
ファイルシステムへのアクセスを高速化している。
VFS inode が inode キャッシュから読み出されたとき、システムは物理デバイスへの
アクセスを省くことができる。
<newline>[see: <htmlurl 
url="./The-Linux-Kernel-images/linux/fs/inode.c" 
name="fs/inode.c">]

<!--
The VFS inode cache is implmented as a hash table whose entries are
pointers to lists of VFS inodes that have the same hash value. The hash value
of an inode is calculated from its inode number and from the device identifier
for the underlying physical device containing the file system. Whenever the
Virtual File System needs to access an inode, it first looks in the VFS inode
cache. To find an inode in the cache, the system first calculates its hash
value and then uses it as an index into the inode hash table. This gives it a
pointer to a list of inodes with the same hash value. It then reads each inode
in turn until it finds one with both the same inode number and the same device
identifier as the one that it is searching for. 
-->
<p>VFS inode キャッシュは、ハッシュテーブルとして実装されていて、そのエントリ
は、同じハッシュ値を持つ VFS inode のリストへのポインタとなっている。inode の
ハッシュ値は、その inode 番号と、ファイルシステムを保持する下位の物理デバイス
のデバイス識別子によって計算される。仮想ファイルシステムが inode にアクセスする
必要があるときは、システムはまずそのハッシュ値を計算し、それを inode ハッシュ
テーブルへのインデックスとして使用する。それによってシステムは、同じハッシュ値
を持つ inode のリストへのポインタを取得する。そして、個々の inode を順番に
読み出して、探している inode と同一の inode 番号とデバイス識別子の両方を
持つ inode を見つける。

<!--
If it can find the inode in the cache, its count is incremented to show that it
has another user and the file system access continues. Otherwise a free VFS
inode must be found so that the file system can read the inode from memory.
VFS has a number of choices about how to get a free inode. If the system
may allocate more VFS inodes then this is what it does; it allocates kernel
pages and breaks them up into new, free, inodes and puts them into the inode
list. All of the system's VFS inodes are in a list pointed at by first_inode
as well as in the inode hash table. If the system already has all of the inodes
that it is allowed to have, it must find an inode that is a good candidate to 
be reused. Good candidates are inodes with a usage count of zero; this 
indicates that the system is not currently using them. Really important VFS 
inodes, for example the root inodes of file systems always have a usage count 
greater than zero and so are never candidates for reuse. Once a candidate for 
reuse has been located it is cleaned up. The VFS inode might be dirty and in 
this case it needs to be written back to the file system or it might be locked
and in this case the system must wait for it to be unlocked before continuing.
The candidate VFS inode must be cleaned up before it can be reused. 
-->
<p>キャッシュに inode が見つかった場合、その inode のカウント値に 1 が足され、
その inode には他にもユーザがいて、ファイルシステムへのアクセスが継続しているこ
とが示される。
見つからない場合、フリーの VFS inode を見つけて、ファイルシステムがメモリから 
inode を読み込めるようにしなければならない。
VFS がフリーの inode を取得する方法は、複数ある。
システムがより多くの VFS inode を割り当ててもよい場合は、VFS は新規の inode を
割り当てる。VFS はカーネルページを割り当てて、そのページを新規のフリー inode に
分割し、それらを inode リストに入れる。システム上の VFS inode はすべて、inode 
ハッシュテーブルにあると同時に、<tt><ref id="first_inode" name="first_inode">
</tt> によってポイントされるリストにも存在する。
システムがすでに使用できるすべての inode を使い切っている場合、システムは再利用
されるのにふさわしい inode の候補を探さなければならない。
候補は、0 の利用カウントを付けられた inode である。これは、システムが現在その 
inode を使用していないことを示している。たとえば、ファイルシステムのルート 
inode のような本当に重要な VFS inode は常に 0 以上の利用カウントを持っている
ので、再利用候補には決してならない。再利用の候補が特定されたら、それは消去
される。VFS inode はダーティー(dirty)になっているかもしれないので、その場合は
ファイルシステムに書き戻される必要があるが、それ以外にもその inode がロックされ
ている場合があり、その際にシステムは処理を継続する前にロックが解除されるのを待
たなければならない。VFS inode の候補は、再利用される前に消去されなければならな
い。

<!--
However the new VFS inode is found, a file system specific routine must be
called to fill it out from information read from the underlying real file 
system. Whilst it is being filled out, the new VFS inode has a usage count of 
one and is locked so that nothing else accesses it until it contains valid 
information. 
-->
<p>新規の VFS inode を見つけ出す方法に関わらず、ファイルシステム固有のルーチン
が呼び出されて、基礎となる実ファイルシステムから読み出された情報でその inode の
フィールドを埋める必要がある。その情報が書き込まれている間、新しい VFS inode 
は、利用カウント 1 を設定され、有効な情報を所持するようになるまでどこからもアク
セスされないようにロックされる。

<!--
To get the VFS inode that is actually needed, the file system may need to
access several other inodes. This happens when you read a directory; only
the inode for the final directory is needed but the inodes for the intermediate
directories must also be read. As the VFS inode cache is used and filled up,
the less used inodes will be discarded and the more used inodes will remain in
the cache. 
-->
<p>実際に必要な VFS inode を見つけだすために、ファイルシステムは他のいくつかの
 inode にアクセスしなければならない場合がある。これが起こるのはディレクトリの
読み込みのときである。最後のディレクトリの inode だけが必要なのだが、その途中
にあるディレクトリの inode も読み込まなければならない。VFS inode キャッシュが
使用され、それが満杯になると、ほとんど使われない inode は破棄され、より利用頻度
の高い inode がキャッシュに残る。

<!--9.2.9  The Directory Cache-->
<sect2>ディレクトリキャッシュ<label id="chapter_fs_sect2-9">

<!--
To speed up accesses to commonly used directories, the VFS maintains a
cache of directory entries. 
As directories are looked up by the real file systems their details are added
into the directory cache. The next time the same directory is looked up, for
example to list it or open a file within it, then it will be found in the 
directory cache. Only short directory entries (up to 15 characters long) are 
cached but this is reasonable as the shorter directory names are the most 
commonly used ones. For example, /usr/X11R6/bin is very commonly accessed
when the X server is running. 
-->
<p>よく利用されるディレクトリへのアクセスを高速化するために、VFS はディレクトリ
エントリのキャッシュを管理している。
<newline>[see: <htmlurl 
url="./The-Linux-Kernel-images/linux/fs/dcache.c" 
name="fs/dcache.c">]<newline>
実ファイルシステムからディレクトリの
問い合わせがあると、それらの詳細がディレクトリキャッシュに入れられる。
たとえばディレクトリを表示させたり、その中のファイルをオープンするといった
同じディレクトリへの問い合わせが続く場合、そのディレクトリはディレクトリ
キャッシュで発見できる。短い(15 文字までの)ディレクトリエントリのみがキャッシュ
されるのだが、短いディレクトリ名が最も頻繁に使われるため、この方法は合理的であ
る。たとえば、<tt>/usr/X11R6/bin</tt> は、X サーバの実行中に、非常に頻繁にアク
セスされる。

<!--
The directory cache consists of a hash table, each entry of which points at a
list of directory cache entries that have the same hash value. The hash
function uses the device number of the device holding the file system and the
directory's name to calculate the offset, or index, into the hash table. It
allows cached directory entries to be quickly found. It is no use having a
cache when lookups within the cache take too long to find entries, or even not
to find them. 
-->
<p>ディレクトリキャッシュはハッシュテーブルから成り、その個々のエントリは、
同じハッシュ値を持つディレクトリキャッシュエントリのリストをポイントしている。
ハッシュ関数は、そのファイルシステムを保持するデバイスのデバイス番号と
ディレクトリ名とを利用して、そのハッシュテーブルへのオフセットとインデックス
とを計算する。それによって、キャッシュされたディレクトリは高速に発見される
ことが可能になる。キャッシュ内でのエントリ検索の問い合わせに時間がかかりすぎ
たり、エントリを見つけられないようなキャッシュでは意味がない。

<!--
In an effort to keep the caches valid and up to date the VFS keeps lists of
Least Recently Used (LRU) directory cache entries. When a directory entry
is first put into the cache, which is when it is first looked up, it is added 
onto the end of the first level LRU list. In a full cache this will displace 
an existing entry from the front of the LRU list. As the directory entry is 
accessed again it is promoted to the back of the second LRU cache list. Again,
this may displace a cached level two directory entry at the front of the level
two LRU cache list. This displacing of entries at the front of the level one 
and level two LRU lists is fine. The only reason that entries are at the front
of the lists is that they have not been recently accessed. If they had, they 
would be nearer the back of the lists. The entries in the second level LRU 
cache list are safer than entries in the level one LRU cache list. This is the
intention as these entries have not only been looked up but also they have 
been repeatedly referenced. 
-->
<p>キャッシュを有効かつ最新に保つために、VFS は最長時間未使用( Least Recently 
Used, LRU)のディレクトリキャッシュエントリのリストを保持している。ディレクト
リが問い合わせを受けて、そのディレクトリのエントリが初めてキャッシュに入れら
れるとき、それは第一レベルの LRU リストの末尾に付け加えられる。キャッシュが
満杯の場合は、その LRU リストの先頭に存在するエントリを削除することで付け加え
られる。
ディレクトリエントリが再度アクセスされると、それは第二レベルの LRU キャッシュ
の末尾に入れられる。これが満杯の場合も同様に、第二レベルの LRU キャッシュリスト
の先頭にあるディレクトリエントリと入れ替わる形となる。第一レベルと第二レベルの 
LRU リストの先頭にあるエントリを立ち退かせるという方法は妥当である。リストの
先頭にエントリがあることの唯一の理由は、それらが最近アクセスされていないという
ことだからである。アクセスがあれば、リストの後尾近くに移る。第二レベルの LRU 
キャッシュリストにあるエントリは、第一レベルの LRU キャッシュリストにあるエント
リよりも安全である。なぜなら、第二レベルにあるエントリは、問い合わせを受けた
だけでなく、繰り返し参照されているからである。

REVIEW NOTE: Do we need a diagram for this? 

<!--9.3  The Buffer Cache-->
<sect1>バッファキャッシュ<label id="chapter_fs_sect3">
<p>

<label id="figure9-7">
<!--                  Figure 9.7: The Buffer Cache-->
<#if output="html">
<figure><ph vspace="1"><img src="./The-Linux-Kernel-images/figure9-7.gif">
</figure>
</#if>
<#unless output="html">
<verb>
                           buffer_head            buffer_head
hash_table +---------+    +-----------+          +-----------+
---------->|         | +->| b_dev     |0x0301 +->| b_dev     |0x0801
           |         | |  |-----------|       |  |-----------|
           |         | |  | b_blocknr |42   +-+  | b_blocknr |17
           |         | |  |-----------|     |    |-----------|
           |         | |  | b_state   |     |    | b_state   |
           |---------| |  |-----------|     |    |-----------|
           |         |-+  | b_count   |     |    | b_count   |
           |---------|    |-----------|     |    |-----------|
           |         |    | b_size    |1024 |    | b_size    |2048
           |         |    |-----------|     |    |-----------|
           |         |    |           |     |    |           |
           |         |    |           |     |    |           |
           |         |    |-----------|     |    |-----------|
           |         |    | b_next    |-----+    | b_next    |
           |         |    |-----------|          |-----------|
           |         |    | b_prev    |          | b_prev    |
           |         |    |-----------|          |-----------|
           |         |    |           |          |           |
           |         |    |-----------|          |-----------|
           |         |    | b_data    |          | b_data    |
           |         |    +-----------+          +-----------+
           |         |
           |         |     buffer_head
           |         |    +-----------+
           |         | +->| b_dev     |0x0301
           |---------| |  |-----------|
           |         |-+  | b_blocknr |39
           |---------|    |-----------|
           |         |    | b_state   |
           |---------|    |-----------|
           ~         ~    ~           ~
           ~         ~    ~           ~
</verb>
</#if>
<p>図表(9.7) バッファキャッシュ

<!--
As the mounted file systems are used they generate a lot of requests to the
block devices to read and write data blocks. All block data read and write
requests are given to the device drivers in the form of buffer_head data
structures via standard kernel routine calls. These give all of the information
that the block device drivers need; the device identifier uniquely identifies 
the device and the block number tells the driver which block to read. All block
devices are viewed as linear collections of blocks of the same size. To speed
up access to the physical block devices, Linux maintains a cache of block
buffers. All of the block buffers in the system are kept somewhere in this
buffer cache, even the new, unused buffers. This cache is shared between all
of the physical block devices; at any one time there are many block buffers in
the cache, belonging to any one of the system's block devices and often in
many different states. If valid data is available from the buffer cache this
saves the system an access to a physical device. Any block buffer that has
been used to read data from a block device or to write data to it goes into the
buffer cache. Over time it may be removed from the cache to make way for a
more deserving buffer or it may remain in the cache as it is frequently
accessed. 
-->
<p>マウントされたファイルシステムが利用される場合、ファイルシステムはデータ
ブロックを読み書きするためにブロックデバイスに対する多くのリクエストを行う。
データブロックの読み書きするためのリクエストはすべて、標準のカーネルルーチン
の呼び出しを経由して、<tt><ref id="buffer_head" name="buffer_head"></tt> データ
構造体で定義されたデバイスドライバに渡される。
この構造体はブロックデバイスドライバに必要なすべての情報を提供する。
デバイス識別子は固有のデバイスを識別し、ブロック番号はドライバにどのブロックを
読み出すべきかを示す。すべてのブロックデバイスは、同一サイズのブロックの
線形的な集合であると見看される。物理ブロックデバイスへのアクセスをスピード
アップするために、Linux はブロックバッファのキャッシュを管理する。
システム上の
すべてのブロックバッファは、使用されていない新しいバッファでさえ、このバッファ
キャッシュのどこかに保存される。このキャッシュはすべての物理ブロックデバイス
間で共有される。どのような時にもそのキャッシュには多くのブロックバッファが
ある。それらはシステムのブロックデバイスのひとつに属していて、しばしば種々の
異なる状態(<tt><ref id="buffer_head" name="state"></tt>)にある。
有効なデータがバッファキャッシュから入手可能な場合、
それによってシステムが物理デバイスにアクセスする手間が省かれる。ブロック
デバイスに対する読み込みや書き出しで使用されたブロックバッファはすべて、
バッファキャッシュに入れられる。時間の経過によって、それらは、より必要性の高い
バッファと交代するためにキャッシュから削除されるか、頻繁にアクセスされるため
キャッシュに残るかする。

<!--
Block buffers within the cache are uniquely identfied by the owning device
identifier and the block number of the buffer. The buffer cache is composed of
two functional parts. The first part is the lists of free block buffers. There
is one list per supported buffer size and the system's free block buffers are
queued onto these lists when they are first created or when they have been
discarded. The currently supported buffer sizes are 512, 1024, 2048, 4096 and
8192 bytes. The second functional part is the cache itself. This is a hash 
table which is a vector of pointers to chains of buffers that have the same 
hash index. The hash index is generated from the owning device identifier and 
the block number of the data block. Figure  9.7 shows the hash table together
with a few entries. Block buffers are either in one of the free lists or they 
are in the buffer cache. When they are in the buffer cache they are also queued
onto Least Recently Used (LRU) lists. There is an LRU list for each buffer
type and these are used by the system to perform work on buffers of a type,
for example, writing buffers with new data in them out to disk. The buffer's
type reflects its state and Linux currently supports the following types: 
-->
<p>キャッシュ内のブロックバッファは、それを保持するデバイスの識別子とバッファ
のブロック番号とによってユニークに識別される。バッファキャッシュはふたつの
機能別部分から構成される。最初の部分は、空のブロックバッファのリストである。
サポートされるバッファサイズごとにひとつのリストがあり、システム上の空のブロッ
クバッファは、初めて作成されたり、削除されたときに、それらのリスト上の待ち行列
に置かれる。現在サポートされているバッファサイズは、512, 1024, 2048, 4096, 
そして 8192 バイトである。第二の部分は、キャッシュそのものである。これは
ハッシュテーブルであり、そのハッシュテーブルは同じハッシュインデックスを持つ
バッファに対するポインタの配列である。ハッシュのインデックスは、該当
ブロックを保持するデバイスの識別子とデータブロックのブロック番号から生成され
る。<ref id="figure9-7" name="図表(9.7)">では、ハッシュテーブルがいくつかの
エントリとともに示されている。
ブロックバッファはフリーリストのいずれかひとつにあるか、バッファキャッシュの
中に存在する。バッファキャッシュにあるときは、それらは最長時間未使用(LRU)
リスト上のキューにも置かれる。LRU リストは個々のタイプのバッファごとに存在し、
システムがそのタイプのバッファ上で処理をする際、たとえば、バッファ内の新しい
データをディスクに書き出す際などに使用される。バッファタイプとはその状態
(state)を反映するものであり、Linux では現在次のようなタイプがサポートされて
いる。

<!--
clean Unused, new buffers, 
locked Buffers that are locked, waiting to be written, 
dirty Dirty buffers. These contain new, valid data, and will be written but
      so far have not been scheduled to write, 
shared Shared buffers, 
unshared
      Buffers that were once shared but which are now not shared, 
-->
<descrip>
<tag>クリーン (clean)</tag>
未使用で新しいバッファ

<tag>ロック済み (locked)</tag>
ロックされ、書き込まれるのを待つバッファ。

<tag>ダーティ (dirty)</tag>
ダーティバッファ。それには新しい有効なデータが含まれ、書き込みがされる予定
だが、今のところ書き込みのスケジュールが回って来ていないもの。

<tag>共有 (shared)</tag>
共有バッファ。

<tag>非共有 (unshared)</tag>
以前は共有であったが、現在は共有されていないバッファ。
</descrip>

<!--
Whenever a file system needs to read a buffer from its underlying physical
device, it trys to get a block from the buffer cache. If it cannot get a buffer
from the buffer cache, then it will get a clean one from the appropriate sized
free list and this new buffer will go into the buffer cache. If the buffer 
that it needed is in the buffer cache, then it may or may not be up to date. 
If it is not up to date or if it is a new block buffer, the file system must 
request that the device driver read the appropriate block of data from the 
disk. 
-->
<p>ファイルシステムは、基礎となる物理デバイスからバッファを読み出す必要が
あるときには、バッファキャッシュからブロックを取得しようとする。
バッファキャッシュから取得できない場合、適切なサイズのフリーリストから
未使用バッファを取得し、その新しいバッファがバッファキャッシュに入る。
ファイルシステムが必要とするバッファがバッファキャッシュにある場合、バッファは
更新(update)されている場合とされていない場合がある。更新されていないか、それが
未使用ブロックバッファである場合は、ファイルシステムは、デバイスドライバによっ
て適切なデータブロックがディスクから読み出されるようリクエストする。

<!--
Like all caches, the buffer cache must be maintained so that it runs 
efficiently and fairly allocates cache entries between the block devices using
the buffer cache. Linux uses the bdflush kernel daemon to perform a lot of 
housekeeping duties on the cache but some happen automatically as a result of 
the cache being used. 
-->
<p>すべてのキャッシュと同様に、バッファキャッシュは、効率よく実行され、バッファ
キャッシュを利用するブロックデバイス間で公平にキャッシュエントリが割り当てられ
るように管理されなければならない。Linux は <tt>bdflush</tt> カーネルデーモン
を使用して、キャッシュに関する多くの細かな作業を実行しているが、それらのいく
つかは、キャッシュが使用された結果として自動的に実行される。

<!--9.3.1  The bdflush Kernel Daemon-->
<sect2>bdflush カーネルデーモン<label id="chapter_fs_sect3-1">

<!--
The bdflush kernel daemon is a simple kernel daemon that provides a
dynamic response to the system having too many dirty buffers; buffers that
contain data that must be written out to disk at some time. It is started as a
kernel thread at system startup time and, rather confusingly, it calls itself
``kflushd'' and that is the name that you will see if you use the ps command
to show the processes in the system. Mostly this daemon sleeps waiting for
the number of dirty buffers in the system to grow too large. As buffers are
allocated and discarded the number of dirty buffers in the system is checked.
If there are too many as a percentage of the total number of buffers in the
system then bdflush is woken up. The default threshold is 60% but, if the
system is desperate for buffers, bdflush will be woken up anyway. This
value can be seen and changed using the update command: 
-->
<p><tt>bdflush</tt> カーネルデーモンは、システムがダーティ(dirty, 更新待ち)
バッファを多く持ちすぎている場合に、システムに対して動的に反応するシンプルな
カーネルデーモンである。
<newline>[see: bdflush(), in <htmlurl 
url="./The-Linux-Kernel-images/linux/fs/buffer.c" 
name="fs/buffer.c">]<newline>
データを保持するバッファは、時々ディスクへと書き戻さなければならない。
そのデーモンは、起動時にはシステム上のカーネルスレッドとして起動される。少し
ややこしいのだが、それは "<tt>kflush</tt>" と呼ばれ、その名前は、システム上の
プロセスを表示する <tt>ps</tt> コマンドを使うと見ることができる。
たいていこのデーモンはスリープ状態で、システム上のダーティバッファの数が多く
なりすぎるのを待っている。バッファが割り当てられたり破棄されたりすると、システ
ム上のダーティバッファの数がチェックされる。システム上のバッファの総数のパーセ
ンテージとしてダーティバッファが多くなりすぎると、<tt>bdflush</tt> は目を覚ま
す。デフォルトの境界線は 60% だが、システムがバッファの不足で困っている場合は、
<tt>bdflush</tt> は強制的に目覚めされられる。この値は、<tt>update</tt> コマンド
を使って確認や変更が可能である。

<verb>
# update -d

bdflush version 1.4
0:    60 Max fraction of LRU list to examine for dirty blocks
1:   500 Max number of dirty blocks to write each time bdflush activated
2:    64 Num of clean buffers to be loaded onto free list by refill_freelist
3:   256 Dirty block threshold for activating bdflush in refill_freelist
4:    15 Percentage of cache to scan for free clusters
5:  3000 Time for data buffers to age before flushing
6:   500 Time for non-data (dir, bitmap, etc) buffers to age before flushing
7:  1884 Time buffer cache load average constant
8:     2 LAV ratio (used to determine threshold for buffer fratricide).
</verb>

<!--
All of the dirty buffers are linked into the BUF_DIRTY LRU list whenever
they are made dirty by having data written to them and bdflush tries to
write a reasonable number of them out to their owning disks. Again this
number can be seen and controlled by the update command and the default is
500 (see above). 
-->
<p>データを書き込まれて更新待ち状態になり、<tt>bdflush</tt> が合理的な数の
ダーティバッファをディスクに書き戻そうとする場合はいつも、ダーティバッファの
すべてが、<tt><ref id="buffer_head" name="BUF_DIRTY"></tt> LRU リストにリンク
される。この数も確認可能であり、<tt>update</tt> コマンドによって制御できる。
デフォルト値は 500 である。(上記を参照)

<!--9.3.2  The update Process-->
<sect2> update プロセス<label id="chapter_fs_sect3-2">

<!--
The update command is more than just a command; it is also a daemon. When
run as superuser (during system initialisation) it will periodically flush all
of the older dirty buffers out to disk. It does this by calling a system 
service routine that does more or less the same thing as bdflush. Whenever a 
dirty buffer is finished with, it is tagged with the system time that it 
should be written out to its owning disk. Every time that update runs it looks
at all of the dirty buffers in the system looking for ones with an expired 
flush time. Every expired buffer is written out to disk. 
-->
<p><tt>update</tt> コマンドは単なるコマンドではなく、デーモンでもある。
(システム初期化の際に)スーパーユーザ権限で起動されると、それは定期的に
古くなったダーティバッファのすべてをディスクに書き戻す(フラッシュする)。
これが実行される際には、<tt>bdflush</tt> と似通ったシステムサービスルーチン
が呼び出される。
<newline>[see: sys_bdflush(), in <htmlurl 
url="./The-Linux-Kernel-images/linux/fs/buffer.c" 
name="fs/buffer.c">]<newline>
ダーティバッファは(システムサービスルーチン)終了時に、元のディスクに書き戻す
ため、システム時間が(バッファの構造体に)付け加えられる。<tt>update</tt> コマン
ドが実行されるときは、いつも、システム上のダーティバッファすべてを検査し、
フラッシュすべき時刻を過ぎているものを探す。フラッシュすべき時刻をすぎた
すべてのバッファは、ディスクに書き戻される。

<!--9.4  The /proc File System-->
<sect1>/proc ファイルシステム<label id="chapter_fs_sect4">

<!--
The /proc file system really shows the power of the Linux Virtual File
System. It does not really exist (yet another of Linux's conjuring tricks),
neither the /proc directory nor its subdirectories and its files actually 
exist. So how can you cat /proc/devices? The /proc file system, like a real 
file system, registers itself with the Virtual File System. However, when the 
VFS makes calls to it requesting inodes as its files and directories are 
opened, the /proc file system creates those files and directories from 
information within the kernel. For example, the kernel's /proc/devices file is
generated from the kernel's data structures describing its devices. 
-->
<p><tt>/proc</tt> ファイルシステムは、Linux の仮想ファイルシステムの能力を
如実に示すものである。そのファイルシステムは実在しない。(これも、Linux の魔術
のひとつである。) <tt>/proc</tt> ディレクトリも、そのサブディレクトリも、
その中のファイルも実在しない。では、どうして <tt>cat /proc/devices</tt> という
コマンドを実行できるのか？ <tt>/proc</tt> ファイルシステムは、実ファイル
システムと同様に、仮想ファイルシステムに登録されている。しかし、VFS が 
<tt>/proc</tt> ファイルシステムを呼び出して、そのファイルやディレクトリを
オープンするために inode をリクエストしたときに、 <tt>/proc</tt> ファイル
システムは、カーネル内の情報からそのファイルやディレクトリを(動的に)作成する。
たとえば、カーネルの <tt>/proc/devices</tt> ファイルはそのデバイスを記述する
カーネルのデータ構造体から生成されている。

<!--
The /proc file system presents a user readable window into the kernel's
inner workings. Several Linux subsystems, such as Linux kernel modules
described in chapter  modules-chapter, create entries in the the /proc file
system. 
-->
<p><tt>/proc</tt> ファイルシステムは、カーネル内部の実行状態への窓を、ユーザ
が読みとれるような形で提供する。Linux カーネルモジュール(<ref 
id="chapter_m" name="「モジュール」">の章を参考)のような Linux サブシステムの
いくつかは、<tt>/proc</tt> ファイルシステム内にエントリを作成している。

<!--9.5  Device Special Files-->
<sect1>デバイススペシャルファイル<label id="chapter_fs_sect5">

<!--
Linux, like all versions of Unix TM presents its hardware devices as special
files. So, for example, /dev/null is the null device. A device file does not 
use any data space in the file system, it is only an access point to the device
driver. The EXT2 file system and the Linux VFS both implement device files
as special types of inode. There are two types of device file; character and
block special files. Within the kernel itself, the device drivers implement 
file semantices: you can open them, close them and so on. Character devices
allow I/O operations in character mode and block devices require that all I/O
is via the buffer cache. When an I/O request is made to a device file, it is
forwarded to the appropriate device driver within the system. Often this is not
a real device driver but a pseudo-device driver for some subsystem such as
the SCSI device driver layer. Device files are referenced by a major number,
which identifies the device type, and a minor type, which identifies the unit,
or instance of that major type. For example, the IDE disks on the first IDE
controller in the system have a major number of 3 and the first partition of an
IDE disk would have a minor number of 1. So, ls -l of /dev/hda1 gives: 
-->
<p>Linux は、Unix のあらゆるバージョンと同様に、ハードウェアデバイスをスペ
シャルファイルで表現している。たとえば、<tt>/dev/null</tt> はヌル(null)デバイス
である。デバイスファイルはシステム上のデータ空間を使用しない。それは、単なる
デバイスドライバへのアクセスポイントである。EXT2 ファイルシステムと Linux VFS 
はどちらもデバイスドライバを特別なタイプの inode として実装している。デバイス
ファイルには、キャラクタスペシャルファイルとブロックスペシャルファイルの
二種類がある。
カーネル自体の内部で、デバイスドライバによるそうしたファイルのオープンや
クローズといった、ファイル操作の意味が定義されている。
キャラクタデバイスでは、キャラクタモードでの I/O 操作が可能であり、ブロック
デバイスではすべての I/O 操作がバッファ経由で行われるよう要求される。
デバイスファイルに対する I/O リクエストがなされると、そのリクエストはシステム
上の適切なデバイスドライバに送られる。これはしばしば実際のドライバでなく、
SCSI デバイスドライバ層といったあるサブシステムの疑似デバイス(pseudo-device)
ドライバである場合がある。デバイスファイルは、デバイスタイプを識別するメジャー
番号と、同じメジャー番号の中での実際のユニット(unit)もしくはインスタンス
(instance)を識別するマイナー番号とで参照される。
たとえば、システム上の最初の IDE ディスクコントローラ上にある IDE ディスクは、
メジャー番号 3 であり、IDE ディスクの最初のパーティションはマイナー番号 1 と
なる。したがって、<tt>/dev/hda1</tt> の <tt>ls -l</tt> の結果は次のようになる。
<newline>[see: Linux の全メジャー番号については、<htmlurl 
url="./The-Linux-Kernel-images/linux/include/linux/major.h" 
name="include/linux/major.h">]<newline>

<verb>
$ ls -l /dev/hda1
brw-rw----   1 root    disk       3,    1  Nov 24  15:09 /dev/hda1
</verb>

<!--
Within the kernel, every device is uniquely described by a kdev_t data type,
this is two bytes long, the first byte containing the minor device number and
the second byte holding the major device number. 
The IDE device above is held within the kernel as 0x0301. An EXT2 inode
that represents a block or character device keeps the device's major and
minor numbers in its first direct block pointer. When it is read by the VFS, 
the VFS inode data structure representing it has its i_rdev field set to the
correct device identifier. 
-->
<p>カーネル内部では、すべてのデバイスが <tt><ref id="kdev_t" name="kdev_t">
</tt> データタイプによってユニークに記述される。このデータは 2 バイト長であり、
最初のバイトにはデバイスのマイナー番号が含まれ、二番目のバイトにはメジャー番号
が保持されている。
<newline>[see: <htmlurl 
url="./The-Linux-Kernel-images/linux/include/linux/kdev_t.h" 
name="include/linux/kdev_t.h">]<newline>
上記の IDE デバイスは、カーネル内の 0x0301 に保持されている。ブロックデバイス
やキャラクタデバイスを表す EXT2 <tt><ref id="ext2_inode" name="inode"></tt> 
は、デバイスのメジャー番号とマイナー番号を、ブロックを直接ポイントする(配列の)
先頭のポインタに保持している。
それが VFS によって読み出されるとき、それを表す VFS <tt><ref id="inode" 
name="inode"></tt> データ構造体は、<tt><ref id="inode" name="i_rdev"></tt> 
フィールドに正しいデバイス識別子を設定する。

<!--
Footnotes:

1 Well, not knowingly, although I have been bitten by operating systems with
more lawyers than Linux has developers 
-->
<label id="chapter_fs_fn">
<footnote>
(脚注 1): Linux には、大勢の開発者がいる。いくつかのオペレーティングシステムに
は、もっと大勢の弁護士がいるらしい。
</footnote>