- 论坛徽章:
- 0
|
附简单文件系统源代码
src.zip
(2.93 KB, 下载次数: 92)
我下载了一个简单的文件系统rkfs,并做了以下工作
1.这个rkfs不知是哪个版本的,对照2.6.17.4内核的vfs修改接口
2.修改后,编译成功,可以成功加载,写用户态程序可以成功写入
而后重点分析了写操作的代码
对照《linux内核情景分析(上)》(p579--p623)ext2写操作分析rkfs源代码
对
static struct address_space_operations rkfs_aops = {
.readpage = rkfs_readpage,
.writepage = rkfs_writepage,
.prepare_write = rkfs_prepare_write,
.commit_write = rkfs_commit_write
}
中的rkfs_prepare_write和rkfs_commit_write不太理解.
现对ext2这两个函数的原理简单分析如下:
ext2_prepare_write:对ext2而言写操作调用ext2_prepare_write的功能是在写入前做的一些准备工作,
处理缓冲页面与设备上的逻辑内容是否一致,完成ext2的三重间接的设备块定位等等.
即这个函数建立了page缓存到buffer_head缓存的对应关系,且buffer_head中一个成员指明了
这个逻辑块所对应的设备块号.
ext2用的是内核提供的generic_commit_write函数,该函数将缓冲页面提交给内核线程kflushd
该线程处理脏的buffer_head队列,并写入设备.
我的问题是这样的:
大家先看一下rkfs的实现
static int
rkfs_prepare_write(struct file *file, struct page *page,
unsigned from, unsigned to) {
return 0;
}
static int
rkfs_commit_write(struct file *file, struct page *page,
unsigned from, unsigned to) {
struct inode *inode = page->mapping->host;
void *page_addr = kmap(page);
loff_t pos = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to;
printk("RKFS: commit_write: [%s] [%s] [%s] \n",
PageUptodate(page) ? "Uptodate" : "Not Uptodate",
PageDirty(page) ? "Dirty" : "Not Dirty",
PageLocked(page) ? "Locked" : "Unlocked");
if(page->index == 0) {
memcpy(file_buf, page_addr, PAGE_SIZE);
ClearPageDirty(page);
}
SetPageUptodate(page);
kunmap(page);
if (pos > inode->i_size) {
i_size_write(inode, pos);
mark_inode_dirty(inode);
}
return 0;
}
rkfs_prepare_write直接返回0,并没有做类似ext2的逻辑块到设备块的定位
rkfs_commit_write中也没有把块设置为脏块,插入一个脏块的队列
那么这个工作以后就看内核线程kflushd的处理了,既没有到设备块的定位,又没有脏块的处理
那内核线程怎么知道往硬盘上哪个块写入呢?
困惑了一周了!
[ 本帖最后由 magiceyes 于 2008-11-19 19:14 编辑 ] |
|