raid5_cache.c数据结构之r5l_io_unit

结构体代码

struct r5l_log {
	struct md_rdev *rdev;

	u32 uuid_checksum;

	sector_t device_size;		/* log device size, round to
					 * BLOCK_SECTORS */
	sector_t max_free_space;	/* reclaim run if free space is at
					 * this size */

	sector_t last_checkpoint;	/* log tail. where recovery scan
					 * starts from */
	u64 last_cp_seq;		/* log tail sequence */

	sector_t log_start;		/* log head. where new data appends */
	u64 seq;			/* log head sequence */

	sector_t next_checkpoint;
	u64 next_cp_seq;

	struct mutex io_mutex;
	struct r5l_io_unit *current_io;	/* current io_unit accepting new data */

	spinlock_t io_list_lock;
	struct list_head running_ios;	/* io_units which are still running,
					 * and have not yet been completely
					 * written to the log */
	struct list_head io_end_ios;	/* io_units which have been completely
					 * written to the log but not yet written
					 * to the RAID */
	struct list_head flushing_ios;	/* io_units which are waiting for log
					 * cache flush */
	struct list_head finished_ios;	/* io_units which settle down in log disk */
	struct bio flush_bio;

	struct kmem_cache *io_kc;

	struct md_thread *reclaim_thread;
	unsigned long reclaim_target;	/* number of space that need to be
					 * reclaimed.  if it's 0, reclaim spaces
					 * used by io_units which are in
					 * IO_UNIT_STRIPE_END state (eg, reclaim
					 * dones't wait for specific io_unit
					 * switching to IO_UNIT_STRIPE_END
					 * state) */
	wait_queue_head_t iounit_wait;

	struct list_head no_space_stripes; /* pending stripes, log has no space */
	spinlock_t no_space_stripes_lock;

	bool need_cache_flush;
	bool in_teardown;
};
一、几个重要的元素

log_start

功能:新数据在log中的起始扇区

变化:向磁盘写新页的时候,扇区加8(为什么是8呢,因为默认一页是8个扇区呀)

current_io

功能:正在接收数据的结构体

初始化:创建meta时,log->current_io = r5l_new_meta(log)

删除:写log的时候,log->current_io = NULL

二、链表

running_ios:

功能:组织接收数据,没有完全写入log的io

初始化:初始化log的时候,INIT_LIST_HEAD(&log->running_ios)

进:创建meta的时候,io加入list_add_tail(&io->log_sibling, &log->running_ios)

出:如果io的state位是IO_UNIT_IO_END,io就会从running_ios移到finished_ios

io_end_ios:

功能:组织写入log,没有写入RAID的io(need_cache_flush)

初始化:初始化log的时候,INIT_LIST_HEAD(&log->io_end_ios)

进:当log->need_cache_flush为真的时候,r5l_move_io_unit_list(&log->running_ios, &log->io_end_ios,  IO_UNIT_IO_END);

出:加到flushing_ios ;list_splice_tail_init(&log->io_end_ios, &log->flushing_ios)

flushing_ios

功能:组织flush的io

初始化:初始化log的时候,INIT_LIST_HEAD(&log->flushing_ios)

进:

出:从io->stripe_list取下来后,提交sh,list_splice_tail_init(&log->flushing_ios, &log->finished_ios)

finished_ios

功能:组织已经写入log的io

初始化:初始化log的时候,INIT_LIST_HEAD(&log->finished_ios)

进;

出:r5l_complete_finished_ios,

no_space_stripes

功能:因log没有空间而pending的条带

初始化:

进:准备写log时,log没有空间存放,list_add_tail(&sh->log_list, &log->no_space_stripes)

出:log空间回收后,sh = list_first_entry(&log->no_space_stripes, struct stripe_head, log_list); list_del_init(&sh->log_list); 接着set_bit(STRIPE_HANDLE, &sh->state); raid5_release_stripe(sh)


三、几个有点难的元素

struct kmem_cache *io_kc:

赋值:log->io_kc = KMEM_CACHE(r5l_io_unit, 0)

使用:申请io,io = kmem_cache_zalloc(log->io_kc, GFP_NOIO | __GFP_NOFAIL)

释放:kmem_cache_destroy(log->io_kc)

struct md_thread *reclain_target

功能:回收的线程

wait_queue_head_t iounit_wait

初始化:init_waitqueue_head(&log->iounit_wait)

唤醒:wake_up(&log->iounit_wait)

使用:回收的时候wait_event_lock_irq(log->iounit_wait, r5l_reclaimable_space(log) > reclaimable, log->io_list_lock);


你可能感兴趣的:(Linux,md,raid5)