你好,我有一个快速的问题,是否有人可以为我回答。 在仅一次写入系统中,一个人如何在其上实现读取系统。
答案 0 :(得分:1)
有很多解决方法,下面是其中的简单概述。
这样的光盘布局:
0 root block -- identifies the file system, maybe a pointer to the end of metadata (n)
k first data block -- contains data, possibly stale written to media.
l last data block -- last data block written.
m last meta data block -- contains directories, inode tables, etc...
n first meta data block -- contains initial directories, inodes, etc...
首次访问媒体时,文件系统需要确定这些值在哪里。对媒体的二进制搜索显示了 l 和 m 以及可能的 n 的位置。通常无法找到其他方式。
按此顺序查看元数据[m..n],在较低的块地址处遇到的文件的较新版本要比旧版本的文件低。即,元数据从高地址增长到低地址。如果您需要更新某些元数据,则只需要向前扫描,直到它的第一个实例为止。并且您可以复制您的实例并进行修改,以阻止[m-1]。
请注意,并非文件的所有元数据都需要替换;如果它有5个数据指针块,而您只更改了一个,则只需替换该块。灵活的树状结构在这里有帮助。
数据无关紧要;如果在文件的块3中更改字节,则文件系统必须找到块3的指针在哪里,并重写块指针树以反映新的块。如果您查看传统(例如v7 unix文件系统),这将显而易见。它可以处理一种更加复杂的布局,很难想象。
如果要执行类似以下内容的代码:
for (i = 0; i < N ; i++) {
write(fd, str+i, 1);
fsync(fd);
}
您可能会发现一次写入介质很快就会用完空间;您将至少每个字节提交一个磁盘块,并且可能更像3。16k是仅写介质的通用磁盘块大小,因此可能是每个字节48k。
更频繁地,文件系统将保持同步介质直到空闲时间,或者仅从另一个介质中保存的日志中执行定期快照,以防止出现上述病理情况。
许多形式的一次写入媒体并不是真正的写入一次,而是每个位都可以设置或清除一次。一个块可以多次写入,但是只有一个定向的转换实际上才生效。而且,许多形式的媒体都将从未写入块与特定的读取错误区分开。这些功能使元数据中的状态标志之类的事情成为可能,从而使一次写入文件系统的效率更高。
即使使用了真正的基于块的一次写入介质,仍然可以遵循这种方法,效率略低。例如,如果一个未初始化的块返回全零(或0xffs),则文件系统可以为每个块加上一个标识符作为前缀,从而降低IO的效率,但允许检测到未初始化的块。