Linux 核函数 dm_per_bio_data 有什么作用?
What does the Linux kernel function dm_per_bio_data do?
我正在尝试理解从内核源代码调用一些函数的内核模块的代码。代码在device-mapper.h.
struct dm_target_io {
struct dm_io *io;
struct dm_target *ti;
unsigned target_bio_nr;
unsigned *len_ptr;
struct bio clone;
};
static inline void *dm_per_bio_data(struct bio *bio, size_t data_size)
{
return (char *)bio - offsetof(struct dm_target_io, clone) - data_size;
}
我们在其他地方被告知,在 device_mapper.h 的评论中,"dm_per_bio_data returns the data location." 我不确定为什么会这样。
首先,dm_per_bio_data 接受一个 struct bio* 并用 offsetof(struct dm_target_io, clone) 减去它,这应该给出封闭的 dm_target_io 结构的开始。然后,它减去 data_size,它将指针指向--where?
我一直在寻找 dm_target_io 在另一个结构中声明的位置,以查看减去 data_size 可能带我去哪里。到目前为止还没有这样的运气。
per_io_data_size
是这里的关键。通过设置 struct dm_target
的成员,device-mapper 在 dm_target_io 之前为用户定义的数据分配了额外的 space 所以它们被放置如下:
(额外)(dm_target_io ...(克隆))
so dm_per_bio_data returns 指向 extra space.
开头的指针
struct dm_md_mempools *dm_alloc_md_mempools(struct mapped_device *md, enum dm_queue_mode type,
unsigned integrity, unsigned per_io_data_size)
{
struct dm_md_mempools *pools = kzalloc_node(sizeof(*pools), GFP_KERNEL, md->numa_node_id);
unsigned int pool_size = 0;
unsigned int front_pad;
if (!pools)
return NULL;
switch (type) {
case DM_TYPE_BIO_BASED:
case DM_TYPE_DAX_BIO_BASED:
pool_size = dm_get_reserved_bio_based_ios();
front_pad = roundup(per_io_data_size, __alignof__(struct dm_target_io)) + offsetof(struct dm_target_io, clone);
pools->io_pool = mempool_create_slab_pool(pool_size, _io_cache);
if (!pools->io_pool)
goto out;
break;
case DM_TYPE_REQUEST_BASED:
case DM_TYPE_MQ_REQUEST_BASED:
pool_size = dm_get_reserved_rq_based_ios();
front_pad = offsetof(struct dm_rq_clone_bio_info, clone);
/* per_io_data_size is used for blk-mq pdu at queue allocation */
break;
default:
BUG();
}
pools->bs = bioset_create(pool_size, front_pad, BIOSET_NEED_RESCUER);
if (!pools->bs)
goto out;
我正在尝试理解从内核源代码调用一些函数的内核模块的代码。代码在device-mapper.h.
struct dm_target_io {
struct dm_io *io;
struct dm_target *ti;
unsigned target_bio_nr;
unsigned *len_ptr;
struct bio clone;
};
static inline void *dm_per_bio_data(struct bio *bio, size_t data_size)
{
return (char *)bio - offsetof(struct dm_target_io, clone) - data_size;
}
我们在其他地方被告知,在 device_mapper.h 的评论中,"dm_per_bio_data returns the data location." 我不确定为什么会这样。
首先,dm_per_bio_data 接受一个 struct bio* 并用 offsetof(struct dm_target_io, clone) 减去它,这应该给出封闭的 dm_target_io 结构的开始。然后,它减去 data_size,它将指针指向--where?
我一直在寻找 dm_target_io 在另一个结构中声明的位置,以查看减去 data_size 可能带我去哪里。到目前为止还没有这样的运气。
per_io_data_size
是这里的关键。通过设置 struct dm_target
的成员,device-mapper 在 dm_target_io 之前为用户定义的数据分配了额外的 space 所以它们被放置如下:
(额外)(dm_target_io ...(克隆))
so dm_per_bio_data returns 指向 extra space.
开头的指针struct dm_md_mempools *dm_alloc_md_mempools(struct mapped_device *md, enum dm_queue_mode type,
unsigned integrity, unsigned per_io_data_size)
{
struct dm_md_mempools *pools = kzalloc_node(sizeof(*pools), GFP_KERNEL, md->numa_node_id);
unsigned int pool_size = 0;
unsigned int front_pad;
if (!pools)
return NULL;
switch (type) {
case DM_TYPE_BIO_BASED:
case DM_TYPE_DAX_BIO_BASED:
pool_size = dm_get_reserved_bio_based_ios();
front_pad = roundup(per_io_data_size, __alignof__(struct dm_target_io)) + offsetof(struct dm_target_io, clone);
pools->io_pool = mempool_create_slab_pool(pool_size, _io_cache);
if (!pools->io_pool)
goto out;
break;
case DM_TYPE_REQUEST_BASED:
case DM_TYPE_MQ_REQUEST_BASED:
pool_size = dm_get_reserved_rq_based_ios();
front_pad = offsetof(struct dm_rq_clone_bio_info, clone);
/* per_io_data_size is used for blk-mq pdu at queue allocation */
break;
default:
BUG();
}
pools->bs = bioset_create(pool_size, front_pad, BIOSET_NEED_RESCUER);
if (!pools->bs)
goto out;