6.828(2018) hw: xv6 log

这个作业主要是让你熟悉xv6的文件系统中log部分。该作业共分为两个部分,第一个部分是根据代码回答一些问题,第二个部分是对现有的代码做一点点优化。

xv6 log

xv6 中 log 主要是为了解决崩溃恢复的问题。因为在文件系统中,很多操作涉及到磁盘上很多块的读写,在这些读写中间如果发生系统崩溃,那么磁盘上的文件系统就会陷入一种不一致的中间状态。比如。而log的设计就可以让一连串的读写成为一个原子操作,要么这一连串读写都不成功,要么都成功,而不会出现一部分成功的中间状态。

xv6 文件接口例子

这部分用几个例子来说明xv6 文件系统接口的函数调用过程,这几个例子是依次进行的。弄懂了这几个例子,就能对 xv6的文件系统的接口执行时的函数调用有更深的了解。

1. xv6 创建文件,命令为 echo > a, 如下:

$ echo > a
write 34 ialloc (from create sysfile.c; mark it non-free)
write 34 iupdate (from create; initialize nlink &c)
write 59 writei (from dirlink fs.c, from create)

call graph:
  sys_open      sysfile.c
    create      sysfile.c
      ialloc    fs.c
      iupdate   fs.c
      dirlink   fs.c
        writei  fs.c

首先是open系统调用,带了一个新建文件的参数,所以在 sys_open 中会去调用 create 函数,因为是新建文件,所以 dirlookup在该文件夹中没找到名为 a 的文件,返回0。转而去执行 ialloc, ialloc会分配一个新的 inode,修改它的 type, 并用 log_write写回,这就是上面的第一次 write, 所以 34 就是新分配的 inode 所在的块号。 ialloc 返回后,create 修改它的 nlink 等属性,再用 iupdate 进行更新,这就是上面的第二次 write。最后create 调用 dirlink 将新的 inode 挂在目标文件夹下面。在 dirlink 中,使用 writei 修改文件夹内容,writei修改完后会用 log_write 写回磁盘,这就是第三次 write,所以现在可以回答以下问题了。

Q: block 34block 59 里存的是什么?
A: block 34存的有新分配的文件 ainode, block 59存的是文件 a 的上级文件夹的目录,里面有文件 a 的信息。

Q: 为什么有两次对 block 34writei
A: 第一次是 create 调用 ialloc 分配 inode 时修改 type 进行保存所产生的。第二次是 create 随后修改 inodenlink 等属性再保存产生的。不过这两次修改在 cache buf 和 磁盘的 log 都只占一份(对于同一个 block 在内存中只能有一个 cache buf),所以也没啥影响。

Q: 如果并发地调用 ialloc 会怎么样?他们会得到同一个 inode 吗?
A: ialloc 主要调用 bread 来 读取 inode, 而bread 主要是调用 bget, 其在返回时会获取 bufsleeplock, 即整个 block 都被锁住。其他人必须等 brelse 释放了这个 block 才可能使用这个 inode。所以是不可能得到同一个 inode的。

2. xv6 写入文件,命令为 echo x > a, 如下:

$ echo x > a
write 58 balloc  (from bmap, from writei)
write 508 bzero
write 508 writei (from filewrite file.c)
write 34 iupdate  (from writei)
write 508 writei
write 34 iupdate

call graph:
 sys_write       sysfile.c
   filewrite     file.c
     writei      fs.c
       bmap
         balloc
           bzero
       iupdate

由于上面已经创建好了文件 a, 所以 open 不会产生 write。后面调用 write 系统调用才会产生 writesys_write 只是 filewrite 的一层包装。在 filewrite 中,会调用 writei 真正进行写入。writei会对每个 block 先调用 bmap 进行映射,由于文件目前还是空的,所以 bmap 会调用 balloc 分配一个 block, balloc 分配时会修改分配的块的 bit map 标志位,并用 log_write 保存。这对应着上面的第一次 write。所以block 58 为文件 a 第一个blockbit map 标志所在的 block。随后 balloc 调用 bzero 将新分配的块的内容全部置为0, bzero 对块写入后用 log_write 保存,这对应着上面的第二次 write。所以 block 508 为 文件 a的第一个块的块号。bmap 执行完返回后,writei 将数据写入到分配的块中,用 log_write 保存。这对应着上面的第三次 write。接着它更新 文件 ainodesize, 并用 iupdate 保存,这对应着上面的第四次 write,所以block 34存的有文件 ainode

到这里到这个文件的写入其实就已经结束了,后面的两次 write 其实是因为 echo 进行了两次 write 系统调用,第二次用来输出 newline ,也就是对应着最后的两次 write

Q: block 58block 508 里存的是什么?
A: block 34存的有新分配的文件 ainode, block 59存的是文件 a 的上级文件夹的目录,里面有文件 a 的信息。block 508 为 文件 a的第一个块的块号。

Q: 为什么有两次 writeiiupdate
A: 因为 echo 进行了两次 write 系统调用,第二次用来输出 newline ,也就是对应着最后的两次 write

3. xv6 删除文件,命令为 rm a, 如下:

$ rm a
write 59 writei (from sys_unlink; directory content)
write 34 iupdate (from sys_unlink; link count of file)
write 58 bfree  (from itrunc, from iput)
write 34 iupdate (from itrunc; zeroed length)
write 34 iupdate (from iput; marked free)

call graph:
 sys_unlink
   writei
   iupdate
   iunlockput
     iput
       itrunc
         bfree
         iupdate
       iupdate

rm 命令调用的就是 sys_unlink, 它会先调用 writei 去修改父文件夹的内容,在writei中会将修改后的块用log_write 保存,这就是第一次 write, 所以block 59存的是文件 a 的上级文件夹的目录,这与上面分析得到的结论保持一致。然后紧接着 sys_unlink 会修改 inodenlink, 并用 iupdate 保存,这对应着上面的第二次 write。所以block 34存的是文件 ainode, 这也与上面分析得到的结论保持一致。最后就是 iunlockput(ip);, 先解锁 inode, 再调用 iput 释放inode, iput 中调用 itrunc 再调用 bfree,
bfree 会修改文件 a 的块在bit map 中的标志位,并用 log_write 保存,这对应着上面的第三次 write。所以 block 58 为文件 a 第一个blockbit map 标志所在的 blockbfree 执行完后,itrunc修改 inodesize 为 0,并用 iupdate 保存。这对应着上面的第四次 writeitrunc 执行完后,iput 会将 inodetype 置为 0, 并用 iupdate 保存,这对应着上面的第五次 write

Q: block 34, block 58block 59 里存的是什么?
A: block 34存的有新分配的文件 ainode, block 59存的是文件 a 的上级文件夹的目录,里面有文件 a 的信息,block 58 为文件 a 第一个blockbit map 标志所在的 block

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值