2021SC@SDUSC
首先来分析一下ext4文件系统的acl.h文件(位于fs/ext4文件夹下)的源代码。
先简单说一下什么是acl技术吧。acl(Access Control Lists,访问控制列表),是一种基于包过滤的访问控制技术,它可以根据设定的条件对接口上的数据包进行过滤,允许其通过或丢弃。
举个例子,比如说有三个用户在一个group里,分别是甲,乙,丙。甲跟乙的关系比较好,跟丙的关系不好,所以甲的文件想让乙查看,但不想让丙查看。可以让甲和乙再建一个group,但这就增加了不必要的开销。这时候acl的作用就体现出来了,可以给用户单独的权限来解决这个问题。
acl.h文件如下:
/* File: fs/ext4/acl.h (C) 2001 Andreas Gruenbacher, <a.gruenbacher@computer.org> */ #include <linux/posix_acl_xattr.h> #define EXT4_ACL_VERSION 0x0001 /* ext4文件系统的acl结构体,遵循posix标准 */ typedef struct { __le16 e_tag; __le16 e_perm; __le32 e_id; } ext4_acl_entry; /* ext4文件系统的简短结构体,与posix标准相比,没有e_id字段 */ typedef struct { __le16 e_tag; __le16 e_perm; } ext4_acl_entry_short; /* ext4的头部,只有一个版本号 */ typedef struct { __le32 a_version; } ext4_acl_header; /* 内联函数,根据acl项目的数目获得ext4的acl大小 */ static inline size_t ext4_acl_size(int count) { /* 由于e_id字段除了ACL_USER和ACL_GROUP都是空,所以如果count<=4的话,就是没有e_id的4个,就是acl头的大小加上count乘上ext4_acl_entry_short的大小 */ if (count <= 4) { return sizeof(ext4_acl_header) + count * sizeof(ext4_acl_entry_short); } else { /* 如果大于4,说明有ACL_USER和ACL_GROUP这两个字段,e_id不为空,所以除了头的大小和四个没有e_id字段的大小,加上 */ return sizeof(ext4_acl_header) + 4 * sizeof(ext4_acl_entry_short) + (count - 4) * sizeof(ext4_acl_entry); } } //从acl控制结构体的大小返回acl项的数目 static inline int ext4_acl_count(size_t size) { ssize_t s; //所有的acl都有acl头,所以先去除头结构体的大小 size -= sizeof(ext4_acl_header); //然后减去4个默认的 ACL_USER_OBJ, ACL_GROUP_OBJ, ACL_MASK, ACL_OTHER s = size - 4 * sizeof(ext4_acl_entry_short); /* 如果小于零,说明没有e_id不为零的项,直接减去header的大小除以ext4_acl_entry_short的大小就是数目 */ if (s < 0) { if (size % sizeof(ext4_acl_entry_short)) return -1; return size / sizeof(ext4_acl_entry_short); } else { /* 如果大于0,说明有e_id不为0的项,所以余下的大小除以ext4_acl_entry就得到数目 */ if (s % sizeof(ext4_acl_entry)) return -1; return s / sizeof(ext4_acl_entry) + 4; } } /* 如果配置了CONFIG_EXT4_FS_POSIX_ACL,就设置一些宏,否则设置宏和函数为空 */ #ifdef CONFIG_EXT4_FS_POSIX_ACL /* acl.c */ struct posix_acl *ext4_get_acl(struct inode *inode, int type); int ext4_set_acl(struct user_namespace *mnt_userns, struct inode *inode, struct posix_acl *acl, int type); extern int ext4_init_acl(handle_t *, struct inode *, struct inode *); /*如果没有配置宏*/ #else /* CONFIG_EXT4_FS_POSIX_ACL */ #include <linux/sched.h> #define ext4_get_acl NULL #define ext4_set_acl NULL static inline int ext4_init_acl(handle_t *handle, struct inode *inode, struct inode *dir) { return 0; } #endif /* CONFIG_EXT4_FS_POSIX_ACL */