Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b17500a0 authored by Gao Xiang's avatar Gao Xiang Committed by Greg Kroah-Hartman
Browse files

staging: erofs: introduce xattr & acl support



This implements xattr and acl functionalities.

Inline and shared xattrs are introduced for flexibility.
Specifically, if the same xattr occurs for many times
in a large number of inodes or the value of a xattr is so large
that it isn't suitable to be inlined, a shared xattr
kept in the xattr meta will be used instead.

Signed-off-by: default avatarMiao Xie <miaoxie@huawei.com>
Signed-off-by: default avatarChao Yu <yuchao0@huawei.com>
Signed-off-by: default avatarGao Xiang <gaoxiang25@huawei.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent fd68c6a2
Loading
Loading
Loading
Loading
+37 −0
Original line number Diff line number Diff line
@@ -26,6 +26,43 @@ config EROFS_FS_DEBUG

	  For daily use, say N.

config EROFS_FS_XATTR
	bool "EROFS extended attributes"
	depends on EROFS_FS
	default y
	help
	  Extended attributes are name:value pairs associated with inodes by
	  the kernel or by users (see the attr(5) manual page, or visit
	  <http://acl.bestbits.at/> for details).

	  If unsure, say N.

config EROFS_FS_POSIX_ACL
	bool "EROFS Access Control Lists"
	depends on EROFS_FS_XATTR
	select FS_POSIX_ACL
	default y
	help
	  Posix Access Control Lists (ACLs) support permissions for users and
	  groups beyond the owner/group/world scheme.

	  To learn more about Access Control Lists, visit the POSIX ACLs for
	  Linux website <http://acl.bestbits.at/>.

	  If you don't know what Access Control Lists are, say N.

config EROFS_FS_SECURITY
	bool "EROFS Security Labels"
	depends on EROFS_FS_XATTR
	help
	  Security labels provide an access control facility to support Linux
	  Security Models (LSMs) accepted by AppArmor, SELinux, Smack and TOMOYO
	  Linux. This option enables an extended attribute handler for file
	  security labels in the erofs filesystem, so that it requires enabling
	  the extended attribute support in advance.

	  If you are not using a security module, say N.

config EROFS_FS_USE_VM_MAP_RAM
	bool "EROFS VM_MAP_RAM Support"
	depends on EROFS_FS
+1 −0
Original line number Diff line number Diff line
@@ -8,4 +8,5 @@ obj-$(CONFIG_EROFS_FS) += erofs.o
# staging requirement: to be self-contained in its own directory
ccflags-y += -I$(src)/include
erofs-objs := super.o inode.o data.o namei.o dir.o
erofs-$(CONFIG_EROFS_FS_XATTR) += xattr.o
+32 −1
Original line number Diff line number Diff line
@@ -10,7 +10,7 @@
 * License.  See the file COPYING in the main directory of the Linux
 * distribution for more details.
 */
#include "internal.h"
#include "xattr.h"

/* no locking */
static int read_inode(struct inode *inode, void *data)
@@ -152,15 +152,26 @@ static int fill_inode(struct inode *inode, int isdir)
	if (!err) {
		/* setup the new inode */
		if (S_ISREG(inode->i_mode)) {
#ifdef CONFIG_EROFS_FS_XATTR
			if (vi->xattr_isize)
				inode->i_op = &erofs_generic_xattr_iops;
#endif
			inode->i_fop = &generic_ro_fops;
		} else if (S_ISDIR(inode->i_mode)) {
			inode->i_op =
#ifdef CONFIG_EROFS_FS_XATTR
				vi->xattr_isize ? &erofs_dir_xattr_iops :
#endif
				&erofs_dir_iops;
			inode->i_fop = &erofs_dir_fops;
		} else if (S_ISLNK(inode->i_mode)) {
			/* by default, page_get_link is used for symlink */
			inode->i_op =
#ifdef CONFIG_EROFS_FS_XATTR
				&erofs_symlink_xattr_iops,
#else
				&page_symlink_inode_operations;
#endif
			inode_nohighmem(inode);
		} else {
			err = -EIO;
@@ -208,3 +219,23 @@ struct inode *erofs_iget(struct super_block *sb,
	return inode;
}

#ifdef CONFIG_EROFS_FS_XATTR
const struct inode_operations erofs_generic_xattr_iops = {
	.listxattr = erofs_listxattr,
};
#endif

#ifdef CONFIG_EROFS_FS_XATTR
const struct inode_operations erofs_symlink_xattr_iops = {
	.get_link = page_get_link,
	.listxattr = erofs_listxattr,
};
#endif

#ifdef CONFIG_EROFS_FS_XATTR
const struct inode_operations erofs_fast_symlink_xattr_iops = {
	.get_link = simple_get_link,
	.listxattr = erofs_listxattr,
};
#endif
+22 −0
Original line number Diff line number Diff line
@@ -50,6 +50,9 @@ typedef u64 erofs_nid_t;
struct erofs_sb_info {
	u32 blocks;
	u32 meta_blkaddr;
#ifdef CONFIG_EROFS_FS_XATTR
	u32 xattr_blkaddr;
#endif

	/* inode slot unit size in bit shift */
	unsigned char islotbits;
@@ -72,6 +75,10 @@ struct erofs_sb_info {
#define EROFS_SB(sb) ((struct erofs_sb_info *)(sb)->s_fs_info)
#define EROFS_I_SB(inode) ((struct erofs_sb_info *)(inode)->i_sb->s_fs_info)

/* Mount flags set via mount options or defaults */
#define EROFS_MOUNT_XATTR_USER		0x00000010
#define EROFS_MOUNT_POSIX_ACL		0x00000020

#define clear_opt(sbi, option)	((sbi)->mount_opt &= ~EROFS_MOUNT_##option)
#define set_opt(sbi, option)	((sbi)->mount_opt |= EROFS_MOUNT_##option)
#define test_opt(sbi, option)	((sbi)->mount_opt & EROFS_MOUNT_##option)
@@ -237,17 +244,32 @@ int erofs_namei(struct inode *dir, struct qstr *name,
	erofs_nid_t *nid, unsigned *d_type);

/* xattr.c */
#ifdef CONFIG_EROFS_FS_XATTR
extern const struct xattr_handler *erofs_xattr_handlers[];
#endif

/* symlink */
#ifdef CONFIG_EROFS_FS_XATTR
extern const struct inode_operations erofs_symlink_xattr_iops;
extern const struct inode_operations erofs_fast_symlink_xattr_iops;
#endif

static inline void set_inode_fast_symlink(struct inode *inode)
{
#ifdef CONFIG_EROFS_FS_XATTR
	inode->i_op = &erofs_fast_symlink_xattr_iops;
#else
	inode->i_op = &simple_symlink_inode_operations;
#endif
}

static inline bool is_inode_fast_symlink(struct inode *inode)
{
#ifdef CONFIG_EROFS_FS_XATTR
	return inode->i_op == &erofs_fast_symlink_xattr_iops;
#else
	return inode->i_op == &simple_symlink_inode_operations;
#endif
}

static inline void *erofs_vmap(struct page **pages, unsigned int count)
+4 −0
Original line number Diff line number Diff line
@@ -11,6 +11,7 @@
 * distribution for more details.
 */
#include "internal.h"
#include "xattr.h"

/* based on the value of qn->len is accurate */
static inline int dirnamecmp(struct qstr *qn,
@@ -239,5 +240,8 @@ const struct inode_operations erofs_dir_iops = {

const struct inode_operations erofs_dir_xattr_iops = {
	.lookup = erofs_lookup,
#ifdef CONFIG_EROFS_FS_XATTR
	.listxattr = erofs_listxattr,
#endif
};
Loading