Linux的文件系统管理

来源:互联网 发布:难忘网络真情意伴奏 编辑:程序博客网 时间:2024/05/16 01:01

Unix业界有句话叫“一切皆文件”,Linux作为一个优秀的类Unix操作系统,具有强大的文件管理能力, 其中“一切皆文件”就是很突出的特点!

文件系统就是负责文件的管理。每一个文件通常包含两部分的内容,一个是文件的信息包括文件的权限、文件的所有者、时间参数等,一个是文件数据。前者放在一个叫inode的结构体中,每个文件的inode的编号都是唯一的;后者放在block区,每个block都有唯一的编号,文件占用一个或多个block。inode译成中文就是索引节点,它用来存放档案及目录的基本信息,包含时间、档名、使用者及群组等,该结构体中有成员指出该文件内容放的block编号是多少,如果一个文件太大,会占用多个block。换句话说,只要找到一个文件的inode结点,就能找到该文件的内容。

Linux一个文件系统内部的每个文件的管理是通过inode和block,至于整个文件系统的管理,是通过superblock(超级块)。记录的信息主要有:

1、 block与inode的总量;
        2、未使用与已使用的inode/block数量;
        3、block与inode 大小(block为1,2,4K,inode为128bytes);
                4、filesystem的挂载时间、最近一次写入数据的时间、最近一侧检验磁盘(fsck)的时间等文件系统的相关信息;

这个superblock非常重要,因为我们文件系统的基本信息都写在这里。一般来说,superblock的大小为1025字节。每个文件系统对应一个超级块,通过双向循环链表将超级块管理起来即可实现Linux对多个文件系统的管理。

那么对应单个的文件,Linux下是如何通过文件名来找到文件的呢?主要是两步骤:1、根据文件名,通过目录的对应关系找到文件对应的inode编号;2、根据文件编号找到inode表,再根据inode表中的block指针找到对应的文件内容。在Linux下,可以通过ls –i命令来查看每个文件的inode编号。inode该结构体的作为每个文件的标识,可通过stat函数将其内容读取到struct stat类型的结构体中。struct stat的结构如下。

struct stat {
                          dev_t                st_dev;        /* device */
                          ino_t                st_ino;        /* inode */
                          mode_t            st_mode;        /* protection */
                          nlink_t              st_nlink;        /* number of hard links */
                          uid_t                st_uid;        /* user ID of owner */
                          gid_t                st_gid;        /* group ID of owner */
                          dev_t                st_rdev;        /* device type (if inode device) */
                          off_t                st_size;        /* total size, in bytes */
                          blksize_t        st_blksize;        /* blocksize for filesystem I/O */
                          blkcnt_t          st_blocks;        /* number of blocks allocated */
                          time_t                st_atime;         /* time of last access */
                          time_t                st_mtime;        /* time of last modification */
                          time_t                st_ctime;        /* time of last status change */
                };

在stat结构体中st_dev成员为文件的设备号,可获得该设备的驱动类型及对应的file_operations 结构体即可以找到该文件的相关操作函数。

其中,st_mode的类型 mode_t.其实就是普通的unsigned int.

目前,st_mode使用了其低19bit. 0170000 => 1+ 3*5 = 16.

其中,最低的9位(0-8)是权限,9-11是id,12-15是类型。具体定义如下:

S_IFMT        0170000        bitmask for the file type bitfields
                  S_IFSOCK        0140000        socket
                  S_IFLNK        0120000        symbolic link
                  S_IFREG        0100000        regular file
                  S_IFBLK        0060000        block device
                  S_IFDIR        0040000        directory
                  S_IFCHR        0020000        character device
                  S_IFIFO        0010000        fifo
                  S_ISUID        0004000        set UID bit
                  S_ISGID        0002000        set GID bit (see below)
                  S_ISVTX        0001000        sticky bit (see below)
                  S_IRWXU        00700        mask for file owner permissions
                  S_IRUSR        00400        owner has read permission
                  S_IWUSR        00200        owner has write permission
                  S_IXUSR        00100        owner has execute permission
                  S_IRWXG        00070         mask for group permissions
                  S_IRGRP        00040        group has read permission
                  S_IWGRP        00020        group has write permission
                  S_IXGRP        00010        group has execute permission
                  S_IRWXO        00007        mask for permissions for others (not in group)
                  S_IROTH        00004        others have read permission
                  S_IWOTH        00002        others have write permisson
                S_IXOTH        00001        others have execute permission

当我们需要快速获得文件类型或访问权限时,最好的方法就是使用glibc定义的宏。如:S_ISDIR,S_IRWXU等。

例如要判断/home是目录还是文件可用:

struct stat buf;
        memset(&buf, 0, sizeof(struct stat));
                  lstat(“/home”, &buf);
                  if( S_ISDIR(buf.st_mode)) printf(“is directory\n”);
                if( S_ISREG(buf.st_mode)) printf(“is regular file\n”);

文件系统的管理作为Linux内核的重要部分,整体框架还是比较复杂的,本文只是在文件IO授课时的一个总结,欢迎批评指正。