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

📄 filemap.c.txt

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

相关文件
	/fs/buffer.c

(1)struct page * find_or_create_page(struct address_space *mapping, unsigned long index, unsigned int gfp_mask)
        page = __find_lock_page_helper(mapping, index, *hash);	//先试图照一个页面
        if (!page) {						
                struct page *newpage = alloc_page(gfp_mask);	//如果没有找到,就生成一个



***************************文件的读写****************************************
系统的读写都是以页为单位的。如果要写一整页的话,没有什么问题,但是如果要写一个页的一部分,
则要先从磁盘上读出这部分数据,然后将信数据复制到页中,然后将页置为dirty,交给系统写到磁盘上。
generic_file_write(struct file *file,const char *buf,size_t count, loff_t *ppos)
	struct address_space *mapping = file->f_dentry->d_inode->i_mapping;	//得到该文件的inode节点的mapping

	//循环对buf进行处理
	do {
		//得到一个缓冲页,先在cache中寻找,如果找不到,分配一个新的,特别要注意
		//这里的mapping,也就是关于这个inode节点的页处理函数就传递给这个页,
		//也就是说,分配的这个页就按照mapping中所指示的文件系统所给定的readpage,writepage
		//函数进行这个页面的读写操作
		page = __grab_cache_page(mapping, index, &cached_page);	
		
		kaddr = kmap(page);	//取出地址映射,为复制数据做准备

		//调用相应文件系统的prepare_write函数进行一些准备工作,正如前面所说
		//例如,要写页的一部分的话,要先将页面从磁盘上读出来,诸如此类的事情
		status = mapping->a_ops->prepare_write(file, page, offset, offset+bytes);

		//将用户态的数据复制到页面中
		page_fault = __copy_from_user(kaddr+offset, buf, bytes);	

		//刷新页面
		flush_dcache_page(page);

		//调用相应文件系统的commit_write函数进行真正的读写操作
		status = mapping->a_ops->commit_write(file, page, offset, offset+bytes);
	} while (count);
	……	//进行页面地址解除映射等工作
		
			
*****************************************************************************



*****************************文件读写页面的分配******************************
static inline struct page * __grab_cache_page(struct address_space *mapping,unsigned long index, struct page **cached_page)
	struct page *page, **hash = page_hash(mapping, index);	//得到哈希表的入口
repeat:
	page = __find_lock_page(mapping, index, hash);	//在哈西表中先寻找
	if (!page) {					
		if (!*cached_page) {
			*cached_page = page_cache_alloc(mapping);	//如果没有找到,就非配一个
			if (!*cached_page)
				return NULL;
		}
		page = *cached_page;
		if (add_to_page_cache_unique(page, mapping, index, hash))//将这个页面加入到哈希表中
			goto repeat;
		*cached_page = NULL;
	}
	return page;


int add_to_page_cache_unique(struct page * page,struct address_space *mapping, unsigned long offset,struct page **hash)
	spin_lock(&pagecache_lock);				//加锁,保护页缓冲哈希表
	alias = __find_page_nolock(mapping, offset, *hash);	//由于上面的操作可能引起调度,在检查一遍

	if (!alias)
		__add_to_page_cache(page,mapping,offset,hash);	//确信哈希表中没有这一项,将这个页面插入到表中

	spin_unlock(&pagecache_lock);				//解锁
	lru_cache_add(page);					//加入到lru列表中



static inline void __add_to_page_cache(struct page * page,struct address_space *mapping, unsigned long offset,struct page **hash)
	……			//进行常规的页面设置

	page_cache_get(page);	//page的引用计数count加一

	add_page_to_inode_queue(mapping, page);	//使用相应inode中的mapping对页面进行初始化
	add_page_to_hash_queue(page, hash);	//将页面加入到哈希表中



static inline void add_page_to_inode_queue(struct address_space *mapping, struct page * page)
	struct list_head *head = &mapping->clean_pages;

	mapping->nrpages++;
	list_add(&page->list, head);	//将这个信分配的叶面加入到clean队列中
	page->mapping = mapping;	//将页面的mapping域设置为相应文件系统的mapping域,
					//这样就可以使用这个文件系统的writepage等的函数设置
					//来进行文件的读写等操作


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













⌨️ 快捷键说明

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