Chinaunix

标题: 对一个简单文件系统代码分析后的疑惑 [打印本页]

作者: magiceyes    时间: 2008-11-19 19:12
标题: 对一个简单文件系统代码分析后的疑惑
附简单文件系统源代码
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 编辑 ]
作者: mars007    时间: 2008-11-19 21:53
建议兄弟看看注释:
"Implementing a small filesystem having one file"
你这个文件系统只有一个文件, 所有下面的代码足够了
if(page->index == 0) {
    memcpy(file_buf, page_addr, PAGE_SIZE);
    ClearPageDirty(page);
  }
作者: magiceyes    时间: 2008-11-19 22:14
原帖由 mars007 于 2008-11-19 21:53 发表
建议兄弟看看注释:
"Implementing a small filesystem having one file"
你这个文件系统只有一个文件, 所有下面的代码足够了
if(page->index == 0) {
    memcpy(file_buf, page_addr, PAGE_SIZE);
    Cl ...


我知道这是仅有一个文件的文件系统,
memcpy后难道就写到设备上了么?这不是简单的缓冲区拷贝么!
file_buf这个变量,别的地方也没有再引用啊!
另外,下一行就是清除当前页的脏位啊.其他在没做什么工作了.

我是不明白原理,即使只有一个文件是怎么写到设备上的?
作者: kns1024wh    时间: 2008-11-19 23:20
标题: 回复 #1 magiceyes 的帖子
掌握文件句柄
作者: magiceyes    时间: 2008-11-19 23:40
原帖由 kns1024wh 于 2008-11-19 23:20 发表
掌握文件句柄

能说详细些么?内核是怎么实现的?
作者: mars007    时间: 2008-11-20 09:08
没有实际的物理设备,只是在内存中开辟了一页来存数据,说白了设备就是file_buf




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2