raid5_cache.c数据结构之r5l_io_unit

来源:互联网 发布:算法题库及答案 编辑:程序博客网 时间:2024/06/15 20:44

1 r5l_io_unit

/* * an IO range starts from a meta data block and end at the next meta data * block. The io unit's the meta data block tracks data/parity followed it. io * unit is written to log disk with normal write, as we always flush log disk * first and then start move data to raid disks, there is no requirement to * write io unit with FLUSH/FUA */struct r5l_io_unit {struct r5l_log *log;struct page *meta_page;/* store meta block */int meta_offset;/* current offset in meta_page */struct bio *current_bio;/* current_bio accepting new data */atomic_t pending_stripe;/* how many stripes not flushed to raid */u64 seq;/* seq number of the metablock */sector_t log_start;/* where the io_unit starts */sector_t log_end;/* where the io_unit ends */struct list_head log_sibling; /* log->running_ios */struct list_head stripe_list; /* stripes added to the io_unit */int state;bool need_split_bio;};
(1) struct r5l_log *log

指向raid5的全局配置结构体

(2) struct page *meta_page

功能:存储meta block(以sh为单位)

初始化:需要新的r5l_io_unit时,alloc_page(GFP_NOIO | __GFP_NOFAIL | __GFP_ZERO),接着bio_add_page(io->current_bio, io->meta_page, PAGE_SIZE, 0)添加到结构体current_bio的bvec链表

消亡:__free_page(io->meta_page),当r5l_io_unit内的数据写到raid后,调用r5l_complete_finished_ios->r5l_free_io_unit->__free_page(io->meta_page)

(3) int meta_offset

功能:记录当前meta_page中的偏移,记录现在一页中数据写到哪里(meta_page采用追加写的方法)

初始化:申请新的meta_page后,现在元数据页写一个r5l_meta_block,接着io->meta_offset = sizeof(struct r5l_meta_block)

变化:每次在meta_page中追加写新的页(data/parity)时,都会在meta_page写元数据信息,写完后offset移动到末尾,的io->meta_offset += sizeof(struct r5l_payload_data_parity) + sizeof(__le32) * (1 + !!checksum2_valid)

结束:判断log->current_io->meta_offset + payload_size > PAGE_SIZE时,说明元数据页不能存放一个完整的sh元数据,就提交current_bio到log中,同时state置IO_UNIT_TO_START

(4) current_bio

功能:接收数据,记录元数据页和stripe的数据/校验页,提交数据到log的单位

初始化:申请新meta时产生,io->current_bio = r5l_bio_alloc(log);

结束:结束函数io->current_bio->bi_end_io = r5l_log_endio

(5) pending_stripe

功能:记录结构体中stripe的数目

变化:新stripe添加到一个当前结构体时,atomic_inc(&io->pending_stripe);atomic_dec_and_test(&io->pending_stripe),接着设置io状态IO_UNIT_STRIPE_END

(6) seq

功能:元数据页的序列号

初始化:创建新meta时,io->seq = log->seq++;

变化:没有改变呀

(7) log_start

功能:记录结构体在log的起始扇区

初始化:创建新meta时,io->log_start = log->log_start

变化:current_bio添加新的page后,调用r5_reserve_log_entry函数,这个函数里log中记录当前log中位置(扇区为单位)会加上8(环形存储区域,考虑简单情形)log->log_start=log->log_start + BLOCK_SECTORS;io->log_end记录本次bio的结束位置,io->log_end = log->log_start

(8) log_end

功能:和log_start对应,记录结构体在log的结束扇区

(9) log_sibling

功能:如果io的状态是IO_UNIT_TO_END,就把io->log_sibing从log->running_ios移到log->finished_ios

初始化:创建新meta时,INIT_LIST_HEAD(&io->log_sibling),list_add_tail(&io->log_sibling, &log->running_ios),

变化:如果io的状态是IO_UNIT_TO_END,就把io->log_sibing从log->running_ios移到log->finished_ios,或者从log->finished_ios->io删除io->sibling

进:

出:

(10) stripe_list

功能:记录结构体相关的stripe

初始化:申请新meta时,INIT_LIST_HEAD(&io->stripe_list)

变化:从io->stripe_list中取sh->log_list,删除,并置sh->state为STRIPE_HANDLE,准备写入RAID

进:

出:


(11) state

功能:记录结构体当前状态,来对不同状态的结构体执行不同操作

可选值:

IO_UNIT_RUNNING: 接受新IO;设置条件,新建meta,状态初始化为这个状态

IO_UNIT_IO_START: 结构体的bio正在写log;设置条件,把current_bio写到log时

IO_UNIT_IO_END:已经写到log;设置条件,已经写到log里,在bio的endio中设置

IO_UNIT_STRIPE_END:已经写到RAID;设置条件,r5l_stripe_write_finished函数


(12) need_split_bio

功能:记录是不是填满log设备,并且log->log_start从零开始

原创粉丝点击