# 15.6 File system recovering

接下来我们看一下发生在XV6的启动过程中的文件系统的恢复流程。当系统crash并重启了，在XV6启动过程中做的一件事情就是调用initlog函数。

![](https://1977542228-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MHZoT2b_bcLghjAOPsJ%2F-MSeczlhbFKSwLmq0egq%2F-MSjlpdC7kU7Jkb_m2t8%2Fimage.png?alt=media\&token=816178b1-18fa-4f4d-a180-d83093a91e38)

initlog基本上就是调用recover\_from\_log函数。

![](https://1977542228-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MHZoT2b_bcLghjAOPsJ%2F-MSeczlhbFKSwLmq0egq%2F-MSjm0zKwyo8J3kcTgE8%2Fimage.png?alt=media\&token=c07bbbe1-849f-4d35-a0f7-abd16ef92134)

recover\_from\_log先调用read\_head函数从磁盘中读取header，之后调用install\_trans函数。这个函数之前在commit函数中也调用过，它就是读取log header中的n，然后根据n将所有的log block拷贝到文件系统的block中。recover\_from\_log在最后也会跟之前一样清除log。

这就是恢复的全部流程。如果我们在install\_trans函数中又crash了，也不会有问题，因为之后再重启时，XV6会再次调用initlog函数，再调用recover\_from\_log来重新install log。如果我们在commit之前crash了多次，在最终成功commit时，log可能会install多次。

> 学生提问：如果一个进程向磁盘写了一些数据，但是在commit之前进程出现了故障，假设故障之后进程退出了，这样会有问题吗？
>
> Frans教授：简单回答是没问题，因此磁盘不会被更新，所以效果就像文件系统操作没有发生过一样。并且进程并不能在故障后恢复，唯一能在故障之后还能保持的是保存在磁盘中的状态。（注，应该是没有理解问题。进程通过write系统调用成功写入的数据，就算在成功落盘之前进程异常退出了，内核还是会写入到磁盘中，前提是内核还在运行。）
