Chinaunix

标题: 文件系统中,移动一个文件当如何实现? [打印本页]

作者: simpleman7210    时间: 2013-07-31 13:29
标题: 文件系统中,移动一个文件当如何实现?

对于一个简单的Unix或Linux文件系统,要移动一个文件,原理上似乎不难理解,
先撇开一些细节,我想过程大概是这样:得到这个文件所在的目录,从目录中删除对应的文件目录项,
再到目标目录中,添加一个目录项,如此就完成了移动。

但是具体实现时,我遇到了难题。因为文件系统可能被多个进程访问,所以从源目录中删除一个目录项,
需要对源目录加锁。往目标目录添加目录项,也是如此,需要对目标目录加锁。甚至还要对源文件加锁,
假如源文件是一个目录,要修改目录项"..",使其指向目标目录。

这么多的加锁操作,我怎么保证能一致性地完成呢?也许该用术语说,怎么当作一个原子或事务来完成呢?

另外,严格地说,还需要检查,目标目录的合理性:目标目录不可以是源目录的子目录,因为这样导致了目录之间的循环。

当我无论在做检查,或者在对文件或目录操作时,都不得不考虑,可能有另一个进程也可能在做同样的事情。说不定我要移动的文件已经被另一个进程移走了,说不定目标目录已经无效了....如此,让我觉得困难。所以我来寻求帮助。请问,如何实现文件的移动,使之既安全又完整呢?

  
作者: jeppeter    时间: 2013-07-31 15:40
回复 1# simpleman7210


    你问的问题是一个相当深奥的问题,一般真的没有办法一下子回答你。但总的要保证你的要求,一定要用日志。这种日志文件系统,如果是最简单的,一般是EXT3,如果是分布式的,是REISERFS,这些都是可以进行你说的那种原子性操作。
   
作者: amarant    时间: 2013-07-31 16:59
去看一下源码吧,文件系统相关操作考虑的问题非常多
作者: simpleman7210    时间: 2013-07-31 17:42
感谢jeppeter 和amarant 的回答,虽然我的问题没有马上解决,但起码让我得到了鼓励。
我是在写一个模拟文件系统的过程中遇到这个问题的。坦白说linux源代码我只看过0.11。所以请教有经验的人对这个问题的看法,以借鉴成熟系统是怎么处理的。
作者: amarant    时间: 2013-07-31 19:54
回复 4# simpleman7210


    又是一个自己动手实践的,鼓励一下!
作者: luoyan_xy    时间: 2013-07-31 22:50
把文件从原目录的目录项下删除,添加到新文件的目录项
文件夹需要特殊处理
往细了说,还要考虑新文件是否已存在同名,不允许移动一个目录到其子目录等等
作者: 瀚海书香    时间: 2013-08-01 14:39
回复 1# simpleman7210
对于一个简单的Unix或Linux文件系统,要移动一个文件,原理上似乎不难理解,
先撇开一些细节,我想过程大概是这样:得到这个文件所在的目录,从目录中删除对应的文件目录项,
再到目标目录中,添加一个目录项,如此就完成了移动。

但是具体实现时,我遇到了难题。因为文件系统可能被多个进程访问,所以从源目录中删除一个目录项,
需要对源目录加锁。往目标目录添加目录项,也是如此,需要对目标目录加锁。甚至还要对源文件加锁,
假如源文件是一个目录,要修改目录项"..",使其指向目标目录。

这么多的加锁操作,我怎么保证能一致性地完成呢?也许该用术语说,怎么当作一个原子或事务来完成呢?

另外,严格地说,还需要检查,目标目录的合理性:目标目录不可以是源目录的子目录,因为这样导致了目录之间的循环。

当我无论在做检查,或者在对文件或目录操作时,都不得不考虑,可能有另一个进程也可能在做同样的事情。说不定我要移动的文件已经被另一个进程移走了,说不定目标目录已经无效了....如此,让我觉得困难。所以我来寻求帮助。请问,如何实现文件的移动,使之既安全又完整呢?


实现一个真正的文件系统的确需要考虑很多东西。但是一些基本的思想你应该了解。

比如关于多个进程访问的问题,其实这个在内核里面到处都有这种情形比如skb、device、cache等等。解决的方法就是使用refcnt。删除的时候并不是真正的删除,而只是减少refcnt,当最后一个owner将refcnt减为0后,才做真正的删除。移动里面的删除,同样可以这样实现。

   




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