页次: 1
博主看到你内容很有帮助,所以特地注册了一个账号这里回帖一下,同时更正一下博主的说法。
1091 } else if (S_ISLNK(inode->i_mode)) {
[color=#FF0000] 1092 // if (!inode->i_blocks) [/color]
1093 inode->i_op = &ext2_fast_symlink_inode_operations;
1094 // else {
1095 // inode->i_op = &page_symlink_inode_operations;
1096 // inode->i_mapping->a_ops = &ext2_aops;
1097 // }
1098 } else
针对博主上述的这个说法,这个地方inode->i_blocks,由于ext2文件系统的更新在高版本内核中每个inode会额外分配2个block用于acl规则的存储,
所以inode->i_blocks在低版本ext2中该值是0,但是在更新后的ext2文件系统中该值是2。
2.4.x高版本中已修复此问题
/*
* Test whether an inode is a fast symlink.
*/
static inline int ext2_inode_is_fast_symlink(struct inode *inode)
{
int ea_blocks = EXT2_I(inode)->i_file_acl ?
(inode->i_sb->s_blocksize >> 9) : 0;
return (S_ISLNK(inode->i_mode) &&
inode->i_blocks - ea_blocks == 0);
}
高版本如下:
else if (S_ISLNK(inode->i_mode)) {
if (ext2_inode_is_fast_symlink(inode)) {
inode->i_op = &ext2_fast_symlink_inode_operations;
nd_terminate_link(ei->i_data, inode->i_size,
sizeof(ei->i_data) - 1);
} else {
inode->i_op = &ext2_symlink_inode_operations;
if (test_opt(inode->i_sb, NOBH))
inode->i_mapping->a_ops = &ext2_nobh_aops;
else
inode->i_mapping->a_ops = &ext2_aops;
}
}
同时再针对这个软连长度问题也说明一下:
struct ext2_inode_info {
__u32 i_data[15];
__u32 i_flags;
__u32 i_faddr;
__u8 i_frag_no;
__u8 i_frag_size;
__u16 i_osync;
__u32 i_file_acl;
__u32 i_dir_acl;
__u32 i_dtime;
__u32 not_used_1; /* FIX: not used/ 2.2 placeholder */
__u32 i_block_group;
__u32 i_next_alloc_block;
__u32 i_next_alloc_goal;
__u32 i_prealloc_block;
__u32 i_prealloc_count;
__u32 i_high_size;
int i_new_inode:1; /* Is a freshly allocated inode */
};
在2.4.0版本,上面是一个ext2_inode的相关结构,如果一个软连接字符长度不超过15,那么该字符串将会被存放到i_data结构中,也就是说这个inode的block就是0,所以可以直接使用ext2_fast_symlink_inode_operations相关结构进行操作即可。如果一个软连接的长度超过15个字节,i_date此时就不够用了,那么该名称字符串需要重新申请一个block进行存储,基于文件申请缓存的原则,需要先申请一个page然后再把该page的内容写入到block中。而page_symlink_inode_operations就是提供了该inode对其page的操作,先从page中找找不到再从block找。
页次: 1