当前位置: 技术问答>linux和unix
关于unix(minix),nachos的文件系统的菜鸟问题
来源: 互联网 发布时间:2015-09-11
本文导语: 学校作业。我比较弱,大家包涵。如果有大虾知道nachos的东西就更好了。 nachos中的文件长度是被固定的。也就是生成后不能被改变。但是为什么是被固定的呢?它采用的是索引表分配空间的方法。难道这样的方法导...
学校作业。我比较弱,大家包涵。如果有大虾知道nachos的东西就更好了。
nachos中的文件长度是被固定的。也就是生成后不能被改变。但是为什么是被固定的呢?它采用的是索引表分配空间的方法。难道这样的方法导致了它的文件长度不能改变吗?
为什么unix和minix中的文件长度就不是固定的呢?
如果大家不知道我提问的具体内容,就大概说一下,一个简单的操作系统中,要实现文件长度不是生成时固定的,以后可以修改,写文件超出文件长度时能自动添加,需要做哪些工作吧。
多谢了。
nachos中的文件长度是被固定的。也就是生成后不能被改变。但是为什么是被固定的呢?它采用的是索引表分配空间的方法。难道这样的方法导致了它的文件长度不能改变吗?
为什么unix和minix中的文件长度就不是固定的呢?
如果大家不知道我提问的具体内容,就大概说一下,一个简单的操作系统中,要实现文件长度不是生成时固定的,以后可以修改,写文件超出文件长度时能自动添加,需要做哪些工作吧。
多谢了。
|
不管是逻辑还是物理,总要有个什么方法来找到具体的块吧?这样的方法还必须非常高效,就算不高效,也要是在常数时间内可以找到对应的块,这样的话,索引表就是比较高效的实现了,逻辑块也是基于这样的实现,所以还是会产生我上面说的那种情况的……
如果要解决这种问题,类似于FAT或者inode的方案是比较好的。如果你想单纯靠索引表解决问题的话,代码会变得非常复杂,并且可能伴随着大量的效率损失(想想看也知道,否则malloc干啥不用这种方案呢?)……
如果要解决这种问题,类似于FAT或者inode的方案是比较好的。如果你想单纯靠索引表解决问题的话,代码会变得非常复杂,并且可能伴随着大量的效率损失(想想看也知道,否则malloc干啥不用这种方案呢?)……
|
我认为Unix (system V)种用的是混合索引,在i-node中有char i_addr[40],没3个字节为一项,总共为13项(最后1个字节保留),这样i_addr[0-9]作为直接索引,后面的3项分别作为间接索引(指向一个索引表),2级索引,3级索引。。。。。
索引表4B为一个表项(若一个块的大小为1k,一个表项将可以容纳256项)
所以Unix可以支持很大的文件
对pipe文件,为了提高文件读写速度,限制为10k(当块为1k时),这样就只用到直接索引,将10个地址项作为循环队列使用
索引表4B为一个表项(若一个块的大小为1k,一个表项将可以容纳256项)
所以Unix可以支持很大的文件
对pipe文件,为了提高文件读写速度,限制为10k(当块为1k时),这样就只用到直接索引,将10个地址项作为循环队列使用
|
以传统System V的文件系统为例
struct dinode
{
unsigned short di_mode; /* mode and type of file */
short di_nlink; /* number of links to file */
short di_uid; /* owner's user id */
short di_gid; /* owner's group id */
off_t di_size; /* number of bytes in file */
char di_addr[40]; /* disk block addresses */
time_t di_atime; /* time last accessed */
time_t di_mtime; /* time last modified */
time_t di_ctime; /* time created */
};
di_addr[40],实际可用39,每3个字节一组,共13个地址,你可能误以为一个文件最长只有1k * 13 = 13k,其实UNIX的文件系统还有一个间址块的概念,即所谓的直接块、一次间址块、二次间址块和三次间址块,这样,一个unix下的普通文件的最大长度就可以为:
10个直接块,最多可有10k字节
1个具有256个直接块的一次间址块最多可有256k字节
1个具有256个一次间接块的二次间址块最多可有64M字节
1个具有256个二次间址块的三次间址块最多可有16G字节
(10 + 1 + 1 + 1 = 13)
但受到di_size的限制(32位长整形),实际上一个文件的最大长度不能超过4G(2的32次方)
这样说你知道是怎么一回事了吧
struct dinode
{
unsigned short di_mode; /* mode and type of file */
short di_nlink; /* number of links to file */
short di_uid; /* owner's user id */
short di_gid; /* owner's group id */
off_t di_size; /* number of bytes in file */
char di_addr[40]; /* disk block addresses */
time_t di_atime; /* time last accessed */
time_t di_mtime; /* time last modified */
time_t di_ctime; /* time created */
};
di_addr[40],实际可用39,每3个字节一组,共13个地址,你可能误以为一个文件最长只有1k * 13 = 13k,其实UNIX的文件系统还有一个间址块的概念,即所谓的直接块、一次间址块、二次间址块和三次间址块,这样,一个unix下的普通文件的最大长度就可以为:
10个直接块,最多可有10k字节
1个具有256个直接块的一次间址块最多可有256k字节
1个具有256个一次间接块的二次间址块最多可有64M字节
1个具有256个二次间址块的三次间址块最多可有16G字节
(10 + 1 + 1 + 1 = 13)
但受到di_size的限制(32位长整形),实际上一个文件的最大长度不能超过4G(2的32次方)
这样说你知道是怎么一回事了吧
|
文件长度不能改变的原因你不是已经说到了吗?就是因为分配表的问题,假设文件大小可以修改的话,那么你在修改之前在文件A后面紧接着写入了B文件,当你需要修改的时候则会产生什么样的问题呢?如果是依赖于簇的文件系统(譬如M$的FAT16/32),可以在簇里面包含指向下一个簇的指针,但是分配表的就不行。
如果你修改A的大小势必修改分配表,但是数据的连续性要求你把B的一部分空间也占用了,如此一来,B就会被损坏或者B后移,但是又可能导致B后面的文件要后移,如此一来,文件操作就变得非常复杂且低效……
所以为了比较简单,干脆就不允许修改文件的大小。主要是系统设计的时候就是这么干的,所以你也没办法了……
如果你修改A的大小势必修改分配表,但是数据的连续性要求你把B的一部分空间也占用了,如此一来,B就会被损坏或者B后移,但是又可能导致B后面的文件要后移,如此一来,文件操作就变得非常复杂且低效……
所以为了比较简单,干脆就不允许修改文件的大小。主要是系统设计的时候就是这么干的,所以你也没办法了……