专题2 文件系统结构

    技术2022-05-20  50

    1.       概述

    Unix文件系统可划分为引导块、超级块、i结点块(inode区)和数据区等四个部分,其中:

    (1)       引导块位于文件系统的第0号物理块,它保存了文件系统的引导代码;

    (2)       超级块位于文件系统的第1号物理块,它描述了文件系统本身的结构信息,这个信息的数据结构一般为“struct filsys”, 定义在文件“filsys”中;

    (3)       I节点区位于超级块之后,它描述了文件的属性信息,这个信息的数据结构一般为“struct dinode”,定义在文件“ino.h”中;

    (4)       数据区位于i节点之后,用于存储文件的内容。

    文件系统决定了文件的存储与寻址方式,UNIX文件系统采取了3级缓冲结构,并将文件属性存储于i节点中。

    UNIX下的文件属性包括文件类型、文件访问权限、文件属主ID、文件属组ID、文件链接类、文件长度和文件时间等信息,文件按类型可以分为普通文件、目录文件、管道文件、设备文件、符号链接文件和SOCKET文件等,这些信息存储在文件对应的i节点中。

    UNIX下获取文件系统信息的函数有statfsfstatfs

    UNIX下获取文件属性的函数有statfstatlstat

     

    磁盘文件读取工作原理:以命令”cat T1.c”为例

    在当前目录文件中查找文件“T1.c”及其对应的i节点编写,假设为1109i节点表中读取第1109号节点。读取i节点中文件属性、访问权限等信息读取i节点中磁盘地址表,按照三级索引规则在数据区读取文件内容。

    2.       获取文件属性的C程序代码

    #include <stdio.h>

    #include <stdlib.h>

    #include <string.h>

    #include <sys/types.h>

    #include <sys/stat.h>

    #include <time.h>

     

    int GetFileType(mode_t st_mode, char *resp);/*获取文件类型*/

    int GetFileMode(mode_t st_mode, char *resp);/*获取文件权限*/

    int GetFileOtherAttr(struct stat info, char *resp);/*获取文件其他的一些信息*/

     

    int main(int argc, char *argv[])

    {

        struct stat info;

        char buf[100], *p = buf;

        if(argc != 2)

        {

            fprintf(stderr, "ls1 filename/n");

            return -1;

        }

        memset(buf, 0, sizeof(buf));

        if(lstat(argv[1], &info) == 0)

        {

            p += GetFileType(info.st_mode, p);

            p += GetFileMode(info.st_mode, p);

            p += GetFileOtherAttr(info, p);

            printf("%s %s/n", buf, argv[1]);

        }

        else

        {

            fprintf(stderr, "open file failed. /n");

            return -1;

        }

        return 0;

    }

     

    int GetFileType(mode_t st_mode, char *resp)

    {

        if(resp == NULL)

            return 0;

        if(S_ISDIR(st_mode)) /*测试是否为目录文件*/

            resp[0] = 'd';

        else if(S_ISCHR(st_mode))/*测试是否为字符文件*/

            resp[0] = 'c';

        else if(S_ISBLK(st_mode))/*测试是否为块文件*/

            resp[0] = 'c';

        else if(S_ISREG(st_mode))/*测试是否为普通文件*/

            resp[0] = '-';

        else if(S_ISFIFO(st_mode))/*测试是否为管道文件*/

            resp[0] = 'p';

        else if(S_ISLNK(st_mode))/*测试是否为符号链接文件*/

            resp[0] = '1';

        else

            resp[0] = ' ';

       

        return 1;

     

    }

     

    int GetFileMode(mode_t st_mode, char *resp)

    {

        if(resp == NULL)

            return 0;

        memset(resp, '-', 9);

        if(st_mode & S_IRUSR) /*测试属主读权限*/

            resp[0] = 'r';

        if(st_mode & S_IWUSR)/*测试属主写权限*/

            resp[1] = 'w';

        if(st_mode & S_IXUSR)/*测试属主执行权限*/

            resp[2] = 'x';

        if(st_mode & S_IRGRP)/*测试组读权限*/

            resp[3] = 'r';

        if(st_mode & S_IWGRP)/*测试组写权限*/

            resp[4] = 'w';

        if(st_mode & S_IXGRP)/*测试组执行权限*/

            resp[5] = 'x';

        if(st_mode & S_IROTH)/*测试其他用户读权限*/

            resp[6] = 'r';

        if(st_mode & S_IWOTH)/*测试其他用户写权限*/

            resp[7] = 'w';

        if(st_mode & S_IXOTH)/*测试其他用户执行权限*/

            resp[8] = 'x';

        return 9;

    }

     

    int GetFileOtherAttr(struct stat info, char *resp)

    {

        struct tm *mtime;

        if(resp == NULL)

            return 0;

        mtime = localtime(&info.st_mtime);

        return sprintf(resp, " = m d ddd", info.st_nlink, info.st_uid, info.st_gid, info.st_size, mtime->tm_year + 1900, mtime->tm_mon + 1, mtime->tm_mday);

    }

     

    3.       读取文件系统信息C程序代码

     

    #include <stdio.h>

    #include <stdlib.h>

    #include <unistd.h>

    #include <sys/types.h>

    #include <sys/statfs.h>

    #include <sys/vfs.h>

     

    int main(int argc, char *argv[])

    {

        struct statfs buf;

        if(argc != 2)

            return 1;

        statfs(argv[1], &buf);

        printf("FILE SYSTEM:/ntype=%d/n", buf.f_type);/*文件系统类型*/

        printf("bsize=%d/n", buf.f_bsize);              /*数据块大小*/

        printf("blocks=%d/n", buf.f_blocks);            /*数据块总数*/

        printf("bfree=%d/n", buf.f_bfree);              /*可用块*/

        printf("files=%d/n", buf.f_files);              /*inode总数*/

        printf("ffree=%d/n", buf.f_ffree);              /*可用inode*/

        printf("%s  : %d blocks %d i -nodes/n", argv[1], buf.f_bfree, buf.f_ffree);

        return 0;

    }

     


    最新回复(0)