首页 > 系统相关 >《Unix/linux系统编程》教材第11章学习笔记

《Unix/linux系统编程》教材第11章学习笔记

时间:2023-10-15 13:34:41浏览次数:41  
标签:11 文件系统 索引 Unix fd linux buf 节点 block

第11章:EXT2文件系统

EXT2文件系统
Linux一直使用EXT2作为默认文件系统。

EXT2文件系统数据结构

  • 创建虚拟硬盘
    mke2fs [-b blksize -N ninodes] device nblocks
    eg:dd if=/dev/zero of=vdisk bs=1024 count=1440
    mke2fs vdisk 1440
    在一个名为vdisk的虚拟磁盘文件上创建一个EXT2文件系统,有1440个大小为1KB的块。

  • 虚拟磁盘布局

    Block#0:引导块

*超级块
Block#1:超级块,用于容纳整个文件系统的信息
下面是一些重要字段

  • 块组描述符
    Block#2:块组描述符块

  • 块和索引节点位图
    BLOCK#8:块位图(Bmap)
    BLOCK#9:索引节点位图(Lmap)

  • 索引节点
    BLOCK#10:索引节点

i_block[15]数组指向文件磁盘块的指针,这些磁盘块有:
直接块:i_block[0]至i_block[11],指向直接磁盘块。
间接块:
双重间接块:
三重间接块:

  • 数据块
    紧跟在索引节点块后面的是文件存储数据块。

  • 目录条目
    目录包含dir_entry结构,即:

    是一种可扩充结构。

邮差算法
在计算机系统中,经常出现下面这个问题。一个城市有M个街区,编号从0到M-1。每个街区有N座房子,编号从0到N-1。每座房子有一个唯一的街区地址,用(街区,房子)表示,其中0≤街区<M,0≤房子<N。来自外太空的外星人可能不熟悉地球上的街区寻址方案,倾向于采用线性方法将这些房子地址编为0,1,…,N-1,N,N+1等。已知某个街区地址BA=(街区,房子),怎么把它转换为线性地址LA,反过来,已知线性地址,怎么把它转换为街区地址?如果都从0开始计数,转换就会非常简单。

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

只有都从0开始计数时,转换才有效。如果有些条目不是从0开始计数的,则不能直接在转换公式中使用。我们把这种转换方法称为邮差算法。下面是邮差算法的几种应用。

  • C语言中的Test-Set-Clear位
    标准C语言程序中,最小的可寻址单元是一个字符或字节。在一系列位组成的位图中,通常需要对位进行操作。考虑字符buf[1024],它有1024个字节,用buf[i]表示,其中i = 0,1,...,1023。它还有8192个位,编号为0,1,2,...8191。已知一个位号BIT,例如1234,那么哪个字节i包含这个位,以及哪个位j在该字节中呢?
    i = BIT/8; j = BIT%8; //8 = number of bits in a byte.
    可以在C语言中结合使用邮差算法和位屏蔽来进行下面的位操作。
    .TST a bit for 1 or 0: if (buf[i] & (1 << j))
    .SET a bit to 1 : buf[i] |= (1 << j);
    .CLR a bit to 0 : buf[i] &= ~(1 << j);
    注意一些C语言编译器允许在结构体中指定位,如:
    struct bits{
    unsigned int bit0 : 1; //bit0 field is a single bit
    unsigned int bit123 : 3; //bit123 field is a range of 3 bits
    unsigned int otherbits : 27; //other bits field has 27 bits
    unsigned int bit31 : 1; //bit31 is the highest bit
    }var;
    该结构体将var.定义位一个32位无符号整数,具有单独的位或位范围。那么,var.bit0=0;将1赋值给第0位,则有var.bit123=5;将101赋值给第1位到第3位等。但是,生成的代码仍然依赖于邮差算法和位屏蔽来访问各个位。可以使用邮差算法直接操作位图中的位,无须定义复杂的C语言结构体。

  • 将索引节点号转换为磁盘上的索引节点
    在EXT2文件系统中,每个文件都有一个唯一的索引节点结构。在文件系统磁盘上,索引节点从inode_table块开始。每个磁盘块包含
    INODES_PER_BLOCK = BLOCK_SIZE/sizeof(INODE)
    个索引节点。每个索引节点都有一个唯一的索引节点号,ino=1,2,...,从1开始线性计数,已知一个ino,如1234,那么哪个磁盘块包含该索引节点,以及哪个索引节点在该块中呢?我们需要知道磁盘块号,因为需要通过块来读/写一个真正的磁盘。

