11

c 生成 ext2 文件(直接寻址) – 2

 3 years ago
source link: https://blog.popkx.com/c-generate-a-ext2-file-2/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

c 生成 ext2 文件(直接寻址) – 2

发表于 2018-05-11 16:05:00   |   已被 访问: 495 次   |   分类于:   文件系统   |   暂无评论
上一节,我们用 c 添加了初始文件 xrk,采用的方法是在根目录的 block[0] 的末尾添加 xrk 的文件信息。不过,每个 inode 的 block[0~11] 都是直接寻址,是否可以直接使用 block[1~11] 添加文件呢?
  • 本节计划使用根目录 inode 的 block[1~11] 实现文件的添加。

计划添加 xrk1~11,里面均添加内容 www.xrkxzz.cn。

  • 因为前 21 个数据块和前 2 个 inode 已经被使用,所以我们从第 22 个数据块和第 3 个 inode 开始。

  • 以根目录的 block[1] 为例:

· 我们首先设置 block[1] = 22。
· 在第 22 个块中写入 xrk1 的 inode 信息(inode3)。
· 在第 3 个 inode 中写入 xrk1 的数据块 23(顺延)。
· 最后,在第 23 个块中写入 www.xrkxzz.cn。
  • 余下的根目录 inode 的 block[2~11] 均按此思路写。函数如下:
void GenFiles()
{
    int i = 0, j = 1;       // j=1 是因为 根目录的 inode.block[0] 被自己的 . 和 .. 占用了
    sDataBlock sdtmp;
    sInode sitmp;
    char name[5] = {0};
    int startBlock = 22;
    int startInode = 3;
    char buf[] = "www.xrkxzz.cn\n";

    while(j<12){
        memset(name, 0, 5);
        sprintf(name, "xrk%d", j);
        printf("name : %s -- startBlock: %d\n", name, startBlock);

        // 根目录指向的数据块
        sdtmp.inodeIndex        = startInode++;   // 第三个 inode
        sdtmp.recordLen         = s_sprBlk.blockSize;
        sdtmp.fileNameLen       = (j<10)?4:5;
        sdtmp.fileType          = 1;
        strcpy(sdtmp.fileName, name);  
        sLoadDataBlock(startBlock++, 0, &sdtmp);

        // inode 
        sitmp.st_mode         = 0x81A4;
        sitmp.user            = 0x0;
        sitmp.size            = s_sprBlk.blockSize;
        sitmp.atime           = 0x4764cc3b;
        sitmp.ctime           = 0x4764cc3b;
        sitmp.mtime           = 0x4764cc3b;
        sitmp.dtime           = 0x4764cc3b;
        sitmp.group           = 0;
        sitmp.links           = 1;
        sitmp.ocupiedBlocks   = 2;
        sitmp.flags           = 0;
        sitmp.osInfo          = 0;
        sitmp.blocks[0]       = startBlock++;
        for(i=1; i<15; i++)
            sitmp.blocks[i] = 0;
        sLoadInode(sdtmp.inodeIndex, &sitmp); 

        // inode 指向的数据块

        MFileWriteStringInByte( sitmp.blocks[0]*s_sprBlk.blockSize, buf);       
        //将对应的位图置 1
        sSetBlockBmp(sitmp.blocks[0]);

        j++;
    }  
}
  • 根目录 inode 的如下:
    sitmp.st_mode         = 0x41ed;
    sitmp.user            = 0x0;
    sitmp.size            = s_sprBlk.blockSize*12;             // ************ 非常重要,如果想用 2 个 sitmp.blocks,则至少的 2 个块吧,很好理解
    sitmp.atime           = 0x4764cc3b;                       // 最好是让 乘数因子 等于 实际用的 inode.blocks
    sitmp.ctime           = 0x4764cc3b;
    sitmp.mtime           = 0x4764cc3b;
    sitmp.dtime           = 0x4764cc3b;
    sitmp.group           = 0;
    sitmp.links           = 1;
    sitmp.ocupiedBlocks   = 2;
    sitmp.flags           = 0;
    sitmp.osInfo          = 0;
    sitmp.blocks[0]       = 21;         sitmp.blocks[1]       = 22;         
    for(i=2; i<13; i++)
        sitmp.blocks[i] = sitmp.blocks[1]+2*(i-1);
    sitmp.blocks[13] = 0;
    sitmp.blocks[14] = 0;
  • 在 main 函数中添加此函数的调用,编译运行,并且挂载到 linux,查看结果如下:
$ sudo mount -o loop disk /mnt
$ ls /mnt
xrk1  xrk10  xrk11  xrk2  xrk3  xrk4  xrk5  xrk6  xrk7  xrk8  xrk9
$ cat /mnt/xrk11
www.xrkxzz.cn
$ sudo umount /mnt
  • 成功了,一切符合预期。

这里很重要的一点是:inode 的 block[n] 必须是连续使用的。举个例子,如果 block[0~3] 被使用,而 block[4] 没有被使用,如果直接用 block[5] 来寻址,文件是无法被 linux 识别的。!!!!!!!!


阅读更多:   文件系统


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK