bio切分函数 ---- 非递归实现
来源:互联网 发布:日语特点 知乎 编辑:程序博客网 时间:2024/05/20 08:01
以前的实现方式: 递归式的,但是在内核中递归是一个非常危险的举动, 所以把它实现成非递归的
数据结构:
struct md_bio_pair {
struct list_head bio_head;
struct bio *oldbio;
atomic_t count;
int err;
};
本来打算用bio自己的bi_next将bio串在一起的,但是后面的代码中使用了bi_next, 所以只能用一个新的链表,把要切分的bio串起来。
函数如下:
int do_split(struct bio *bio, struct asd_io_context *ioctx)
{
struct md_bio_pair *bp;
int chksize, split_offset, first_flag = 1, i=0, sum=0, ret = 0;
unsigned int remaining = bio->bi_size >> SECTOR_BITS, len;
unsigned short start_idx = 0;
struct bio *clone;
sector_t next_sec;
struct list_head *pos = NULL;
struct big_bio *tmp_big = NULL;
chksize = ioctx->chunk_size;
split_offset = chksize - (bio->bi_sector & (chksize - 1));
bp = mempool_alloc(asd_sys.src.biopair_mempool,GFP_NOIO);
if(IS_ERR(bp)){
klog(ERROR,"do_split fail\n");
}
memset(bp, 0, sizeof(struct md_bio_pair));
atomic_set(&bp->count,0);
bp->oldbio = bio;
INIT_LIST_HEAD(&bp->bio_head);
next_sec = bio->bi_sector;
do{
if(unlikely(first_flag)){
len = split_offset;
first_flag = 0;
} else {
len = MIN(remaining, chksize);
}
sum = 0;
for(i = start_idx; i < bio->bi_vcnt; i++){
sum += bio->bi_io_vec[i].bv_len >> SECTOR_BITS;
if(sum >= len){
break;
}
}
clone = split_bvec(bp, next_sec, start_idx, i+1, len, asd_sys.src.bioset);
start_idx = i + 1;
atomic_inc(&bp->count);
remaining -= len;
next_sec += len;
}while(remaining > 0);
list_for_each(pos, &bp->bio_head){
tmp_big = list_entry(pos, struct big_bio, list);
if(ret = asd_make_request(ioctx->q, tmp_big->bio)){
klog(ERROR,"====ghost.ret :%d=====\n",ret);
}
}
ioctx->bioret = 0;
return 0;
}
/*
* Creates a little bio that is just does part of a bvec.
*/
struct bio* split_bvec(struct md_bio_pair* bp, sector_t sector,
unsigned short start_idx, unsigned short end_idx,
unsigned int len, struct bio_set *bs)
{
struct bio *clone, *bio = bp->oldbio;
int nr = end_idx - start_idx + 1, i; /* the num of bi_vcnt */
unsigned long flag_md;
struct big_bio* tmp_big = kzalloc(sizeof(struct big_bio), GFP_KERNEL);
if(!tmp_big){
klog(ERROR, "malloc tmp_big fail\n");
}
clone = bio_alloc_bioset(GFP_NOIO, nr, bs);
for(i=start_idx; i < end_idx; i++){
clone->bi_io_vec[i-start_idx] = bio->bi_io_vec[i];
}
clone->bi_sector = sector;
clone->bi_bdev = bio->bi_bdev;
clone->bi_rw = bio->bi_rw;
clone->bi_vcnt = nr - 1;
clone->bi_size = len << SECTOR_BITS;
clone->bi_hw_segments = bio_hw_segments(clone->bi_bdev->bd_disk->queue,clone);
clone->bi_phys_segments = bio_phys_segments(clone->bi_bdev->bd_disk->queue,
clone);
clone->bi_end_io = md_bio_pair_end;
clone->bi_private = bp;
clone->bi_destructor = md_bio_destructor;
tmp_big->bio = clone;
list_add_tail(&tmp_big->list, &bp->bio_head);
return clone;
}
/* for each bio's callback in md_bio_pair */
static int md_bio_pair_end(struct bio *bi, unsigned int done, int err)
{
struct md_bio_pair *bp = (struct md_bio_pair *)bi->bi_private;
if(err){
bp->err = err;
klog(ERROR,"=====err :%d====\n");
}
if(bi->bi_size)
return 1;
md_bio_pair_release(bp);
return 0;
}
static void md_bio_destructor(struct bio *bio)
{
bio_free(bio, asd_sys.src.bioset);
}
void md_bio_pair_release(struct md_bio_pair *bp)
{
struct big_bio *tmp_big = NULL;
struct bio *master = bp->oldbio;
struct list_head* pos, *n;
unsigned long flag_md;
if (atomic_dec_and_test(&bp->count)){
list_for_each_safe(pos, n, &bp->bio_head){
tmp_big = list_entry(pos, struct big_bio, list);
list_del(pos);
tmp_big->bio->bi_destructor(tmp_big->bio);
kfree(tmp_big);
tmp_big = NULL;
}
bio_endio(master, master->bi_size, bp->err);
mempool_free(bp, asd_sys.src.biopair_mempool);
}
}
- bio切分函数 ---- 非递归实现
- 快速切分法寻找中位数的递归与非递归实现
- 组合函数递归和非递归实现
- 递归和非递归实现规律函数
- ackman函数的非递归实现
- Ackerman函数的非递归实现.
- ackerman函数的非递归实现(递归函数非递归化)
- Fibonacci函数的递归和非递归实现
- AVL树C++实现以及(递归函数)非递归改进
- 一类void 递归函数的非递归实现
- 某些函数的递归与非递归实现的比较
- Qt中删除文件夹的函数(非递归实现)
- 组合非递归实现
- Fibonacci 非递归实现
- InorderTraversal非递归实现
- 实现非递归表达
- HeapSort非递归实现
- 递归函数转换为非递归函数
- PostMethod获取post提交的页面代码
- LoaderMax 示例
- 加载jQuery的3种方式
- 简单循环队列模版(数组实现)
- html中的标签
- bio切分函数 ---- 非递归实现
- js判断页面关闭的方法
- C文件操作
- .net wsdl生成cs
- Android NDK的C/C++代码中利用JNI回调实现字符编码转换
- 【VBA研究】VBA代码的存放位置
- 【转】Java对象的强、软、弱和虚引用
- 应用程序扩展,通配符应用程序映射
- vc2008+mysql