block = (ino - 1) / INODES_PER_BLOCK + inode_table;
inode = (ino - 1) % INODES_PER_BLOCK;

同样,将EXT2文件系统中的双重和三重间接逻辑块号转换为物理块号也依赖于邮差算法。
将线性磁盘块号转换为CHS = (柱面、磁头、扇区)格式:软盘和旧硬盘使用CHS寻址,但文件系统始终使用线性块寻址。在调用BIOS INT13时,可使用该算法将磁盘块号转换为CHS。

编程示例
访问和显示EXT2文件系统的内容,安装ext2fs.h头文件。
sudo apt-get install e2fslibs-dev e2fslibs-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>
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);
}
  • 显示位图
  • 显示根索引节点
  • 显示目录条目

3级文件系统

  • 挂载算法
    挂载操作命令
    mount filesys mount_point
    可将某个文件系统挂载到mount_point目录上。

  • 卸载算法
    卸载文件系统操作可卸载已挂载的文件系统。

  • 交叉挂载点
    虽然可以轻松实现挂载和卸载,但是会有一定的影响。对于挂载,必须修改getino(pathname)函数来支持交叉挂载点。假设某文件系统newfs已被挂载到目录/a/b/c/上。当遍历一个路径名时,两个方向的挂载点可能会出现交叉。
    (1)向下遍历:当遍历路径名/a/b/c/x时,一旦到达/a/b/c的minode,就能看到minode已经被挂载(挂载标志=1)。我们不是在/a/b/c的索引节点中搜索x,而是必须要:
    跟随minode的mntPtr指针来定位挂载表条目。
    从挂载表的设备号中,将其根索引节点(ino=2)放入内存。
    然后,继续在挂载设备的根索引节点下搜索x。
    (2)向上遍历:假设在目录/a/b/c/x/上,然后向上遍历,例如cd ../../),将会与挂载点/a/b/c交叉。当到达挂载文件系统的根索引节点时,就能看到它是一个根目录(ino=2),但是它的设备号与实根的设备号不同,因此它现在还不是实根。可以使用它的设备号,找到它的挂载表条目,它指向/a/b/c的minode。然后,切换到/a/b/c的minode,继续向上遍历。因此,交叉挂载点就像一只猴子或松鼠从一棵树跳到另一棵树上,然后又跳了回来。

  • 文件保护
    在Unix/Linux中,可通过文件索引节点中的权限位实现文件保护。每个文件的索引节点都有一个i_mode字段,其中下面的9位是权限。9个权限位为:

    前3位适用于文件所有人,中间3位适用于与所有人同一组的用户,最后3位适用于其他所有用户。对于目录,x位表示某进程是否可进入目录。每个进程都有一个uid和gid。当某进程试图访问某个文件时,文件系统会根据文件的权限位检查进程uid和gid,以确定它是否能以目标操作模式访问文件。如果该进程没有适当的权限,访问会被拒绝。为简单起见,可以忽略进程gid,只使用进程uid来检查访问权限。

学习过程中的问题

在安装ext2fs开发包时,使用书本上给出的代码显示无法定位软件包。
询问gpt

更改代码解决

gpt苏格拉底挑战

  • ext2文件系统数据结构

  • 3级文件系统

代码

#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);
}

标签:11,文件系统,索引,Unix,fd,linux,buf,节点,block
From: https://www.cnblogs.com/weidaixdrx/p/17765342.html

