c读取ext2表和位图信息

    本节根据前面几讲介绍的 ext2 的数据结构,建立了几个结构体,用于存储 ext2 的各种表和位图信息。

为了读写方便,在 MFile 模块添加了如下几个函数。


unsigned char MFileReadByte(off_t liFrom)
{
    unsigned char rtn = 0;

    if(-1 == MFileRead(&rtn, 1, liFrom)){
        printf("%s read error, Message: %s\n", __FUNCTION__, strerror(errno));
        return MFILE_READ;
    }

    return rtn;
}

int MFileWriteByte(off_t liFrom, unsigned char ucWriteData)
{
    if(-1 == MFileWrite(liFrom, &ucWriteData, 1)){
        printf("%s write error, Message: %s\n", __FUNCTION__, strerror(errno));
        return MFILE_WRITE;
    }

    return MFILE_OK;
}

// 将 2 字节的整数拆分成 2 个 1字节的整数,并且按照小端顺序写入地址 liFrom
int MFileWriteUint16InByte(off_t liFrom, uint16 data)
{
    uint8 tmp = 0;

    tmp = (uint8)(data&0xff);
    MFileWriteByte(liFrom, tmp);
    tmp = (uint8)(data>>8);
    MFileWriteByte(liFrom+1, tmp);

    return MFILE_OK;
}

// 将 4 字节的整数拆分成 4 个 1字节的整数,并且按照小端顺序写入地址 liFrom
int MFileWriteUint32InByte(off_t liFrom, uint32 data)
{
    uint8 tmp = 0;

    tmp = (uint8)(data&0xff);
    MFileWriteByte(liFrom, tmp);
    tmp = (uint8)((data>>8)&0xff);
    MFileWriteByte(liFrom+1, tmp);
    tmp = (uint8)((data>>16)&0xff);
    MFileWriteByte(liFrom+2, tmp);
    tmp = (uint8)((data>>24)&0xff);
    MFileWriteByte(liFrom+3, tmp);

    return MFILE_OK;
}

int MFileWriteStringInByte(off_t liFrom, char* str)
{
    uint32 i = 0;
    while('\0' != *(str+i)){
        MFileWriteByte(liFrom+i, *(str+i));
        i++;
    }

    return MFILE_OK;
}



// 读 4 字节,因为读到的是小端,所以要转换下
uint32 MFileRead4Byte(off_t liFrom)
{
    uint32 tmp = 0;
    uint32 rtn = 0;

    tmp = (uint32)MFileReadByte(liFrom);
    rtn |= tmp;
    tmp = (uint32)MFileReadByte(liFrom+1);
    rtn |= tmp<<8;
    tmp = (uint32)MFileReadByte(liFrom+2);
    rtn |= tmp<<16;
    tmp = (uint32)MFileReadByte(liFrom+3);
    rtn |= tmp<<24;    

    return rtn;
}

// 读 2 字节,因为读到的是小端,所以要转换下
uint16 MFileRead2Byte(off_t liFrom)
{
    uint16 tmp = 0;
    uint16 rtn = 0;

    tmp = (uint16)MFileReadByte(liFrom);
    rtn |= tmp;
    tmp = (uint16)MFileReadByte(liFrom+1);
    rtn |= tmp<<8;

    return rtn;
}

新建 MExt2 模块


MExt2.h

#include "../include/MFile.h"

//  Bm      ->  Bitmap
//  Loc     ->  Location
//  dir     ->  directories


#define     MEXT2_OK                     0
#define     MEXT2_INIT                  -1
#define     MEXT2_INFO                  -2
#define     MEXT2_IDLEBITMAP            -3
#define     MEXT2_IDLEINODEBLOCK        -4


// 块组描述符表
typedef struct{
    uint32      blockBmLoc;
    uint32      inodeBmLoc;
    uint32      inodeTable;
    uint16      freeBlocks;
    uint16      freeInodes;
    uint16      directories;
} sGroupDescriptor;

// inode 表
typedef struct{
    uint16      st_mode;
    uint16      user;
    uint32      size;
    uint32      atime;
    uint32      ctime;
    uint32      mtime;
    uint32      dtime;
    uint16      group;
    uint16      links;
    uint32      ocupiedBlocks;
    uint32      flags;
    uint32      osInfo;
    uint32      blocks[15];
} sInode;

