ext3_fill_super() 手続き (2)
帰宅後、着手したら lookup_bdev() が隣りの emacs で開かれている。関数定義直上に記述されているコメントが以下。
/** * lookup_bdev - lookup a struct block_device by name * * @path: special file representing the block device * * Get a reference to the blockdevice at @path in the current * namespace if possible and return it. Return ERR_PTR(error) * otherwise. */
渡される path はext3_get_sb() に渡される dev_name な模様。デバイスファイルのパスと類推。
処理的には
- path_lookup() で nameidata 構造体オブジェクトを取得
- nameidata オブジェクトの dentry 属性なオブジェクトの inode 属性を使ってエラーチェック
- bd_acquire() 手続きで block_devide 構造体オブジェクトを取得して戻す
みたいなカンジ。
とりあえず path_lookup() はリキが必要な模様なので 3rd Edition に詳細な説明があるんで今回はスルーで。とりあえず include/linux/namei.h に定義されている nameidata 構造体の定義を以下に。
struct nameidata { struct dentry *dentry; struct vfsmount *mnt; struct qstr last; unsigned int flags; int last_type; unsigned depth; char *saved_names[MAX_NESTED_LINKS + 1]; /* Intent data */ union { struct open_intent open; } intent; };
bd_acquire() を掘ってみます。inode オブジェクトを渡して block_device オブジェクトが戻される模様。inode 構造体の i_bdev とか i_rdev って何でしょ。
処理の流れ的には
- inode オブジェクトの i_bdev 属性 (ブロックデバイス情報) が NULL ではなかったら そのブロックデバイスに対応する inode の参照カウントを上げて return
- 上記 i_bdev 属性が NULL な場合、i_rdev 属性を bdget() 手続きに渡して block_device オブジェクトを取得
- i_rdev 属性は dev_t 型でデバイス番号との注釈が入っている
- bdget() は i_rdev から block_device なオブジェクトを (生成できれば) 生成して適度に属性を設定して戻す手続きと勝手読み
次は blkdev_get() 手続き
一連の記述を以下に引用。
static int __blkdev_get(struct block_device *bdev, mode_t mode, unsigned flags, int for_part) { /* * This crockload is due to bad choice of ->open() type. * It will go away. * For now, block device ->open() routine must _not_ * examine anything in 'inode' argument except ->i_rdev. */ struct file fake_file = {}; struct dentry fake_dentry = {}; fake_file.f_mode = mode; fake_file.f_flags = flags; fake_file.f_path.dentry = &fake_dentry; fake_dentry.d_inode = bdev->bd_inode; return do_open(bdev, &fake_file, for_part); } int blkdev_get(struct block_device *bdev, mode_t mode, unsigned flags) { return __blkdev_get(bdev, mode, flags, 0); } EXPORT_SYMBOL(blkdev_get);
do_open() は fs/block_dev.c の do_open() かなぁ。あ、おなじファイルだな。直上だ。ちょっとこれ、現時点で意味不明。
なんとなくな類推ですが、do_open() に渡される block_device オブジェクトの属性なデバイス番号を get_gendisk() 手続きに渡して gendisk なオブジェクトを戻してもらって、それを block_device オブジェクトの bd_disk 属性に設定?
このあたり、細部を掘りすぎると微妙な気もしてますが本当かどうかは微妙。
明日もあるので中途半端ですが、今日はこれで終わり。