前言
ext2_lookup是real_lookup中从VFS转入具体文件系统(此处是Ext2文件系统)处理的函数。从real_lookup传递给ext2_lookup的参数是父目录的inode结构 和 通过d_alloc函数分配的当前路径分量的dentry空壳(说是空壳,也不尽然,它里面填充有一些已知道的信息,其中就包括重要的:当前路径分量名)。ext2_lookup返回后,real_lookup也随之结束返回,接着do_lookup也返回。那么__link_path_walk(path_walk)的main loop就几乎结束了。
1、ext2_dir_entry_2
要解析ext2_look函数的前提是弄懂struct ext2_dir_entry_2结构。结构如下:
struct ext2_dir_entry_2 {
__le32 inode; /* Inode number */
__le16 rec_len; /* Directory entry length */
__u8 name_len;/* Name length */
__u8 file_type;
char name[EXT2_NAME_LEN];/* File name */
};
__le32 inode; /* Inode number */
__le16 rec_len; /* Directory entry length */
__u8 name_len;/* Name length */
__u8 file_type;
char name[EXT2_NAME_LEN];/* File name */
};
首先要知道ext2_dir_entry_2是什么。总得来说,它是dentry的磁盘结构,也就是说目录项在磁盘和内存中分别由struct ext2_dir_entry_2 和 struct dentry 表示,就如索引节点分别由strut ext2_inode 和 struct inode表示一样。进一步分析,Ext2文件系统的文件和目录都是用目录项及其对应的索引节点来表示,文件和目录在磁盘上的存储结构是一样的。所以实际上,如果目录项对应的是目录,其inode指向的索引节点中i_block[EXT2_N_BLOCKS]索引对应的数据块中存储的就是ext2_dir_entry_2结构;如果目录项对应的是文件,其inode指向的索引节点中i_block[EXT2_N_BLOCKS]索引对应的数据块中存储的就是文件数据。所以说目录文件的磁盘数据内容跟普通文件不一样,其存放的就是整个目录内所有文件的ext2_dir_entry_2结构。
然后分析文件名长度name_len。它是4的倍数。也就是说,文件名的字符串长度要向上取整为4的倍数。例如我们建立一个名为AA的目录项,那么name_len为AA按四字节对齐的结果,即4,name数组中实际存储情况为为0x41410000(注意name中的每一个0x00就是为了对齐而填充的一个字节)。
接下来解释目录项长度rec_len。rec_len字面意思是目录项的长度,实际代表的是某个具体的ext2_dir_entry_2结构在磁盘上实际代表占用的长度。其原因是,文件系统中文件名或目录的名称有长有短,最长限制是255个字符,但是为了减少不必要的空间浪费,不可能把每个ext2_dir_entry_2都固定占用最大长度,因此ext2_dir_entry_2结构是变长的,rec_len就代表了每一个特定的ext2_dir_entry_2结构在磁盘上占用的空间。即便这样,还是有讲究的。我们知道ext2_dir_entry_2 前4项是固定的,占用空间也是固定的为:4(__u32 inode) + 2(__u16 rec_len)+ 2(__u8 name_len + __u8file_type)=8(个字节)。而从最后一项name开始,一直到ext2_dir_entry_2结构结束这段占用的空间内容就很模糊。一种情况它可以全存储name的元素(即文件名或目录名),第二种情况它可以是name数组只占最前面一部分空间,后面剩余部分冗余空间(可能是一个或多个删除文件的ext2_dir_entry_2结构)。如果ext2_dir_entry_2结构是在中间,则一般是第一种情况。例如AA文件后面还有别的文件,则rec_len=4+2+2+4=12。(前三项为8,是固定长度。第四项是name的长度,是取4的整数倍后的值)。