ICS fslab

发布于 2019-09-12  1106 次阅读


一些参数

SUPERBLOCK: 1个block,存根目录'/'的inode

INODE_MAP: 1个block,4096 * 8 = 32768 个bit

DATABLOCK_MAP: 2个block,65536个bit

INODETABLE: 存inode,单个inode大小112字节,一个块存36个,32768 inode 共886个block

DATAREGION: 存空闲datablock.

inode结构:

mode_t , nlink_t, uid_t, gid_t, size_t, 3 * time_t, 12 * pointer, 2 * double_pointer, 1 * tri_pointer

pointer size = 4

实际系统没有使用tri_pointer.

datablock结构(目录):

每一个目录下的文件/目录记一个metadata = filename (24 bytes) + inode(4 bytes),共28bit.

一个datablock可存146个metadata.

一些函数

一般写法

从path读取inode,视情况要拆父目录和文件名;得到inode后遍历每一个pointer,更新datablock或者读取datablock,写回。

disk_read, disk_write

disk_read和disk_write只会对块和你给的buf指针进行交互(而不是直接给你那个块所在指针),所以每次disk_read得到buf,更新buf后还要用disk_write写回去.

这个特性为实现函数原子性提供了很大帮助:直到程序正常结束再写回,中间只修改buffer,出错return不写回,从而磁盘数据不受影响。唯一的例外是fs_write:当size过大时,由于每次都要真的分配一个datablock给inode,当datablock不够时直接return,虽然不写回但以后的申请datablock的操作都会失败;解决方法是预判是否会出错 或 用个数组存一下,便于回溯。

fs_rename

在调试cp命令时,我惊讶地发现cp会自动判断是否出现文件重名并覆盖,而mv指令若rename不去重则mv也不会去重。研究了以下发现cp判断若有重名文件则对那个文件truncate 0,所以会直接覆盖。所以rename也可以这样实现,不过我这里直接将那个文件remove了.

fs_read

它的返回值为实际读取的字节数,fuse课件里没写(愤怒).

fs_write

你实际上根本不用判断是否是追加写,也不用判断文件只读只写——上层已经帮你处理好了,追加写就是offset加上size,否则offset会为0.

注意覆盖写相当于全清空后写.(filesz <- 0)

另外我偷了懒,如果写入的数据小于块数量,不会将多余的空块删掉(truncate 会删掉),相当于懒标记,这样能省很大功夫。

fs_rmdir, fs_unlink

一个技巧:目录datablock的所有metadata保证连续性,即一个metadata紧挨着下一个metadata,这样有两个好处:目录的size有意义了,可以通过size直接找到最后一个metadata的位置;可以直接判断当前metadata是一个空的还是合法的(否则要多存一个tag位).

插入比较好维护:直接插到文件datablock尾;删除的话,将尾metadata和删除位置交换即可,所以我写了一个函数专门来找尾metadata.

fs_mkdir, fs_mknod

这两个函数实际上是一个东西,你可以先创建一个新inode,然后再插入对应位置里去,不用判断有没有重名文件(用echo时会直接更新这个文件.)

tricks & tips

1.更新inodetable时一次更新一个块,所以若一个函数里要更新同一个块的两个inode,则由于历史版本读取时间不一致可能导致实际只更新了一个inode,很麻烦,所以更新inode后要马上写回;而datablock互相独立,故没有这个问题.

2.执行mv命令的几种情况:

(1) mv 文件名a 目录 : newpath包含文件名a

(2) mv 文件名a (目录)/文件名b : (a!=b) newpath不变

(3) mv 文件名a (目录)/文件名a : newpath不变

(4) mv 目录a 目录b : newpath为b/a

以上/均表示目录分割符而非or.

也就是说,给你的oldpath和newpath已经帮你判断好是不是目录/文件了,直接做就行.

总结 & 感想

我总共写了30.4k (linux) , 1100余行... 每次在千行代码的庞然大物间移来移去总觉得很奇异,,

没有测试数据差评


WRYYYYYYYYY!