minix文件系统

  1791人阅读  评论(0)  收藏  举报

minix文件系统和标准unix文件系统基本相同。它由6个部分组成,分别是:引导块,超级块,i节点位图,逻辑块位图,i节点,和数据区。如果存放文件系统的设备不是引导设备,那么引导块可以为空。PC机的块设备通常以512字节为一个扇区,而文件系统则以盘块为单位使用之。minix中1个盘块等于2个扇区大小。从引导块为第0个盘块开始计算。逻辑块可以为2^n个盘块,minix中逻辑块大小等于盘块。所以盘块=逻辑块=缓冲块=1024字节。超级块存放文件系统的整体信息。i节点位图描述了i节点的使用情况。文件通常将控制信息和数据分开存放,i节点就是存放文件的控制信息的,通常称之为inode。逻辑块位图则描述了逻辑块的使用情况。
linux中的 文件范围很广泛,不仅仅指普通文件。用ls -l命令可以发现显示的信息的最左边字符可以为"-","d","s","p","b","c",分别表示正规文件,目录文件,符号连接,命名管道,块设备,字符设备文件。紧跟在其后的9位字符可以为r,w,x,s,S等,描述了文件的访问权限。后面的信息有文件的用户名,组名,文件大小,修改日期等,这些信息当然是放在inode中的。文件名除外。那么文件系统是如何被加载的呢?在系统启动过程中,具体是在任务1的init()函数中,通过setup系统调用加载的,该函数调用mount_root()函数读取根文件系统的超级块和根inode节点。
下面,就结合文件系统的上述要素,及其数据结构讲解minix1.0文件系统。
1.超级块
struct super_block{
         unsigned short s_niodes; //节点数
         unsigned short s_nzones; //逻辑块数
         unsigned short s_imap_blocks; //i节点位图所占的数据块数
         unsigned short s_zmap_blocks; //逻辑块位图所占用的数据块数
         unsigned short s_firstdatazone; //第一个数据逻辑块号
         unsigned short s_log_zone_size; //log2(数据块数/逻辑块)
         unsigned short s_max_size; //文件的最大长度
         unsigned short s_magic ;    //文件系统魔数
//以下的字段仅出现在内存中
         struct buffer_head* s_imap[8];//i节点位图在缓冲区中的指针
         struct buffer_head* s_zmap[8];//逻辑块位图在缓冲区中的指针
         unsigned short s_dev;//超级块所在的设备号
         struct m_inode *s_isup;//被安装的文件系统的根节点
         struct m_inode *s_imount; //被安装到的i节点
         unsigned long s_time; //修改时间
         struct task_struct *s_wait; //等待该超级块的进程
         unsigned char s_lock; //被锁定标志
         unsigned char s_rd_only; //只读标志
         unsigned char s_dirt; //已修改标志
};
每个文件系统都要有一个超级块。内核维护一个超级块数组:
struct super_block super_block[NR_SUPER];
当一个文件系统被加载时,就将它的超级块读到这个数组中,并读取它的i节点和逻辑块位图到super_block的相应数组中。卸载一个文件系统时就执行相反的操作。
super.c 文件中实现了对超级块的操作,包括get_super,put_super,read_super,另外还有sys_umount,sys_mount, mount_root函数。get_super是从超级块数组中搜索指定设备的超级块。所以它要求相应的文件系统已加载或者已读到数组中。 read_super则是从盘上读取超级块。put_super是释放超级块以及相应的位图,这在sys_umount函数中被调用。
我们来看一下read_super这个函数。
static struct super_block *read_super(int dev)
{
         struct super_block *s;
         struct buffer_head *bh;
         int i,block;
         if(!dev)
                 return NULL;
//检查设备是否更换,这里是检查软盘是否更换,如果更换那么就释放其超级块,并使其位图和缓冲区无效
         check_disk_change(dev);
//如果该超级块已经在超级块数组中,那么就获取它并返回
         if(s=get_super(dev))
                 return s;
//否则就先在超级块数组中找到一个空项,准备读取后填充
         for(s=0+super_block;;s++){
                 if(s>=NR_SUPER+super_block)
                         return NULL;
                 if(!s->dev)
                         break;
         }
//找到空项后初始化它
         s->s_dev=dev;
         s->s_isup=NULL;
         s->s_imount=NULL;
         s->s_time=0;
         s->s_rd_only=0;
         s->s_dirt=0;
//然后锁定该超级块,并从设备上读取超级块。超级块在第1块
         lock_super(s);
         if(!(bh=bread(dev,1))
                 s->s_dev=0;
                 free_super(s);
                 return NULL;
         }
//然后将读取到的超级块从缓冲块读到超级块数组中
         *((struct d_super_block*)s)=*((struct d_super_block*)bh->data);
         brelse(bh);
//判断文件系统魔数是不是0x137f,minix的魔数
         if(s->s_magic!=SUPER_MAGIC){
                 s->s_dev=0;
                 free_super(s);
                 return NULL;
         }
//然后就读取设备上的i节点和逻辑块位图到缓冲区中,先初始化指针数组。I_MAP_SLOTS和Z_MAP_SLOTS都等于8,所以共有1024*8*8个比特用于描述逻辑块。而每个逻辑块为1024字节,所以minix1.0最大支持64M的文件系统。
         for(i=0;i<I_MAP_SLOTS;i++)
                 s->s_imap=NULL;
         for(i=0;i<Z_MAP_SLOTS;i++)
                 s->s_zmap
=NULL;
         block=2;
         for(i=0;i<s->s_imap_blocks;i++)
                 if(s->s_imap
=bread(dev,block))
                         block++;
                 else
                         break;
         for(i=0;i<s->s_zmap_blocks;i++)
                 if(s->s_zmap
=bread(dev,block))
                         block++;
                 else
                         break;
//如果读出的块数不等于因该站有的块数,则说明文件系统位图有问题,则释放掉所有申请的资源后退出
         if(block!=2+s->s_imap_blocks+s->s_zmap_blocks){
                 for(i=0;i<I_MAP_SLOTS;i++)
                         brelse(s->s_imap
);
                 for(i=0;i<Z_MAP-SLOTS;i++)
                         brelse(s->s_zmap
);
                 s->s_dev=0;
                 free_super(s);
                 return NULL;
         }
//对于申请空闲i节点的函数来讲,如果设备上所与的i节点都被使用,则返回为0。所以0号节点不能使用,逻辑块也是如此。
         s->s_imap[0]->b_data[0]|=1;
         s->s_zmap[0]->b_data[0]|=1;
//解锁超级块,返回超级块指针。       
         free_super(s);
         return s;       
}

 

