ext3_fill_super() 手続き (8)

直前エントリ、迷走し杉。疲れが溜っていたのだろうか。

いろいろ整理が必要

ってコトで結論から申し上げるに、open_bdev_excl() に渡される @holder は get_sb_bdev() の fs_type という引数になります。file_system_type なオブジェクトです。で、この file_system_type なオブジェクトは do_kern_mount() の中で get_fs_type() 手続きを使って取り出しているものになります。
ちなみに、

struct vfsmount *
do_kern_mount(const char *fstype, int flags, const char *name, void *data)

の data という引数なんですが、get_sb_bdev() の中では fill_super() という手続きに以下なカンジで渡しているんですが

		error = fill_super(s, data, flags & MS_SILENT ? 1 : 0);

fill_super() を掘ってみると

static int fill_super(struct super_block *sb, void *data, int silent)
{
	static struct tree_descr files[] = {{""}};

	return simple_fill_super(sb, SECURITYFS_MAGIC, files);
}

使われてなかったりします。とりあえずここは別途確認入れる方向で、get_fs_type() 手続きを確認してみる事に。

get_fs_type() 手続き

fs/filesystems.c にて定義。記憶には無いのですが 3rd Edition の 12.3.2 が開かれております。
include/linux/fs.h にて定義されている file_system_type 構造体の定義が以下。

struct file_system_type {
	const char *name;
	int fs_flags;
	int (*get_sb) (struct file_system_type *, int,
		       const char *, void *, struct vfsmount *);
	void (*kill_sb) (struct super_block *);
	struct module *owner;
	struct file_system_type * next;
	struct list_head fs_supers;
	struct lock_class_key s_lock_key;
	struct lock_class_key s_umount_key;
};

この構造体なオブジェクトは VFS がカーネルのコードに含まれる全てのファイルシステムの種別を把握しておく必要がある、という事にて filesystem type registraion なる作業にてリストに追加させる模様。
find_filesystem() という手続きを見るに fs/filesystems.c の先頭部分で定義されている file_systems という変数でリストの先頭を管理している模様。

static struct file_system_type *file_systems;

find_filesystem() の定義が以下。

static struct file_system_type **find_filesystem(const char *name)
{
	struct file_system_type **p;
	for (p=&file_systems; *p; p=&(*p)->next)
		if (strcmp((*p)->name,name) == 0)
			break;
	return p;
}

ポインタのポインタを操作してるので微妙に気色悪い。あ、関数の概要説明もありますな。

get_fs_type() 関数は、引数としてファイルシステム名を受け取り、登録済みのファイルシステムのリストから各要素の name メンバを調べます。そして、そのファイルシステムが存在するときには、対応する file_system_type オブジェクトへのポインタを返します。


との事。手続きをざっくり見てみるに

  • リストを手繰って戻りを fs (struct file_system_type * なローカル変数) に代入
  • find_filesystem() で見つけられなかった場合の後処理??
	if (fs && !try_module_get(fs->owner))
		fs = NULL;
  • name なモジュールを load しようとしてみる
    • request_module() の戻りが 0 で fs も NULL なら探索と後始末をリトライ
  • fs を返却

という流れになるのでしょうか。なんとなく微妙な後味だったりしますが

あと

2.6.10 な kernel をオトして Linux Kernel 2.6.10 方面に出力した方が良さげな気がしてきました。ブログ出力のみだと微妙。fs/super.c の get_sb_bdev() とかエントリ無さげ。