「Linuxカーネル解読室」
       輪講@Hatena
         第15章
「仮想ファイルシステム(VFS)」

      松本一輝
     @KazkiMatz
Q1. inode
• これは何?
Q2. ファイルオープン操作
• ファイルオープンでどのような処理が走るのか?
 – HDD上のファイルにフラグ等が書き込まれるのか?
 – ファイルオープン中に電源落としたらどうなるのか?
Q3. オープン中のファイルを消すとどうなる?

• ディスク使用率が低下しないのは何故か?
Q4. /proc/***はどう実装されている?

• 仮想のディレクトリ?
 – どうやって摺りあわせてるのか?
Q5. ファイルパスは誰がパースするのか?

• “./../../foo/bar/”
Q6. マウント時に何が起きるのか?

• ディレクトリに何かが書き込まれる?
VFS
• 各ファイルシステムの差異を吸収、抽象化す
  るレイヤー
• ファイルタイプの違い(ファイルorディレクトリ)
  も吸収したりする(i_op)
• オブジェクト指向
システムコール(open, read, write, …)
                                           ユーザ空間

                                           カーネル空間


ファイルシステム
  共有処理                 VFS

ファイルシステム
                         …           …
  固有処理




  下位層
files_struct構造体
• task_struct構造体のfilesメンバーから参照される
  – スレッド間で共有参照される
• プロセスfork時には、コピーされる
• fdtable構造体へのポインタを持つ
  – file構造体アドレス配列へのポインタ配列を持つ
• spinlock有
• FDステータス用ビットマップ
  – open_fds
     • どのFDが現在開かれているのか
  – close_on_execフラグ
     • exec()した時に自動で閉じてもらうためのオプション
  – 初期割当て32個=32bit?
  – 足りなくなると、次は256個領域に引越し
     • 配列なので連続の必要あるため
     • 領域確保はkmallocかvmallocで
file構造体
• オープンコンテキストを管理するもの
  – ファイルオープンごとに生成される
  – プロセスfork時には共有参照される
• dentry構造体へのポインタ有
  – dentryを糸口に、ファイルパスが取得できる
• address_space構造体(inodeが含む)へのポインタ有
• spinlock有(epoll用)
• 参照カウント有(f_count)
  – プロセス間で共有されるため
• ファイルオフセット有(f_pos)
  – 読み込み/書き込み動作の対象位置(先頭からの位置)
  – プロセス間で共有!?
dentry構造体
• ディレクトリエントリをモデル化したもの
  – ディレクトリエントリの所有者
  – ファイル名
  – ファイル名に対応するinode構造体へのポインタ
• パス名キャッシュとしての役割
  – dentry_hashtableのヘッド数はメモリ8KBにつき1個
• ファイル名に対して一意
  – ファイル名長さとハッシュ値も持っている
    • 高速比較可
  – ファイルを多重オープンしても共有参照される
• (モノによって?)参照頻度極めて高し
  – スケーラビリティのためRCUリストを持つ(d_rcu)
• spinlock有
• d_mounted(このdentryへのマウント数-後述)
inode構造体
•   ファイル実体に対して一意
•   address_space構造体をメンバーに持つ
•   dentry構造体へのポインタを持つ
     – 1つのinodeは複数のdentryを持つことが出来る
•   参照カウント(i_count)
•   ハッシュリストで高速検索
     – ヘッド数はメモリ16KBにつき一個
•   さらに以下4リストのうちどれかにつながっている
     – inode_in_use
     – 使用中(参照カウントがゼロでない)かつdirtyでない
     – inode_unused
           •   未使用(参照カウントゼロ)
     – s_dirty
           •   dirtyなもの
     – s_io
•   i_op
     – オペレーション関数へのポインタ
•   ファイルのモード、UID、GID (i_mode, i_uid, i_gid)
super_block構造体
• 使用中のファイルシステムと一意である
 – ディスクパーティションごとにひとつ
• ファイルシステムについての各種情報
 –   file_system_type
 –   マウント数
 –   参照カウント
 –   s_op
      • オペレーション関数へのポインタ
• ファイルシステムに書き込まれたsuperblockと対
  応している
file_system_type構造体
• 使用可能なファイルシステム種と一意
• /proc/filesystem
vfsmount構造体
• マウントごとに存在
• ハッシュリストにつながれている
 – パス名ルックアップで使用される
   • dentryでd_mounted > 0 → vfsmount探索
 – ヘッド数は1ページ分(32bitの場合512エントリ)
• 参照カウント有(mnt_count)
 – 配下のファイルオープン、カレントディレクトリ等で
   インクリメントされる
fs_struct構造体
• task_structから参照される(fs)
• ルートディレクトリ、カレントディレクトリ情報
 – dentryへのポインタ
• ルートディレクトリ、カレントディレクトリのファイル
  システム情報
 – vfsmountへのポインタ
• fork時にはコピーされる
link_path_walk()
• 引数として、パス文字列及びnameidata構造
  体
• パーミッションに配慮しながらdentry,
  vfsmountをたどっていく
• . 、 .. 等
atomic_t (型)
An atomic_t is an integer variable that can be inspected and changed atomically.
It is mostly used for reference counting and semaphores. On i386 it is defined as
typedef struct { volatile int cnt; } atomic_t;
(http://www.win.tue.nl/~aeb/linux/lk/lk-13.html)



SMP環境を考慮したatomic_t用メソッド例(i386)

static __inline__ void atomic_dec(atomic_t *v) {
     __asm__ __volatile__(
          LOCK "decl %0“
          :"=m" (v->cnt)
          :"m" (v->cnt));
}
再掲
Q1. inode
• これは何?
Q2. ファイルオープン操作
• ファイルオープンでどのような処理が走るのか?
 – HDD上のファイルにフラグ等が書き込まれるのか?
 – ファイルオープン中に電源落としたらどうなるのか?
Q3. オープン中のファイルを消すとどうなる?

• ディスク使用率が低下しないのは何故か?
Q4. /proc/***はどう実装されている?

• ディレクトリがあるわけ?
Q5. ファイルパスは誰がパースするのか?

• “./../../foo/bar/”
Q6. マウント時に何が起きるのか?

• ディレクトリに何かが書き込まれる?
以上

Slide