Chinaunix首页 | 论坛 | 博客
  • 博客访问: 72863
  • 博文数量: 172
  • 博客积分: 2047
  • 博客等级: 大尉
  • 技术积分: 1745
  • 用 户 组: 普通用户
  • 注册时间: 2010-05-19 15:23
文章分类

全部博文(172)

文章存档

2011年(72)

2010年(100)

我的朋友

分类: C/C++

2011-03-25 14:36:52

文件系统下做底层。发过来的写请求其实没有立即完成,而是等到release 时来完成。
也就是“欺骗”上层说已经完成了。
它也就以为完成了。然后就会把另外一个命令发送过来。写入,截断,修改文件。

写入 和截断都有各自的问题。
写入时会以 修改之前的为初始版本,可见前面修改的就会被忽略掉了。
当然写入的位置会进行改变。开始写入的就是00 了。

截断因为需要知道是操作的什么文件。提供的参数只有path 和 len;
所以要从path 找到它应该操作的文件。
truncate 到不会出现写入忽略。如果截断的位置在写入中间,也会造成这样的问题。
如果新分配一个file 对象。那么也是以原始版本为基础。修改的结果还是没有把前一次考虑进去

如果采用map 记录了打开的文件。每次新打开文件。但是releas 本身没有完成,
那么查找的还是上一次的文件
但是这个文件同时也在被修改。如果锁住release。那么truncate 就会等待release 完成后进行。


他们实际要进行比较的对象是 write truncate 。但是现在变成了 truncate release 。
他们之间之前是可以同步完成的关系。

这是几个问题纠缠在一起
1、 如果truncate 保证是新对象。那么不会和release 纠缠,但是问题存在。
2、 如果truncate 使用旧有对象,那么就会和release 交互操作。可能是truncate 把文件改变了。
    release 在来写,可能是release 写了。truncate 再来。


我们最终要保证什么样的顺序?
write 操作完成。至少将本地信息改变后,才能进行文件的下一次写入。
这里不能对open 进行判断,open没有标志接下来是要做什么的。可以在write 和truncate 这个类型的
操作进行操作。

现在的问题是,如果考虑到了几次写入交互的问题,那么就需要对写入进行很严格的访问限制。
这里同时要保证不会妨碍正常的并行的写入。



我们实际上这里并没有违反它的规定。

这里有另外一个原则上的问题:系统的严格程度要达到什么样



1 o w r
2 o w r
2w 应该在1r 之后。

这本身也是满足系统的要求的?
(这里有两个文件本身就是同时打开,然后相互逐一写入的。)
比如 t1 t2 都打开的文件 a
t1 t2 open 了文件。
然后t1 写了一部分,t2 写了一部分。
这个作为编程者在编程时是不应该去做的。
当然如果做,并且每次指定好文件的offset ,那么是可以不犯错误的。
从文件系统的包容性来看。我们应该支持这种最为极端的情况。

如果我们都是在一个文件爱你打开 o w r 之后,才允许另外一批的写入。
那么第二个可能就等待太久了。
如我们在写入共同一个文件的时候。系统本身的log;

本来系统的意思是o r 不管。
只是负责管理 w w 之间的关系。保证它们是一个完成后另外一个进行。

如果内容传输本身就是在w 中进行的。
那么就有1w 2w 1w 1w 2w 这种情况出现。

但是如果规定是在 r 中传输数据。
而且想要保证数据的完整性。
如果考虑在1r 之后 在进行2w
那么就是 1w 1w 1w 2w 2w
这应该算是影响了系统本身的想法。。

如果我们依然要达到这样的效果,
可行的办法是 对数据写入部分进行处理。进行所操作。
也就是那个文件。
1file -- cfile
2file -- cfile

写入都采用先定位 在写入的方式。

之前还采用过共用 file 的方式。
file
file
大家使用一个file。
在open 是搜索文件是否打开了。文件如果打开过,有对象管理了。那么就直接使用了。
1、如果两个文件是同时打开,打开的时候都不会有文件存在,但是一个完成以后。
   后面一个就应该直接用前面一个的了。
   这里还有,他们会同时请求这个文件的目录。
   文件目录这里是否应该采用锁,锁的代价?时间是否会延长。
   锁应该锁什么,所应该是锁当前这个dir ,
   这里的困难就是没有办法对没有建立的对象将进行锁。
   除非是设置更高粒度的锁。锁住更多的对象。


在real_read_dir 时,需要检测该目录是否已经被读取过了。
进行目录锁。

在open 时,可以放置关于路径的锁。

现在需要做到的是:
对文件的修改能够按照一定顺序的完成,我们修改了它底层的返回。破坏了请求发起的顺序。
但最终要保证顺序是和原来一样的。不能在依赖于上层的管理。要底层来自己管理。


系统本身保证了底层写入是原子的:在一个写入操作没有完成之前是不会发起另外一次写入的。

从如果算作本地内容,我们也可以认为是写入完成了的。所以我们只要让对一个文件写入所修改的对象
是同一个就可以做到修改都正确写入。

我们保证open 时已经open 的文件是指向的对象是同一个。
读操作时不会有问题,读取时,大家都是有起始位置的。(采用cache 的读取方式可能需要更多的思考,
文件多次读取的时间是否会比较长,尽量采用内存。)


在写入上面,现在面对的问题是open
问题:如果前一次的写入已经达到了release 阶段,那么我们打开时,就应该把上一次的处理完在来处理这一次的。
可能是open 时发现文件已经在release 阶段。
也可能是write tuncate 时发现文件在release 阶段。
那么我们也需要在write tuncate 时对文件进行重新生成新的对象。

两次o w* r 可能处在的时间关系,也就是看第二次write 时,第一次所处的状况。
如果是write,那么二次write 处现在被锁住了,第一次write 完成后明显该进行第二次的write。
当然第一次write 没有完毕时,是不会有第二次的请求到来。
第一次write 完毕后,会调用第一次的write 和第二次的write 竞争。
这个时候两个请求只会有一个被送达。

应该来说只有写大文件才能看出。改变测试用例。




阅读(409) | 评论(0) | 转发(0) |
0

上一篇:mfs write data

下一篇:write 分析

给主人留下些什么吧!~~