相关文章

  • linux读书笔记第四章
    在Linux中,文件权限是保护文件和目录的重要机制之一。通过设置文件的属性和权限,可以控制对文件的访问、修改和执行操作。1.文件属性:在Linux中,每个文件都有三个基本属性:拥有者(user)、所属组(group)和其他人(others)。这三个属性确定了谁有权访问文件以及可以执行哪些操作。2.文件权限......
  • kernel6.5.7+busybox1.36.1制作一个Mini Linux (没启动起来)
    目录前奏下载linux内核源码并编译下载busybox的源代码制作根文件系统镜像文件安装qemu...有兴趣的同学可参考该文档将其完善...前奏rambo@debian:~$cat/etc/issueDebianGNU/Linux12\n\lrambo@debian:~$free-htotalusedfree......
  • Win11系统如何设置电脑睡眠唤醒时需要输入密码?
       ......
  • 2023-2024-1 20211306 密码系统设计与实现课程学习笔记5
    20211306密码系统设计与实现课程学习笔记5任务详情自学教材第11章,提交学习笔记知识点归纳以及自己最有收获的内容,选择至少2个知识点利用chatgpt等工具进行苏格拉底挑战,并提交过程截图,提示过程参考下面内容“我在学***X知识点,请你以苏格拉底的方式对我进行提问,一次一个问题......
  • linux命令-kill pkill
    linux环境杀死进程常用kill-9命令。kill-924213kill命令杀死指定进程PID,需要配合ps使用,而pkill直接对进程对名字进行操作,更加方便。比如pkill-9tomcat无需查找tomcat进程号,直接杀死tomcat相关进程。pkill踢掉用户还有一种用法,强制某个登陆用户下线。who命令查询当前登陆......
  • 以PMIC为例简析Linux MFD/Remap/Regulator的使用
     关键词:ADI、SPI、Regmap、MFD、Regulator、PMIC等等。 以SC27XX为例,梳理一个PMIC用到的内核模块。1.MFD框架MFD是Multi-FunctionDevice,MFD子系统是Linux下一种用于管理和控制多功能设备的软件框架。他提供一种统一接口,使得多个设备可以通过一个驱动程序进行管理和控制。K......
  • Linux 中 tmux工具实现分屏
     系统:centos7.61810001、下载tmux工具[root@pc1~]#tmuxbash:tmux:commandnotfound...[root@pc1~]#yuminstalltmux-y##安装命令 002、启动 tmux功能在终端直接输入 tmux,然后底部会出现如下效果: 003、左右分屏:ctrl+b,然后输入%: 00......
  • 20211128《信息安全系统设计与实现》第十一章学习笔记
    一、任务内容1.知识点归纳以及自己最有收获的内容,选择至少2个知识点利用chatgpt等工具进行苏格拉底挑战,并提交过程截图,提示过程参考下面内容(4分)“我在学***X知识点,请你以苏格拉底的方式对我进行提问,一次一个问题”核心是要求GPT:“请你以苏格拉底的方式对我进行提问”然后GPT......
  • Bazzite:专为 Steam Deck 和 PC 上的 Linux 游戏打造的发行版
    导读对于一个专为 Linux 游戏定制的发行版,你是否感兴趣呢?如果答案是肯定的,那么我们为你准备了绝佳选择。Bazzite是一个新推出的基于Fedora的发行版,它是为 Linux桌面上的游戏,以及越来越火热的 SteamDeck 定制的。在此文章中,我们将对Bazzite进行简短总结,并探讨......
  • 《Unix/Linux系统编程》教材学习笔记第十一章
    chapter11EXT2文件系统Linux一直使用EXT2(Card等1995)作为默认文件系统。EXT3(EXT3,2014)是EXT2的扩展。EXT3中增加的主要内容是一个日志文件,它将文件系统的变更记录在日志中。日志可在文件系统崩溃时更快地从错误中恢复。没有错误的EXT3文件系统与EXT2文件系统相同。EXT3的最新......