每个 group descriptor 是 32 bytes 那么大。从上面,我们看到了三个关键的 block 指针,这三个关键的 block 指针,我们已经在前面都提到过了。
3.3 Inode
前面都准备好了以后,我们现在终于可以开始读取文件了。首先要读的,当然是文件系统的根目录。注意,这里所谓的根目录,是相对于这一个文件系统或者说硬盘分区而言的,它并不一定是整个 Linux 操作系统上的根目录。这里的这个 root 目录存放在一个固定的 inode 中,这就是文件系统上的 inode 2。需要提到 inode 计数同 block 计数一样,也是全局性质的。这里需要特别注意的是,inode 计数是从 1 开始的,而前面我们提到过 block 计数是从 0 开始,这个不同在开发程序的时候要特别留心。(这一奇怪的 inode 计数方法,曾经让本文作者大伤脑筋。)
那么,我们先来看一下得到一个 inode 号数以后,怎样读取这个 inode 中的用户数据。在 super block 中有一个字段 s_inodes_per_group 记载了每个 block group 中有多少个 inode。用我们得到的 inode 号数除以 s_inodes_per_group,我们就知道了我们要的这个 inode 是在哪一个 block group 里面,这个除法的余数也告诉我们,我们要的这个 inode 是这个 block group 里面的第几个 inode;然后,我们可以先找到这个 block group 的 group descriptor,从这个 descriptor,我们找到这个 group 的 inode table,再从 inode table 找到我们要的第几个 inode,再以后,我们就可以开始读取 inode 中的用户数据了。
这个公式是这样的:block_group = (ino - 1) / s_inodes_per_group。这里 ino 就是我们的 inode 号数。而 offset = (ino - 1) % s_inodes_per_group,这个 offset 就指出了我们要的 inode 是这个 block group 里面的第几个 inode。
找到这个 inode 之后,我们来具体的看看 inode 是什么样的。
struct ext3_inode { __u16 i_mode; /* File mode */ __u16 i_uid; /* Low 16 bits of Owner Uid */ __u32 i_size; /* 文件大小,单位是 byte */ __u32 i_atime; /* Access time */ __u32 i_ctime; /* Creation time */ __u32 i_mtime; /* Modification time */ __u32 i_dtime; /* Deletion Time */ __u16 i_gid; /* Low 16 bits of Group Id */ __u16 i_links_count; /* Links count */ __u32 i_blocks; /* blocks 计数 */ __u32 i_flags; /* File flags */ __u32 l_i_reserved1; /* 可以忽略 */ __u32 i_block[EXT3_N_BLOCKS]; /* 一组 block 指针 */ __u32 i_generation; /* 可以忽略 */ __u32 i_file_acl; /* 可以忽略 */ __u32 i_dir_acl; /* 可以忽略 */ __u32 i_faddr; /* 可以忽略 */ __u8 l_i_frag; /* 可以忽略 */ __u8 l_i_fsize; /* 可以忽略 */ __u16 i_pad1; /* 可以忽略 */ __u16 l_i_uid_high; /* 可以忽略 */ __u16 l_i_gid_high; /* 可以忽略 */ __u32 l_i_reserved2; /* 可以忽略 */}; 上一篇:ext2文件系统下恢复误删除的文件 下一篇:Linux文件系统的反删除方法 |