2.3.1.3扩展属性操作函数的通用实现如前所述,内核对扩展属性的相关操作提供了通用的实现方式,分别为generic_setxattr()、generic_getxattr()、generic_listxattr()及generic_removexattr()。下面针对generic_setxattr()函数进行分析,该函数定义在fs/xattr.c中,函数头如下所示: intgeneric_setxattr(struct dentry*dentry, const char *name, const void *value, size_tsiz,int flags)
该函数包含5个参数:dentry表示目标文件对应的目录项;name表示扩展属性的名字;value表示扩展属性的值;size表示扩展属性值的长度;flags表示相应的操作标志。
图2-5 generic_setxattr()函数调用流程图 如图2-5所示,下面结合源码对该函数的执行步骤进行说明: ①调用xattr_resolve_name()函数来查找指定命名空间中扩展属性的处理函数。该函数定义在fs/xattr.c中,它根据指定扩展属性所属的命名空间的名字,在超级块指定的处理程序数组中依次查找各命名空间的处理程序,最终返回相应的处理程序。 ②根据xattr_resolve_name()函数得到的扩展属性处理程序集来调用相应的set函数对扩展属性进行设置。 2.3.1.4扩展属性在ext4文件系统中的实现1 扩展属性在ext4中的存储 在ext4文件系统中,扩展属性可以存储在文件的inode中,也可以存储在新的磁盘块中。 图2-6即为扩展属性在ext4文件系统的inode中的存储格式,由图可知,扩展属性所占有的空间分为两部分:扩展属性首部和一系列的扩展属性项。每个数据项包含了扩展属性的名称和指向扩展属性值存储区域的指针,扩展属性值存储在扩展属性所在存储空间的末尾,属性名称和属性值相对增长;对于存储在磁盘块中的扩展属性,扩展属性项的存储格式和存放在inode中的扩展属性项的存储格式相同,区别仅在于扩展属性首部不同。如果文件的扩展属性存放在数据块中,那么当两个文件的扩展属性集合相同时,两者可以共享同一磁盘表示,这样有助于节省磁盘空间。
图2-6 存储在inode中的ACL在ext4文件系统中存储结构 对于扩展属性首部,如果扩展属性存储在文件的inode中,则用ext4_xattr_ibody_header结构体表示;如果存储在额外磁盘块中,则用ext4_xattr_header结构表示。这两个结构体均定义在fs/ext4/xattr.h中,其定义如下所示: struct ext4_xattr_header{ __le32h_magic; /* magic number for identification */ __le32h_refcount; /* reference count */ __le32h_blocks; /* number of disk blocks used */ __le32h_hash; /* hash value of all attributes */ __le32h_checksum; /* crc32c(uuid id xattrblock) */ /* id = inum if refcount=1, blknum otherwise */ __u32h_reserved[3]; /* zero right now */ };
struct ext4_xattr_ibody_header{ __le32h_magic; /* magic number for identification */ }; 如上所示,代码中已经对各字段含义进行了解释,因此这里不再赘述。这里只强调一下ext4_xattr_header中的h_blocks字段,尽管代码中注释为该字段用于记录可以使用的磁盘块数,但实际上该字段只能为1,任何其他值都是错误的。 对于每个扩展属性项,内核中使用ext4_xattr_entry结构体进行描述,定义如下所示: struct ext4_xattr_entry{ __u8e_name_len; /* length of name */ __u8e_name_index; /* attribute name index */ __le16e_value_offs; /* offset in disk block of value */ __le32e_value_block; /* disk block attribute is stored on (n/i) */ __le32e_value_size; /* size of attribute value */ __le32e_hash; /* hash value of name and value */ char e_name[0]; /* attribute name */ };
如上所示,结构体中各字段的含义在代码中已明确标注,因此这里不再赘述。 |
|
声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系
[邮箱地址] 删除
|