bd_acquire() 手続き

なんとなく進めてみる。今は以下なあたりを掘削中。

	bdev = bdget(inode->i_rdev);

inode オブジェクトの i_rdev 属性って定義は以下で

	dev_t			i_rdev;

3rd Edition では_実デバイス番号_とある。dev_t 型は include/linux/coda.h で以下な定義でビンゴなのだろうか。

typedef u_long dev_t;

unsigned long ッスか。を、Linux カーネル 2.6 解読室では_デバイス番号 (特殊ファイルの場合)_との記述。
i_rdev 属性って何だ、といいつつ bdev_test とか bdev_set とかな手続きが微妙にポイント高そげな事が判明 (block_dev.c にて定義)。

static int bdev_test(struct inode *inode, void *data)
{
	return BDEV_I(inode)->bdev.bd_dev == *(dev_t *)data;
}

static int bdev_set(struct inode *inode, void *data)
{
	BDEV_I(inode)->bdev.bd_dev = *(dev_t *)data;
	return 0;
}

む。block_device なオブジェクトをどーやって求めてるのか、と言いつつ BDEV_I というマクロを掘ってみたら出ました container_of

static inline struct bdev_inode *BDEV_I(struct inode *inode)
{
	return container_of(inode, struct bdev_inode, vfs_inode);
}

inode なポインタから bdev_inode 構造体の先頭アドレスを取得して戻してるはず。この手続きを呼び出している箇所では基本的にリストを手繰ってるはずなんですがどうなんだろうか、と言いつつ掘削。

bdget()
 iget5_locked()
  ifind()
   find_inode()

リストの先頭は iget_lockd() にて取得している模様。しかし上記の BDEV_I マクロの直上で定義されている bdev_inode 構造体は

struct bdev_inode {
	struct block_device bdev;
	struct inode vfs_inode;
};

どこでオブジェクト作っているのか、と。grep してみたら fs/block_dev.c のみでアクセスされている模様。

$ find -name "*.[ch]"|xargs grep bdev_inode
./fs/block_dev.c:struct bdev_inode {
./fs/block_dev.c:static inline struct bdev_inode *BDEV_I(struct inode *inode)
./fs/block_dev.c:       return container_of(inode, struct bdev_inode, vfs_inode);
./fs/block_dev.c:       struct bdev_inode *ei = kmem_cache_alloc(bdev_cachep, SLAB_KERNEL);
./fs/block_dev.c:       struct bdev_inode *bdi = BDEV_I(inode);
./fs/block_dev.c:       struct bdev_inode *ei = (struct bdev_inode *) foo;
./fs/block_dev.c:       bdev_cachep = kmem_cache_create("bdev_cache", sizeof(struct bdev_inode),
$

今日は早めに寝ます。