你好,我有一个快速的问题,是否有人可以为我回答。在一次只写一次的媒体系统中,一个人如何在其上实现普通的读写文件系统。媒体将被初始化为全1。即使可以多次写入一个块,我也只能将1更改为0,而不能将其更改为其他方式。因此,如何在这样的媒体上支持常规文件系统。
有很多解决方法,这里是其中的简单概述。
光盘布局如下:
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。
更常见的是,文件系统将保持同步介质直到空闲时间,或者仅从另一个介质中保存的日志中执行定期快照,以防止出现上述病理情况。
许多形式的一次写入媒体并不是真正的一次写入,而是每个位只能被set或cleared一次。一个块可以多次写入,但是只有一个定向的转换实际上才生效。而且,许多形式的媒体都将never write块与特定的读取错误区分开。这些功能允许在元数据中使用状态标志之类的功能,从而使一次写入文件系统的效率更高。
即使使用了真正的基于块的一次写入介质,仍然可以遵循,但效率稍低。例如,如果未初始化的块返回全零(或0xffs),则文件系统可以为每个块加上标识符作为前缀,从而降低IO的效率,但允许检测未初始化的块。