ext3_fill_super() 手続き (7)

すぐ忘れる。

  • get_sb_bdev() は fs/super.c にて定義
  • そこから呼ばれる open_bdev_excl() は fs/block_dev.c にて定義

再度

スピードつけて open_bdev_excl() 配下をおさらい。完全に見落してたんですが、3rd Edition の 14.4.1 に block_device な構造体に関する詳細な説明あり。
あと get_sb_bdev() を呼び出す手続きも以下なコメントの部分から見ても確認の必要あり。

 * open_bdev_excl  -  open a block device by name and set it up for use
 *
 * @path:	special file representing the block device
 * @flags:	%MS_RDONLY for opening read-only
 * @holder:	owner for exclusion
 *
 * Open the blockdevice described by the special file at @path, claim it
 * for the @holder.

open_bdev_excl() から呼び出される bd_claim() に渡される @holder に渡される void * って具体的には何なのか。再度その上を見てみる (俯瞰する) 必要あり?

sys_mount()

fs/namespace.c にて定義。
ここから do_mount() が呼び出される。ってか

asmlinkage long sys_mount(char __user * dev_name, char __user * dir_name,
			  char __user * type, unsigned long flags,
			  void __user * data)

な data が最終的に @holder になるはずなんですが、3rd Edition な記述によれば_ファイルシステム固有のデータ構造へのポインタ_とある (12.4.3)。これって 3rd Edition の 18.3.1 にある ext3_sb_info オブジェクトなのかなぁ (vfs super block の s_fs_info メンバが指すオブジェクト)。
続きを見てみると新規に mount するのであれば do_new_mount() が呼び出されるはず。

あらら

vfs_kern_mount() で微妙な操作をチェックしたと思ったら上記の読みが全部ダウトなのが判明。とほほほ。とりあえず行ったりきたりしている内に do_kern_mount() にて

struct vfsmount *
do_kern_mount(const char *fstype, int flags, const char *name, void *data)
{
	struct file_system_type *type = get_fs_type(fstype);
	struct vfsmount *mnt;
	if (!type)
		return ERR_PTR(-ENODEV);
	mnt = vfs_kern_mount(type, flags, name, data);

なカンジの操作をしている事を確認。ここで戻る vfsmount なオブジェクトを vfs_kern_mount() に渡しているのが分かる。で、この type が以下なカンジで渡されて

struct vfsmount *
vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void *data)

get_sb() に以下な形で渡される。

	error = type->get_sb(type, flags, name, data, mnt);

で、ext3 だと以下。

static int ext3_get_sb(struct file_system_type *fs_type,
	int flags, const char *dev_name, void *data, struct vfsmount *mnt)
{
	return get_sb_bdev(fs_type, flags, dev_name, data, ext3_fill_super, mnt);
}

で、get_sb_bdev() の中で以下。

int get_sb_bdev(struct file_system_type *fs_type,
	int flags, const char *dev_name, void *data,
	int (*fill_super)(struct super_block *, void *, int),
	struct vfsmount *mnt)
{
	struct block_device *bdev;
	struct super_block *s;
	int error = 0;

	bdev = open_bdev_excl(dev_name, flags, fs_type);

呼び出された先で以下な形。

struct block_device *open_bdev_excl(const char *path, int flags, void *holder)

現時点では holder には vfsmount なオブジェクトが渡される、と見てビンゴなはず。なんとなく靄が晴れかかってるんですが、もう少し上記の手続きから呼び出される手続きをきちんと確認する必要あり。

ってか

上記の記述な以下は

な data が最終的に @holder になるはずなんですが、3rd Edition な記述によれば_ファイルシステム固有のデータ構造へのポインタ_とある (12.4.3)。これって 3rd Edition の 18.3.1 にある ext3_sb_info オブジェクトなのかなぁ (vfs super block の s_fs_info メンバが指すオブジェクト)。

ダウト。このあたりの見極めと検証が大切ですな。
# 上記がビンゴかどうかは不明ですが ...

get_fs_type()

fs/filesystem.c にて定義。ってか、上記ダウトだな。

現時点では holder には vfsmount なオブジェクトが渡される、と見てビンゴなはず。

何だよ、と。do_kern_mount() の記述が以下。

struct vfsmount *
do_kern_mount(const char *fstype, int flags, const char *name, void *data)
{
	struct file_system_type *type = get_fs_type(fstype);
	struct vfsmount *mnt;
	if (!type)
		return ERR_PTR(-ENODEV);
	mnt = vfs_kern_mount(type, flags, name, data);
	put_filesystem(type);
	return mnt;
}

get_fs_type() の戻りは file_system_type なオブジェクトのポインタですな。とほほ。
そりゃそう、と言えばそりゃそうですね。get_fs_type() 手続きは、スデに今日は無理なので明日確認します。