文件扩展属性(Extended Attributes, EA)
文件扩展属性是一种用于将任意元数据与文件i节点关联起来的技术,通常以名称-值对的形式存在。从Linux 2.6版本开始,系统开始支持这种功能,并在多种文件系统中得到实现,如Btrfs、ext2/ext3/ext4、JFS、Reiserfs和XFS等。
16.1 概述
扩展属性(EA)可以用于实现访问控制列表(ACLs)、文件能力等功能。此外,它们还可以记录文件的版本号、MIME类型、字符集信息或指向图标资源的指针等。
- 命名空间:EA被划分为不同的命名空间,包括
user
、trusted
、system
和security
。每个命名空间有不同的用途和权限要求。user
:非特权用户可以在权限允许的情况下读取和修改这些属性。trusted
:需要特权进程才能修改。system
:主要用于内核级别的操作,例如ACLs。security
:用于存储操作系统安全模块的数据,比如SELinux的安全标签。
16.2 实现细节
- 限制:
- EA名称长度不能超过255字节。
- EA值的最大容量为64KB。
- 在某些文件系统上,所有EA的总大小可能受限于单个逻辑磁盘块的大小(例如,在ext2/ext3/ext4文件系统中是1024字节到4096字节不等)。
16.3 操作扩展属性的系统调用
以下是用于创建、获取、删除和列出扩展属性的主要系统调用:
-
设置/更新EA值:
#include <sys/xattr.h> int setxattr(const char *path, const char *name, const void *value, size_t size, int flags); int lsetxattr(const char *path, const char *name, const void *value, size_t size, int flags); int fsetxattr(int fd, const char *name, const void *value, size_t size, int flags);
-
获取EA值:
ssize_t getxattr(const char *path, const char *name, void *value, size_t size); ssize_t lgetxattr(const char *path, const char *name, void *value, size_t size); ssize_t fgetxattr(int fd, const char *name, void *value, size_t size);
-
删除EA:
int removexattr(const char *path, const char *name); int lremovexattr(const char *path, const char *name); int fremovexattr(int fd, const char *name);
-
列出所有EA名称:
ssize_t listxattr(const char *path, char *list, size_t size); ssize_t llistxattr(const char *path, char *list, size_t size); ssize_t flistxattr(int fd, char *list, size_t size);
示例代码:简化版 setfattr
下面是一个简单的C程序示例,它接受命令行参数来创建或修改文件的user
扩展属性。这个程序类似于setfattr(1)
工具的功能简化版。
#include <sys/xattr.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
void usageError(char *progName) {
fprintf(stderr, "Usage: %s <filename> <attribute_name> <attribute_value>\n", progName);
exit(EXIT_FAILURE);
}
int main(int argc, char *argv[]) {
if (argc != 4) {
usageError(argv[0]);
}
const char *filename = argv[1];
const char *attr_name = argv[2];
const char *attr_value = argv[3];
// Ensure attribute name starts with "user."
char full_attr_name[256];
snprintf(full_attr_name, sizeof(full_attr_name), "user.%s", attr_name);
int result = setxattr(filename, full_attr_name, attr_value, strlen(attr_value), 0);
if (result == -1) {
perror("setxattr");
exit(EXIT_FAILURE);
}
printf("Successfully set extended attribute '%s' for file '%s'\n", full_attr_name, filename);
return 0;
}
编译并运行示例程序
假设你已经保存上述代码到一个名为set_ea.c
的文件中,可以通过以下命令编译和运行该程序:
gcc -o set_ea set_ea.c
./set_ea myfile my_attribute "This is the value of my attribute"
这将会为名为myfile
的文件设置一个名为user.my_attribute
的扩展属性,其值为"This is the value of my attribute"。
总结
通过使用扩展属性,你可以为文件添加额外的元数据,从而增强文件系统的功能和灵活性。理解如何利用系统调用来操作这些属性,可以帮助开发者更好地管理文件及其相关的元数据。本文介绍了如何设置、获取、删除和列出扩展属性,并提供了一个简单的示例程序来演示如何创建或修改文件的user
扩展属性。