Skip to content

Commit

Permalink
f2fs: use generic posix ACL infrastructure
Browse files Browse the repository at this point in the history
f2fs has some weird mode bit handling, so still using the old
chmod code for now.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
  • Loading branch information
Christoph Hellwig authored and Al Viro committed Jan 26, 2014
1 parent 64e178a commit a6dda0e
Show file tree
Hide file tree
Showing 7 changed files with 31 additions and 170 deletions.
174 changes: 17 additions & 157 deletions fs/f2fs/acl.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -167,19 +164,11 @@ static void *f2fs_acl_to_disk(const struct posix_acl *acl, size_t *size)

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;

Expand All @@ -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;
Expand Down Expand Up @@ -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;
}

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;
if (default_acl) {
error = __f2fs_set_acl(inode, ACL_TYPE_DEFAULT, default_acl,
ipage);
posix_acl_release(default_acl);
}
if (acl) {
if (error)
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,
};
7 changes: 1 addition & 6 deletions fs/f2fs/acl.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down
4 changes: 4 additions & 0 deletions fs/f2fs/f2fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand Down
3 changes: 2 additions & 1 deletion fs/f2fs/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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,
Expand Down
2 changes: 2 additions & 0 deletions fs/f2fs/namei.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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,
Expand Down
9 changes: 5 additions & 4 deletions fs/f2fs/xattr.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <linux/rwsem.h>
#include <linux/f2fs_fs.h>
#include <linux/security.h>
#include <linux/posix_acl_xattr.h>
#include "f2fs.h"
#include "xattr.h"

Expand Down Expand Up @@ -216,8 +217,8 @@ const struct xattr_handler f2fs_xattr_security_handler = {
static const struct xattr_handler *f2fs_xattr_handler_map[] = {
[F2FS_XATTR_INDEX_USER] = &f2fs_xattr_user_handler,
#ifdef CONFIG_F2FS_FS_POSIX_ACL
[F2FS_XATTR_INDEX_POSIX_ACL_ACCESS] = &f2fs_xattr_acl_access_handler,
[F2FS_XATTR_INDEX_POSIX_ACL_DEFAULT] = &f2fs_xattr_acl_default_handler,
[F2FS_XATTR_INDEX_POSIX_ACL_ACCESS] = &posix_acl_access_xattr_handler,
[F2FS_XATTR_INDEX_POSIX_ACL_DEFAULT] = &posix_acl_default_xattr_handler,
#endif
[F2FS_XATTR_INDEX_TRUSTED] = &f2fs_xattr_trusted_handler,
#ifdef CONFIG_F2FS_FS_SECURITY
Expand All @@ -229,8 +230,8 @@ static const struct xattr_handler *f2fs_xattr_handler_map[] = {
const struct xattr_handler *f2fs_xattr_handlers[] = {
&f2fs_xattr_user_handler,
#ifdef CONFIG_F2FS_FS_POSIX_ACL
&f2fs_xattr_acl_access_handler,
&f2fs_xattr_acl_default_handler,
&posix_acl_access_xattr_handler,
&posix_acl_default_xattr_handler,
#endif
&f2fs_xattr_trusted_handler,
#ifdef CONFIG_F2FS_FS_SECURITY
Expand Down
2 changes: 0 additions & 2 deletions fs/f2fs/xattr.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,6 @@ struct f2fs_xattr_entry {
#ifdef CONFIG_F2FS_FS_XATTR
extern const struct xattr_handler f2fs_xattr_user_handler;
extern const struct xattr_handler f2fs_xattr_trusted_handler;
extern const struct xattr_handler f2fs_xattr_acl_access_handler;
extern const struct xattr_handler f2fs_xattr_acl_default_handler;
extern const struct xattr_handler f2fs_xattr_advise_handler;
extern const struct xattr_handler f2fs_xattr_security_handler;

Expand Down

0 comments on commit a6dda0e

Please sign in to comment.