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

Commit a6dda0e6 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Al Viro
Browse files

f2fs: use generic posix ACL infrastructure



f2fs has some weird mode bit handling, so still using the old
chmod code for now.

Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarJaegeuk Kim <jaegeuk.kim@samsung.com>
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 64e178a7
Loading
Loading
Loading
Loading
+17 −157
Original line number Diff line number Diff line
@@ -17,9 +17,6 @@
#include "xattr.h"
#include "acl.h"

#define get_inode_mode(i)	((is_inode_flag_set(F2FS_I(i), FI_ACL_MODE)) ? \
					(F2FS_I(i)->i_acl_mode) : ((i)->i_mode))

static inline size_t f2fs_acl_size(int count)
{
	if (count <= 4) {
@@ -167,19 +164,11 @@ fail:

struct posix_acl *f2fs_get_acl(struct inode *inode, int type)
{
	struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
	int name_index = F2FS_XATTR_INDEX_POSIX_ACL_DEFAULT;
	void *value = NULL;
	struct posix_acl *acl;
	int retval;

	if (!test_opt(sbi, POSIX_ACL))
		return NULL;

	acl = get_cached_acl(inode, type);
	if (acl != ACL_NOT_CACHED)
		return acl;

	if (type == ACL_TYPE_ACCESS)
		name_index = F2FS_XATTR_INDEX_POSIX_ACL_ACCESS;

@@ -205,21 +194,15 @@ struct posix_acl *f2fs_get_acl(struct inode *inode, int type)
	return acl;
}

static int f2fs_set_acl(struct inode *inode, int type,
static int __f2fs_set_acl(struct inode *inode, int type,
			struct posix_acl *acl, struct page *ipage)
{
	struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
	struct f2fs_inode_info *fi = F2FS_I(inode);
	int name_index;
	void *value = NULL;
	size_t size = 0;
	int error;

	if (!test_opt(sbi, POSIX_ACL))
		return 0;
	if (S_ISLNK(inode->i_mode))
		return -EOPNOTSUPP;

	switch (type) {
	case ACL_TYPE_ACCESS:
		name_index = F2FS_XATTR_INDEX_POSIX_ACL_ACCESS;
@@ -261,154 +244,31 @@ static int f2fs_set_acl(struct inode *inode, int type,
	return error;
}

int f2fs_init_acl(struct inode *inode, struct inode *dir, struct page *ipage)
int f2fs_set_acl(struct inode *inode, struct posix_acl *acl, int type)
{
	struct f2fs_sb_info *sbi = F2FS_SB(dir->i_sb);
	struct posix_acl *acl = NULL;
	int error = 0;

	if (!S_ISLNK(inode->i_mode)) {
		if (test_opt(sbi, POSIX_ACL)) {
			acl = f2fs_get_acl(dir, ACL_TYPE_DEFAULT);
			if (IS_ERR(acl))
				return PTR_ERR(acl);
		}
		if (!acl)
			inode->i_mode &= ~current_umask();
	}

	if (!test_opt(sbi, POSIX_ACL) || !acl)
		goto cleanup;

	if (S_ISDIR(inode->i_mode)) {
		error = f2fs_set_acl(inode, ACL_TYPE_DEFAULT, acl, ipage);
		if (error)
			goto cleanup;
	}
	error = __posix_acl_create(&acl, GFP_KERNEL, &inode->i_mode);
	if (error < 0)
		return error;
	if (error > 0)
		error = f2fs_set_acl(inode, ACL_TYPE_ACCESS, acl, ipage);
cleanup:
	posix_acl_release(acl);
	return error;
	return __f2fs_set_acl(inode, type, acl, NULL);
}

int f2fs_acl_chmod(struct inode *inode)
int f2fs_init_acl(struct inode *inode, struct inode *dir, struct page *ipage)
{
	struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
	struct posix_acl *acl;
	int error;
	umode_t mode = get_inode_mode(inode);

	if (!test_opt(sbi, POSIX_ACL))
		return 0;
	if (S_ISLNK(mode))
		return -EOPNOTSUPP;

	acl = f2fs_get_acl(inode, ACL_TYPE_ACCESS);
	if (IS_ERR(acl) || !acl)
		return PTR_ERR(acl);
	struct posix_acl *default_acl, *acl;
	int error = 0;

	error = __posix_acl_chmod(&acl, GFP_KERNEL, mode);
	error = posix_acl_create(dir, &inode->i_mode, &default_acl, &acl);
	if (error)
		return error;

	error = f2fs_set_acl(inode, ACL_TYPE_ACCESS, acl, NULL);
	posix_acl_release(acl);
	return error;
	if (default_acl) {
		error = __f2fs_set_acl(inode, ACL_TYPE_DEFAULT, default_acl,
				       ipage);
		posix_acl_release(default_acl);
	}

static size_t f2fs_xattr_list_acl(struct dentry *dentry, char *list,
		size_t list_size, const char *name, size_t name_len, int type)
{
	struct f2fs_sb_info *sbi = F2FS_SB(dentry->d_sb);
	const char *xname = POSIX_ACL_XATTR_DEFAULT;
	size_t size;

	if (!test_opt(sbi, POSIX_ACL))
		return 0;

	if (type == ACL_TYPE_ACCESS)
		xname = POSIX_ACL_XATTR_ACCESS;

	size = strlen(xname) + 1;
	if (list && size <= list_size)
		memcpy(list, xname, size);
	return size;
}

static int f2fs_xattr_get_acl(struct dentry *dentry, const char *name,
		void *buffer, size_t size, int type)
{
	struct f2fs_sb_info *sbi = F2FS_SB(dentry->d_sb);
	struct posix_acl *acl;
	int error;

	if (strcmp(name, "") != 0)
		return -EINVAL;
	if (!test_opt(sbi, POSIX_ACL))
		return -EOPNOTSUPP;

	acl = f2fs_get_acl(dentry->d_inode, type);
	if (IS_ERR(acl))
		return PTR_ERR(acl);
	if (!acl)
		return -ENODATA;
	error = posix_acl_to_xattr(&init_user_ns, acl, buffer, size);
	posix_acl_release(acl);

	return error;
}

static int f2fs_xattr_set_acl(struct dentry *dentry, const char *name,
		const void *value, size_t size, int flags, int type)
{
	struct f2fs_sb_info *sbi = F2FS_SB(dentry->d_sb);
	struct inode *inode = dentry->d_inode;
	struct posix_acl *acl = NULL;
	int error;

	if (strcmp(name, "") != 0)
		return -EINVAL;
	if (!test_opt(sbi, POSIX_ACL))
		return -EOPNOTSUPP;
	if (!inode_owner_or_capable(inode))
		return -EPERM;

	if (value) {
		acl = posix_acl_from_xattr(&init_user_ns, value, size);
		if (IS_ERR(acl))
			return PTR_ERR(acl);
	if (acl) {
			error = posix_acl_valid(acl);
		if (error)
				goto release_and_out;
		}
	} else {
		acl = NULL;
			error = __f2fs_set_acl(inode, ACL_TYPE_ACCESS, acl,
					       ipage);
		posix_acl_release(acl);
	}

	error = f2fs_set_acl(inode, type, acl, NULL);

release_and_out:
	posix_acl_release(acl);
	return error;
}

const struct xattr_handler f2fs_xattr_acl_default_handler = {
	.prefix = POSIX_ACL_XATTR_DEFAULT,
	.flags = ACL_TYPE_DEFAULT,
	.list = f2fs_xattr_list_acl,
	.get = f2fs_xattr_get_acl,
	.set = f2fs_xattr_set_acl,
};

const struct xattr_handler f2fs_xattr_acl_access_handler = {
	.prefix = POSIX_ACL_XATTR_ACCESS,
	.flags = ACL_TYPE_ACCESS,
	.list = f2fs_xattr_list_acl,
	.get = f2fs_xattr_get_acl,
	.set = f2fs_xattr_set_acl,
};
+1 −6
Original line number Diff line number Diff line
@@ -37,18 +37,13 @@ struct f2fs_acl_header {
#ifdef CONFIG_F2FS_FS_POSIX_ACL

extern struct posix_acl *f2fs_get_acl(struct inode *, int);
extern int f2fs_acl_chmod(struct inode *);
extern int f2fs_set_acl(struct inode *inode, struct posix_acl *acl, int type);
extern int f2fs_init_acl(struct inode *, struct inode *, struct page *);
#else
#define f2fs_check_acl	NULL
#define f2fs_get_acl	NULL
#define f2fs_set_acl	NULL

static inline int f2fs_acl_chmod(struct inode *inode)
{
	return 0;
}

static inline int f2fs_init_acl(struct inode *inode, struct inode *dir,
							struct page *page)
{
+4 −0
Original line number Diff line number Diff line
@@ -953,6 +953,10 @@ static inline int f2fs_readonly(struct super_block *sb)
	return sb->s_flags & MS_RDONLY;
}

#define get_inode_mode(i) \
	((is_inode_flag_set(F2FS_I(i), FI_ACL_MODE)) ? \
	 (F2FS_I(i)->i_acl_mode) : ((i)->i_mode))

/*
 * file.c
 */
+2 −1
Original line number Diff line number Diff line
@@ -390,7 +390,7 @@ int f2fs_setattr(struct dentry *dentry, struct iattr *attr)
	__setattr_copy(inode, attr);

	if (attr->ia_valid & ATTR_MODE) {
		err = f2fs_acl_chmod(inode);
		err = posix_acl_chmod(inode, get_inode_mode(inode));
		if (err || is_inode_flag_set(fi, FI_ACL_MODE)) {
			inode->i_mode = fi->i_acl_mode;
			clear_inode_flag(fi, FI_ACL_MODE);
@@ -405,6 +405,7 @@ const struct inode_operations f2fs_file_inode_operations = {
	.getattr	= f2fs_getattr,
	.setattr	= f2fs_setattr,
	.get_acl	= f2fs_get_acl,
	.set_acl	= f2fs_set_acl,
#ifdef CONFIG_F2FS_FS_XATTR
	.setxattr	= generic_setxattr,
	.getxattr	= generic_getxattr,
+2 −0
Original line number Diff line number Diff line
@@ -496,6 +496,7 @@ const struct inode_operations f2fs_dir_inode_operations = {
	.getattr	= f2fs_getattr,
	.setattr	= f2fs_setattr,
	.get_acl	= f2fs_get_acl,
	.set_acl	= f2fs_set_acl,
#ifdef CONFIG_F2FS_FS_XATTR
	.setxattr	= generic_setxattr,
	.getxattr	= generic_getxattr,
@@ -522,6 +523,7 @@ const struct inode_operations f2fs_special_inode_operations = {
	.getattr	= f2fs_getattr,
	.setattr        = f2fs_setattr,
	.get_acl	= f2fs_get_acl,
	.set_acl	= f2fs_set_acl,
#ifdef CONFIG_F2FS_FS_XATTR
	.setxattr       = generic_setxattr,
	.getxattr       = generic_getxattr,
Loading