vfs(Virtual File System)は、各プロセスが同手順でファイル操作を行えるように、単一のインターフェイスを提供しているファイルシステムです。
Linuxは以下のようなファイルシステムをサポートしている。(一例)
ext ext2 xia minix umsdos msdos vfat proc~ smb ncp iso9660 sysv hpfs affs ufs~
各ファイルシステムの上位には、vfs(仮想ファイルシステム)があり、下位にはデバイスドライバがある。
vfsはファイルシステムの論理的イメージを操作し、vfs以下の各ファイルシステムモジュールで、論理イメージと物理イメージの変換を行っている。
デバイスドライバへのI/Oは、ファイルデータはページキャッシュ経由で行われ、ディレクトリ等は、バッファキャッシュ経由で行われる。
ページキャッシュは、バッファキャッシュに分割され、バッファキャッシュ処理でI/Oされるので、ページキャッシュはバッファキャッシュにも登録される。
「ファイルからデータを読み込み」の場合
例えば以下のCコードで、read? システムコールを呼び出した場合のvfsの動作について簡単に示します。
#include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <errno.h> #include <string.h> int main(void) { int fd; char vm[4096]; memset(vm, 0, 4096); if ((fd = open("/etc/hosts", O_RDONLY)) < 0) return errno; if ((read(fd, vm, 4096)) < 0) return errno; printf("%s", vm); close(fd); return 0; }
このサンプルで、ファイル操作はopen?, read?, close?である。アプリケーションは、どのファイルシステム上に存在するファイルかまったく気にしなくて良い。ext3上のファイルだったり、xfs上のファイルだったりはvfsが解決する。
mini詳解
Q:vfsはどうやって、アクセス先のファイルシステムを特定するのか?
A:例えばreadの場合は以下の動作で各ファイルシステムに振り分ける。
1.マウント時に各ファイルシステムはジャンプテーブルを用意します。
2.対象ファイルディスクリプターよりfile構造体を得る。
(fget_light関数→fcheck_filesマクロでtask_structのfilesを参照する)
(task_structはkernelの重要な動作を成す核なので、ここでは割愛します。)
(kernelの動きについては。。後で参考になるURL貼っておきます。[7/4])
3.file->f_op->read が対象ファイルシステムのread登録関数でファイルシステム毎の処理を行う。
各ファイルシステムは、各ファイルシステムのルールに則り、ディスクアクセス等を行い、ユーザが要求した操作を実現するのが目的である。
ファイルアクセス操作の流れ
1.ユーザがある部分のデータをread?する
2.vfsがext3にread?するよう指示を出す
3.ext3はディスクアクセスをし、read?したデータをvfsに返す
4.vfsはユーザにread?したデータ返す
5.ユーザが受け取る。
イメージは以下の図を参照
後はアセンブラのコードまで行って、実際の読み込みが行われます。
linuxカーネルソース/include/linux/fs.hの解説
ファイルシステムはmountして、read?、write?して、umount?してと、いろいろ動きます。
いろいろなファイルシステムが動くし、いろいろなプロセスが動きます。ファイルシステムは常に動くわけではなく、必要なときだけkernelより呼び出され、ファイルシステムが操作されます。
必要なときだけ呼び出されるには、kernelによってあらかじめ決められた構造体に関数を登録することが必要です。
CPUが2つ以上(smp?カーネル)の場合、同時にrename?が動いたりすると困るので、kernel-lock(排他制御)などkernelの動きを止めたり(一部分)する機構があります。
kernel-lockはファイルシステムと非常に密接な関係ですが、そんなことまで書く時間が無いので省略。。。
#編集中なので気にしないでください。。。
#内容もメモ書き程度です。。。
主要構造体 | 用途 |
file_system_type | mountやumount?時に使用される |
super_operations | ファイルシステムのスーパーブロックを操作するときに使用される |
inode_operations | create?、mkdir?等inode?操作が行われるファイル操作の集まり |
file_operations | read?、write?等ファイル操作行われる時に使用される |
export_operations | nfsをexport?するためにkernel2.6?から導入された |
address_space_operations | ファイルデータをページキャッシュで利用する際に使用する |
vm_operations_struct? | 仮想メモリエリアに対する操作を行う際に使用する |
dentry_operations? | vfsがdentry?操作を行う際に使用する |