// 数据块
typedef struct{
    uint32      inodeIndex;
    uint16      recordLen;
    uint8       fileNameLen;
    uint8       fileType;
    uint8       fileName[256];   // malloc 根据 fileNameLen    
}sDataBlock;

// super block
typedef struct
{
    uint32      inodes;
    uint32      blocks;
    uint32      reservedBlocks;
    uint32      freeBlocks;
    uint32      freeInodes;
    uint32      firstBlock;
    uint32      blockSize;      // 1024<<blockSize = 实际块大小(Bytes)
    uint32      log;            // 给 0 就成
    uint32      blocksPerGroup;
    uint32      framsPerGroup;
    uint32      inodesPerGroup;
    uint32      lastMountTime;
    uint32      lastWriteTime;
    uint16      mountNum;
    uint16      maxMountNum;
    uint16      magic;
    uint16      fsState;
    uint16      errBehav;
    uint16      minorRev;
    uint32      lastCheck;
    uint32      checkIntvl;
    uint32      osType;
    uint32      majorRev;
    uint16      reserverdBlocksUid;
    uint16      reserverdBlocksGid;
    uint32      firstInode;
    uint16      inodeSize;
    uint16      blockGroupIndex;
    uint8       compatibleFeatures[12];
    uint8       uuid[16]; 
    uint8       volmName[16];
    // 余下的填充零
} sSuperBlock;

MExt2.c

#include "../include/MExt2.h"

static char m_fileName[255] = {0};

static sSuperBlock          s_sprBlk;
static sGroupDescriptor     s_grpDescrpt;
static int sGetSuperBlockInfo(sSuperBlock* pSuperBlock);
static int sGetGroupDescriptorInfo(sGroupDescriptor* pGrpDescrpt);

int InitMExt2(char* cpFileName)
{
    if(0 > MFileOpen(cpFileName)){
        printf("InitMExt2 error, MFileOpen failed\n");
        return MEXT2_INIT;
    }
    sGetSuperBlockInfo(&s_sprBlk);
    sGetGroupDescriptorInfo(&s_grpDescrpt);

    return MEXT2_OK;
}

// 未加错误判断
// 超级块,占一个块
static int sGetSuperBlockInfo(sSuperBlock* pSuperBlock)
{
    pSuperBlock->inodes = MFileRead4Byte(0x400);
    pSuperBlock->blocks = MFileRead4Byte(0x400 + 4);
    pSuperBlock->reservedBlocks = MFileRead4Byte(0x400 + 4*2);
    pSuperBlock->freeBlocks = MFileRead4Byte(0x400 + 4*3);
    pSuperBlock->freeInodes = MFileRead4Byte(0x400 + 4*4);
    pSuperBlock->firstBlock = MFileRead4Byte(0x400 + 4*5);
    pSuperBlock->blockSize  = 1024<<MFileRead4Byte(0x400 + 4*6);
    pSuperBlock->blocksPerGroup = MFileRead4Byte(0x420);
    pSuperBlock->framsPerGroup = MFileRead4Byte(0x420 + 4);
    pSuperBlock->inodesPerGroup = MFileRead4Byte(0x420 + 4*2);
    pSuperBlock->inodeSize = MFileRead2Byte(0x458);
    pSuperBlock->blockGroupIndex = MFileRead2Byte(0x458 + 2);

    return MEXT2_OK;
}

int GetSuperBlockInfo(sSuperBlock* pSuperBlock)
{
    *pSuperBlock = s_sprBlk;

    return MEXT2_OK;
}


// 未完美错误判断
// 块组
static int sGetGroupDescriptorInfo(sGroupDescriptor* pGrpDescrpt)
{
    uint32  start = 0;

    // 首先获取起点,即超级块结束的位置
    start = 0x400 + 1024;

    pGrpDescrpt->blockBmLoc = MFileRead4Byte(start);
    pGrpDescrpt->inodeBmLoc = MFileRead4Byte(start + 4);
    pGrpDescrpt->inodeTable = MFileRead4Byte(start + 4*2);
    pGrpDescrpt->freeBlocks = MFileRead2Byte(start + 4*3);
    pGrpDescrpt->freeInodes = MFileRead2Byte(start + 4*3 + 2);
    pGrpDescrpt->directories = MFileRead4Byte(start + 4*3 + 2*2);

    return MEXT2_OK;
}

