struct bdev_inode {
struct block_device bdev;
struct inode vfs_inode;
};
struct block_device *bdget(dev_t dev)
{
struct block_device *bdev;struct inode *inode;
inode = iget5_locked(blockdev_superblock, hash(dev),bdev_test, bdev_set, &dev); //bdev_test, bdev_set函数不允许睡眠
if (!inode)
return NULL;
bdev = &BDEV_I(inode)->bdev;
if (inode->i_state & I_NEW) {
bdev->bd_contains = NULL;
bdev->bd_inode = inode;
bdev->bd_block_size = (1 << inode->i_blkbits);
bdev->bd_part_count = 0;
bdev->bd_invalidated = 0;
inode->i_mode = S_IFBLK;
inode->i_rdev = dev;
inode->i_bdev = bdev;
inode->i_data.a_ops = &def_blk_aops;
mapping_set_gfp_mask(&inode->i_data, GFP_USER);
inode->i_data.backing_dev_info = &default_backing_dev_info;
spin_lock(&bdev_lock);
list_add(&bdev->bd_list, &all_bdevs);
spin_unlock(&bdev_lock);
unlock_new_inode(inode);
}
return bdev;
}
给定dev_t dev,可通过该函数查找或创建请求的块设备。
struct inode *iget5_locked(struct super_block *sb, unsigned long hashval,
int (*test)(struct inode *, void *),
int (*set)(struct inode *, void *), void *data)
{
struct hlist_head *head = inode_hashtable + hash(sb, hashval);
struct inode *inode;
inode = ifind(sb, head, test, data, 1);
if (inode)
return inode;
/*
* get_new_inode() will do the right thing, re-trying the search
* in case it had to block at any point.
*/
return get_new_inode(sb, head, test, set, data);
}
iget5_locked(...)使用ifind()函数查找由hashval和data指定的inode或创建新的inode.
该inode经过container_of获取bdev_inode类型指针
然后由获得的bdev_inode指针对 struct block_device bdev进行操作。如果是新创建的,则初始化;否则直接返回以创建的bdev.