学习笔记5

第十一章 ext2文件系统

11.1~11.2ext2文件系统、块

ext2文件系统是linux最为常用的文件系统,ext2是(The Second Extended File System)的简称。
ext2文件系统的布局如图所示。

Block#0:引导块:B0是引导块,文件系统不是用它,它用来容纳一个引导程序,从磁盘引导操作系统的时候会用到它。
Block#1:超级块:B1是超级块,用于容纳整个文件系统的信息。
下为超级块信息。

struct ext2_super_block {
u32 s_inodes_count;             // Inodes count
u32 s_blocks_count;             // Blocks count
u32 s_r_blocks_count;           // Reserved blocks count
u32 s_free_blocks_count;        // Free blocks count
u32 s_free_inodes_count;        // Free inodes count
u32 s_first_data_block;         // First Data Block
u32 s_log_block_size;           // Block size
u32 s_log_cluster_size;         // Allocation cluster size
u32 s_blocks_per_group;         // # Blocks per group
u32 s_clusters_per_group;       // # Fragments per group
u32 s_inodes_per_group;         // # Inodes per group
u32 s_mtime;                    // Mount time
u32 s_wtime;                    // Write time
u32 s_mnt_count;                // Mount count
u16 s_max_mnt_count;            // Maximal mount count
u16 s_magic;                    // Magic signature
//more non-essential fields
u16 s_inode_size;               // size of inode structure
};

Block#2:块组描述符块:ext2将磁盘块分成几个组。每个组有8192个块,每组用一个块组描述符结构体来描述。
Block#8:块位图:位图是用来表示某种项的位序列。0表示处于FREE的状态,而1表示为IN_USE(正在使用)状态。
Block#10:索引(开始)节点:每个文件都用一个128字节的唯一索引节点结构体进行表示。
数据块

11.3 邮差算法

邮差算法的意思是:一个城市有M个街区,编号从0到M-1,每个街区又有N座房子,编号从0到N-1。我们可以用(街区,房子)表示每一栋房子的位置,同时我们也可以使用线性方法将房子编为0,1,...,N等。如何进行这两种地址的转换?事实上较为简单。

Linear_address LA = N*block + house;
Block_address BA = (LA / N, LA % N);

注意只有从0开始计数的时候,转换才是有效的。

11.4-11.6 编程实例

可以通过C语言结合ext2fs开发包进行测试。可以进行的实践包括显示超级块、显示位图、显示根索引节点等等。
同时还可以通过这种方法进行遍历,可以遍历整个ext2文件系统树。
掌握了ext2文件系统的内容,就可以对其进行实现了。

下图为具体的ext2文件系统数据结构:

11.7~11.9 基本文件系统

在type.h文件中,包含了文件系统数据结构类型,比如超级块、主描述符、索引节点、目录条目结构等等。
实用程序函数:在util.c文件中包含了文件系统中常用的实用程序函数,包括iget()、iput()和getino()函数等。
如何执行ls:在学习了这些知识后,我们就能理解ls的功能以及其原理了。
通过ext2文件系统的相关知识,我们可以掌握在文件系统中创建、删除文件和路径的原理和方式。
1级文件系统函数及其原理:
1级文件系统函数的功能是文件和路径、创建和删除等较为直接和底层的相关的操作。

mkdir:mkdir创建一个带路径名的新目录。同时将目录的权限设置为0755,即rwxr_xr_x,所有人可以访问和读写,其他人可以访问但是只能读取。
creat:creat创建一个空的普通文件。
rmdir:删除一个路径。
link:链接文件。
unlink:解除链接文件。

2级文件系统函数及其原理:
2级文件系统函数的功能常常是打开、读取文件、写入文件等对文件进行的操作。

open:打开文件。
lseek:将打开的文件描述符在OFT中的偏移量从文件开头或当前位置开始的字节位置。
close:关闭文件描述符。

3级文件系统函数及其原理:
3级文件系统函数进行文件系统的挂载、卸载和文件保护等

mount:挂载。使用方法:mount filesys mount_point。
卸载:卸载已经挂载的文件系统。

实践内容过程、问题解决

实践——使用ext2文件系统相关内容读取超级块,并输出。

尝试使用书上的方法,读取并输出设备上超级块的内容

问题1

发现缺少必要的头文件ext2fs/ext2_fs.h,同时,书上给出的方法是使用sudo apt-get install ext2fs-dev进行安装,但发现报包不存在错误。


上网搜索资料,使用博客> https://blog.csdn.net/qq_32693119/article/details/88682028的方法成功解决。

问题2

不知道linux中磁盘设备作为文件的文件名

参考了博客:https://blog.csdn.net/MENGHUANBEIKE/article/details/103237313
得知sudo fdisk -l可以直接列出所有磁盘分区和对应设备名称。

问题3

进行代码运行时,无法打开设备文件

后来思考后考虑到可能原因是权限不够,故使用sudo再次尝试。

出现新问题:指定的设备不是ext2支持文件格式。
代码:

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <ext2fs/ext2_fs.h>
#include <unistd.h>
#include <time.h>

typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
typedef struct ext2_super_block SUPER;

SUPER *sp;
char buf[1024];
int fd, blksize, inodesize;

int print(char *s, u32 x)
{
    printf("%-30s = %8d\n", s, x);
}

int super(char *device)
{
    fd = open(device, O_RDONLY);
    if (fd < 0)
    {
        printf("open %sfailed\n", device);
        exit(1);
    }
    lseek(fd, (long)1024 * 1, 0);
    read(fd, buf, 1024);
    sp = (SUPER *)buf;
    printf("%-30s = %8x ", "s_magic", sp->s_magic);
    if (sp->s_magic != 0xEF53)
    {
        printf("NOT an EXT2 FS\n");
        exit(2);
    }
    printf("EXT2 FS OK\n");
    print("s_inodes_count",sp->s_inodes_count);
    print("s_blocks_count",sp->s_blocks_count);
    print("s_r_blocks_count",sp->s_r_blocks_count);
    print("s_free_inodes_count", sp->s_free_inodes_count);
    print("s_free_blocks_count", sp->s_free_blocks_count);
    print("s_first_data_block",sp->s_first_data_block);
    print("s_log_block_size",sp->s_log_block_size);
    print("s_blocks_per_group",sp->s_blocks_per_group);
    print("s_inodes_per_group",sp->s_inodes_per_group);
    print("s_mnt_count",sp->s_mnt_count);
    print("s_max_mnt_count",sp->s_max_mnt_count);
    printf("%-30s = %8x\n","s_magic",sp->s_magic);
    printf("s_mtime = %s\n", ctime(&sp->s_mtime));
    printf("s_wtime = %s", ctime(&sp->s_wtime));
    blksize = 1024 * (1 << sp->s_log_block_size);
    printf("block size = %d\n",blksize);
    printf("inode size = %d\n",sp->s_inode_size);
}

char *device = "mydisk";

int main(int argc,char* argv[]){
    if(argc>1)
        device = argv[1];
    super(device);
}

最终读取超级块的结果:

chatgpt











posted @ 2023-10-15 16:36  入林寻梨花白  阅读(3)  评论(0编辑  收藏  举报