minix文件系统的物理结构
--
1) minix文件系统是一种简单而又朴素的文件系统, ext2文件系统可看成是对minix的改进, 可以将每一个ext2块组看成一个微型的minix文件系统. 
--
2) minix文件系统的块长只允许为1k, 第1块为启动块, 第2块为超级块, 从第3块开始, 依次为inode位图块组, 数据块位图块组, inode块组, 最后为数据块组. 
--
3) minix文件系统的目录项由16位inode编号和定长的文件名区域组成, inode从1开始编号, 编号0标记删除的目录项, 编号1为根目录项. 目录项分为16字节版和32字节版, 最长文件名分别为14和30. 
--
4) minix文件系统的inode分为32字节版(minix_inode)和64字节版(minix2_inode). minix_inode只有1个时戳标记, 用户组号(i_gid)为8位, 它包含由9个16位字组成的二重文件索引表. minix2_inode则使用3个文件时戳, 16位gid和10个32位字组成的三重文件块索引表. 
--
5) 根据目录项和inode尺寸的不同, minix文件系统盘分为4种格式化版本, 其s_magic分别为0x137F, 0x138F, 0x2468, 0x2478. 
--
; include/linux/minix_fs.h:

/*
* minix super-block data on disk
*/
struct minix_super_block {
__u16 s_ninodes; inode总数
__u16 s_nzones; 16位数据块总数
__u16 s_imap_blocks; inode表位图块数
__u16 s_zmap_blocks; 数据块位图块数
__u16 s_firstdatazone; 数据块的起点
__u16 s_log_zone_size; 数据块长指数
__u32 s_max_size; 最大文件字节长度
__u16 s_magic; 版本特征值
__u16 s_state; 安装状态
__u32 s_zones; 32位数据块总数
};

/*
* This is the original minix inode layout on disk.
* Note the 8-bit gid and atime and ctime.
*/
struct minix_inode {
__u16 i_mode;
__u16 i_uid;
__u32 i_size;
__u32 i_time;
__u8  i_gid;
__u8  i_nlinks;
__u16 i_zone[9];
};

/*
* The new minix inode has all the time entries, as well as
* long block numbers and a third indirect block (7+1+1+1
* instead of 7+1+1). Also, some previously 8-bit values are
* now 16-bit. The inode is now 64 bytes instead of 32.
*/
struct minix2_inode {
__u16 i_mode;
__u16 i_nlinks;
__u16 i_uid;
__u16 i_gid;
__u32 i_size;
__u32 i_atime;
__u32 i_mtime;
__u32 i_ctime;
__u32 i_zone[10];
};

struct minix_dir_entry {
__u16 inode;
char name[0];
};

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值