⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 iobuf.c.txt

📁 linux内核学习笔记 希望想看的人可以很快下载到
💻 TXT
字号:
any problems, send mails to sindybear@163.com


相关文件
	/include/linux/iobuf.h
	/drivers/md/lvm.c




****************************kiobuf的分配和初始化过程**********************
(1)int alloc_kiovec(int nr, struct kiobuf **bufp)
	for (i = 0; i < nr; i++) {	//按照参数给定的数目分配kiobuf结构
		iobuf = vmalloc(sizeof(struct kiobuf));	//分配一个kiobuf结构
		kiobuf_init(iobuf);			//进行初始化
 		alloc_kiobuf_bhs(iobuf)) 		//
		bufp[i] = iobuf;
	}


(2)static void kiobuf_init(struct kiobuf *iobuf)
	memset(iobuf, 0, sizeof(*iobuf));		//全部置为0
	init_waitqueue_head(&iobuf->wait_queue);	//初始化等待信号量
	iobuf->array_len = KIO_STATIC_PAGES;
	iobuf->maplist   = iobuf->map_array;


(3)int alloc_kiobuf_bhs(struct kiobuf * kiobuf)
	for (i = 0; i < KIO_MAX_SECTORS; i++)	//生成buffer_head结构
		kiobuf->bh[i] = kmem_cache_alloc(bh_cachep, SLAB_KERNEL)
***************************************************************************



***************************kiobuf的一些辅助函数*****************************
/*
 * 这个函数主要作用是将按照参数的制定扩展kiobuf结构中的maplist。
 * 这个域主要是用来容纳page结构的。
 */
(1)int expand_kiobuf(struct kiobuf *iobuf, int wanted)
	struct page ** maplist;
	
	if (iobuf->array_len >= wanted)	//如果要求的page页数目比原来的还小
		return 0;		//就什么也不做
	maplist = (struct page **) 	//按照参数给定的数目分配page页结构的指针
		kmalloc(wanted * sizeof(struct page **), GFP_KERNEL);
	/* 
	 * 下面的代码很重要,因为kmalloc可能休眠,所以要重新检查一下
	 */
	if (iobuf->array_len >= wanted) {
		kfree(maplist);
		return 0;
	}
	
	if (iobuf->array_len > KIO_STATIC_PAGES)	//释放老的iobuf中的maplist
		kfree (iobuf->maplist);

	/*
	 * 将原来的iobuf中的页面信息复制到新的结构中,然后使用这个新的替代原来旧的
	 */	
	memcpy (maplist, iobuf->maplist, iobuf->array_len * sizeof(struct page **));
	iobuf->maplist   = maplist;
	iobuf->array_len = wanted;
****************************************************************************


***************************回调函数********************************
(1)
void end_kio_request(struct kiobuf *kiobuf, int uptodate)
	if ((!uptodate) && !kiobuf->errno)	//如果数据更新失败,进行错误设置
		kiobuf->errno = -EIO;

	/*
	 * 减少kiobuf的io_count计数。如果计数为0,说明kiobuf中的所有提交的bh请求都完成了。
	 * 如果这个kiobuf有end_io回调函数,就执行。同时唤醒kiobuf结构中的等待队列。
	 */
	if (atomic_dec_and_test(&kiobuf->io_count)) {	
		if (kiobuf->end_io)		
			kiobuf->end_io(kiobuf);
		wake_up(&kiobuf->wait_queue);
	}

*******************************************************************



*****************************等待机制***********************************
(1)
void kiobuf_wait_for_io(struct kiobuf *kiobuf)
	struct task_struct *tsk = current;		//得到进程的结构
	DECLARE_WAITQUEUE(wait, tsk);

	if (atomic_read(&kiobuf->io_count) == 0)	//如果kiobuf已经完成
		return;					//返回

	add_wait_queue(&kiobuf->wait_queue, &wait);	//将等待信号量加入到等待队列
repeat:
	set_task_state(tsk, TASK_UNINTERRUPTIBLE);	//设置为可终止状态
	if (atomic_read(&kiobuf->io_count) != 0) {
		run_task_queue(&tq_disk);		//进行磁盘读写操作
		schedule();				//调度
		if (atomic_read(&kiobuf->io_count) != 0)//如果kiobuf中还有没有完成的
			goto repeat;			//循环
	}
	tsk->state = TASK_RUNNING;			//设置为可运行状态
	remove_wait_queue(&kiobuf->wait_queue, &wait);	//从等待队列中删除
************************************************************************

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -