gpt4 book ai didi

创建一个重要的设备映射器目标

转载 作者:太空宇宙 更新时间:2023-11-04 02:28:04 25 4
gpt4 key购买 nike

我正在尝试编写一个用于 DM 的重映射目标。

我遵循了来自多个地方(包括 this Answer)的说明,所有这些基本上都给出了相同的代码。

这还可以,但对我来说还不够。

我需要修改正在重新映射的 struct bio 的“传输中”数据。

这意味着我需要深度克隆bio,包括数据;显然,所提供的函数(例如:bio_clone_bioset())根本不复制数据,而是将 iovec 指向原始页面/偏移量。

我尝试了以下方案的一些变体:

void
mt_copy(struct bio *dst, struct bio *src) {
struct bvec_iter src_iter, dst_iter;
struct bio_vec src_bv, dst_bv;
void *src_p, *dst_p;
unsigned bytes;
unsigned salt;

src_iter = src->bi_iter;
dst_iter = dst->bi_iter;
salt = src_iter.bi_sector;

while (1) {
if (!src_iter.bi_size) {
break;
}

if (!dst_iter.bi_size) {
break;
}

src_bv = bio_iter_iovec(src, src_iter);
dst_bv = bio_iter_iovec(dst, dst_iter);

bytes = min(src_bv.bv_len, dst_bv.bv_len);

src_p = kmap_atomic(src_bv.bv_page);
dst_p = kmap_atomic(dst_bv.bv_page);

memcpy(dst_p + dst_bv.bv_offset, src_p + src_bv.bv_offset, bytes);

kunmap_atomic(dst_p);
kunmap_atomic(src_p);

bio_advance_iter(src, &src_iter, bytes);
bio_advance_iter(dst, &dst_iter, bytes);
}
}

static struct bio *
mt_clone(struct bio *bio) {
struct bio *clone;

clone = bio_clone_bioset(bio, GFP_KERNEL, NULL);
if (!clone) {
return NULL;
}
if (bio_alloc_pages(clone, GFP_KERNEL)) {
bio_put(clone);
return NULL;
}

clone->bi_private = bio;

if (bio_data_dir(bio) == WRITE) {
mt_copy(clone, bio);
}

return clone;
}

static int
mt_map(struct dm_target *ti, struct bio *bio) {
struct mt_private *mdt = (struct mt_private *) ti->private;

bio->bi_bdev = mdt->dev->bdev;

bio = mt_clone(bio);
submit_bio(bio->bi_rw, bio);

return DM_MAPIO_SUBMITTED;
}

但是,这有效。

当我 submit_bio() 使用克隆的 bio 时,我没有收到 .end_io 调用并且调用任务被阻止(“信息:任务装载:488 被阻止超过 120 秒。”)。这与包含单个 iovec(1024 字节)的 READ 请求一起使用。在这种情况下,输入缓冲区当然不需要复制,因为它们应该被覆盖; 请求完成后,我需要将传入数据复制回原始缓冲区...但我没有到达那里。

我很明显漏掉了一些东西,但我无法理解是什么。

注意:我没有做任何优化(例如:使用更智能的分配策略),因为我需要先了解基础知识。

注意:我纠正了一个错误(感谢@RuslanRLaishev),不幸的是影响不大;看我自己的回答。

最佳答案

正确吗?

if (bio_alloc_pages(**bio**, GFP_KERNEL)) {
bio_put(clone);
return NULL;
}

if (bio_alloc_pages(**clone**, GFP_KERNEL)) {
bio_put(bio);
return NULL;
}

关于创建一个重要的设备映射器目标,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48054703/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com