第十一章 EXT2 文件系统
EX2文件系统数据结构
创建虚拟硬盘
mke2fs [-b blksize -N ninodes] device nblocks
虚拟磁盘布局
Block#0:引导块
超级块
Block#1
容纳整个文件系统的信息
超级块的重要字段:
u32 s_inodes_count://文件系统中节点总数
u32 s_blocks_count://文件系统中块总数
u32 s_r_blocks_count://为超级用户保留的块数
u32 s_free_blocks_count: //文件系统中空闲块总数
u32 s_mtime://文件系统的挂接时间
u32 s_wtime://最后一次对该超级块进行写操作的时间
u32 s_magic ://魔数签名,用于确定文件系统版本的标志
u32 s_inodes_per_group://表示每个组块的inode数目,查找文件inode所在块的位置很重要
u32 s_mnt_count://文件系统挂接计数
u32 s_max_mnt_count://文件系统最大挂接计数
u32 s_state://文件系统的状态
块描述符
Block#2
块和索引节点位图
- BLOCK#8:块位图
- BLOCK:9:索引节点位图
索引节点
BLOCK#10:索引节点
- 直接块
- 间接块
- 双重间接块
- 三重间接块
数据块
紧跟在索引节点块后面的是文件存储数据块
目录条目
包含dir_entry结构
邮差算法
Linear_address LA = N*block + house;
Block_address BA = (LA/N,LA%N);
C语言中的Test-Set-Clear位
C语言结合使用邮差算法和位屏蔽来进行下面的位操作
将索引节点号转换为磁盘上的索引节点
编程示例(实践部分)
- superblock.c程序显示EXT2文件系统的超级块信息
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/io.h>
#include <ext2fs/ext2_fs.h>
typedef unsigned char u8;
typedef struct ext2_super_block SUPER;
typedef struct ext2_group_desc GD;
#define BLKSIZE 1024
SUPER *sp;
GD *gp;
char buf[BLKSIZE];
int fd;
// get_block() reads a disk block into a buf[]?
int get_block(int fd, int blk, char *buf)
{
lseek(fd, (long)blk*BLKSIZE, SEEK_SET);
return read(fd, buf, BLKSIZE);
}
int imap(char *device)
{
int i, ninodes, blksize, imapblk;
fd = open(device, O_RDONLY);
if (fd < 0)
{
printf("open %s failed\n", device);
exit(1);
}
get_block(fd, 1, buf); // get superblock
sp = (SUPER *)buf;
// check magic number to ensure itz s an EXT2 FS ninodes = sp->s_inodes_count //
ninodes = sp->s_inodes_count;
printf("ninodes = %d\n", ninodes);
get_block(fd, 2, buf); //
gp = (GD *)buf;
imapblk = gp->bg_inode_bitmap;
printf("imapblk = %d\n", imapblk);
get_block(fd, imapblk, buf);
for ( i = 0; i <= ninodes/8; i++)
{
printf("%02x ", (u8)buf[i]);
}
printf("\n");
}
char *dev = "mydisk";
int main(int argc, char*argv[])
{
if(argc>1) dev = argv[1];
imap(dev);
}
遇到以下问题:
通过翻书,发现需要输入
sudo apt-get install e2fslibs-dev e2fslibs-dev
安装ext2fs开发包
- 显示位图
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/io.h>
#include <ext2fs/ext2_fs.h>
typedef unsigned char u8;
typedef struct ext2_super_block SUPER;
typedef struct ext2_group_desc GD;
#define BLKSIZE 1024
SUPER *sp;
GD *gp;
char buf[BLKSIZE];
int fd;
// get_block() reads a disk block into a buf[]?
int get_block(int fd, int blk, char *buf)
{
lseek(fd, (long)blk*BLKSIZE, SEEK_SET);
return read(fd, buf, BLKSIZE);
}
int imap(char *device)
{
int i, ninodes, blksize, imapblk;
fd = open(device, O_RDONLY);
if (fd < 0)
{
printf("open %s failed\n", device);
exit(1);
}
get_block(fd, 1, buf); // get superblock
sp = (SUPER *)buf;
// check magic number to ensure itz s an EXT2 FS ninodes = sp->s_inodes_count //
ninodes = sp->s_inodes_count;
printf("ninodes = %d\n", ninodes);
get_block(fd, 2, buf); //
gp = (GD *)buf;
imapblk = gp->bg_inode_bitmap;
printf("imapblk = %d\n", imapblk);
get_block(fd, imapblk, buf);
for ( i = 0; i <= ninodes/8; i++)
{
printf("%02x ", (u8)buf[i]);
}
printf("\n");
}
char *dev = "mydisk";
int main(int argc, char*argv[])
{
if(argc>1) dev = argv[1];
imap(dev);
}
- 显示根索引节点
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/io.h>
#include <ext2fs/ext2_fs.h>
#define BLKSIZE 1024
typedef struct ext2_group_desc GD;
typedef struct ext2_super_block SUPER;
typedef struct ext2_dir_entry_2 DIR;
typedef struct ext2_inode INODE;
SUPER *sp;
GD *gp;
INODE *ip;
DIR *dp;
char buf[BLKSIZE];
int fd,firstdata, inodesize ,blksize, iblock;
char *dev = "mydisk";
int get_block(int fd, int blk, char *buf)
{
lseek(fd, blk*BLKSIZE, SEEK_SET);
return read(fd, buf, BLKSIZE);
}
int inode (char *dev)
{
int i;
fd = open(dev, O_RDONLY);
if(fd < 0)
{
printf("open faild\n");
exit(1);
}
get_block(fd, 2, buf);
gp = (GD *)buf;
printf("bmap_block=%d imap_block=%d inodes_table=%d \n",
gp->bg_block_bitmap,
gp->bg_inode_bitmap,
gp->bg_inode_table);
iblock = gp->bg_inode_table;
printf("----root inode information----\n");
get_block(fd, iblock, buf);
ip = (INODE *)buf;
ip++;
printf("mode = %4x ",ip->i_mode);
printf("uid = %d gid = %d\n", ip->i_uid, ip->i_gid);
printf("size = %d\n", ip->i_size);
//unsigned int tmp = ip->i_ctime;
printf("ctime = %s",ctime((const time_t *)&ip->i_ctime));
printf("links = %d\n", ip->i_links_count);
for ( i = 0; i < 15; i++)
{
if(ip->i_block[i])
{
printf("i_block[%d] = %d\n", i, ip->i_block[i]);
}
}
}
int main(int argc, char *argv[])
{
if(argc>1) dev = argv[1];
inode(dev);
}
3级文件系统函数
挂载算法
mount filesys mount_point
可将某个文件系统挂载到mount_point目录上
卸载算法同理
卸载算法
交叉挂载点
- 向下遍历
- 向上遍历
文件保护
9个权限位
文件系统项目拓展
多个组-4KB大小块-管道文件-I/O缓冲
苏格拉底挑战
- EXT2文件系统数据结构
- 3级文件系统