int GetGroupDescriptorInfo(sGroupDescriptor* pGrpDescrpt)
{
    *pGrpDescrpt = s_grpDescrpt;

    return MEXT2_OK;
}


// 获取 inode
int sGetInodeInfo(off_t addr, sInode* pSInode)
{
    int i = 0;

    pSInode->st_mode = MFileRead2Byte(addr);
    pSInode->user    = MFileRead2Byte(addr + 2*1);
    pSInode->size    = MFileRead4Byte(addr + 2*2);
    pSInode->group   = MFileRead2Byte(addr + 24);
    pSInode->links   = MFileRead2Byte(addr + 24 + 2);
    pSInode->ocupiedBlocks = MFileRead4Byte(addr + 24 + 2*2 );
    for(i=0; i<15; i++){
        pSInode->blocks[i] = MFileRead4Byte(addr + 40 + 4*i);
    }

    return MEXT2_OK;
}
    这里有函数名字前面有个 s,是因为计划将这些函数作为静态函数使用。目前为了开发调试方便,有的未加 static 关键字。

main.c

#include "../include/MExt2.h"

char fileName[] = "../../tmp/disk";


sSuperBlock sb;
sGroupDescriptor sg;

int main()
{
    InitMExt2(fileName);

    printf("GetSuperBlockInfo: ----------------------\n");
    GetSuperBlockInfo(&sb);
    printf("inodes: %ld\n", sb.inodes);
    printf("blocks: %ld\n", sb.blocks);
    printf("blockSize: %d\n", sb.blockSize);
    printf("reservedBlocks: %ld\n", sb.reservedBlocks);
    printf("freeBlocks: %ld\n", sb.freeBlocks);
    printf("freeInodes: %ld\n", sb.freeInodes);
    printf("firstBlock: %ld\n", sb.firstBlock);
    printf("blocksPerGroup: %ld\n", sb.blocksPerGroup);
    printf("framsPerGroup: %ld\n", sb.framsPerGroup);
    printf("inodesPerGroup: %ld\n", sb.inodesPerGroup);
    printf("inodeSize: %d\n", sb.inodeSize);
    printf("blockGroupIndex: %d\n", sb.blockGroupIndex);


    printf("GetGroupDescriptorInfo: ----------------------\n");
    GetGroupDescriptorInfo(&sg);
    printf("blockBmLoc: %d\n", sg.blockBmLoc);
    printf("inodeBmLoc: %d\n", sg.inodeBmLoc);
    printf("inodeTable: %d\n", sg.inodeTable);
    printf("freeBlocks: %d\n", sg.freeBlocks);
    printf("freeInodes: %d\n", sg.freeInodes);
    printf("directories: %d\n", sg.directories);

    return 0;
}
  • 编译后,运行,结果如下:
$ ./main.out 


GetSuperBlockInfo: ----------------------
inodes: 128
blocks: 1024
blockSize: 1024
reservedBlocks: 51
freeBlocks: 986
freeInodes: 117
firstBlock: 1
blocksPerGroup: 8192
framsPerGroup: 8192
inodesPerGroup: 128
inodeSize: 128
blockGroupIndex: 0
GetGroupDescriptorInfo: ----------------------
blockBmLoc: 6
inodeBmLoc: 7
inodeTable: 8
freeBlocks: 986
freeInodes: 117
directories: 2
  • 这里以获取 超级块信息 和 块组描述符 为例,其他的表信息获取类似。
阅读更多:   文件系统
添加新评论

icon_redface.gificon_idea.gificon_cool.gif2016kuk.gificon_mrgreen.gif2016shuai.gif2016tp.gif2016db.gif2016ch.gificon_razz.gif2016zj.gificon_sad.gificon_cry.gif2016zhh.gificon_question.gif2016jk.gif2016bs.gificon_lol.gif2016qiao.gificon_surprised.gif2016fendou.gif2016ll.gif