Commit 47f70d08 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Al Viro

reiserfs: use generic posix ACL infrastructure

Also don't bother to set up a .get_acl method for symlinks as we do not
support access control (ACLs or even mode bits) for symlinks in Linux.
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarJan Kara <jack@suse.cz>
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 702e5bc6
...@@ -48,18 +48,18 @@ static inline int reiserfs_acl_count(size_t size) ...@@ -48,18 +48,18 @@ static inline int reiserfs_acl_count(size_t size)
#ifdef CONFIG_REISERFS_FS_POSIX_ACL #ifdef CONFIG_REISERFS_FS_POSIX_ACL
struct posix_acl *reiserfs_get_acl(struct inode *inode, int type); struct posix_acl *reiserfs_get_acl(struct inode *inode, int type);
int reiserfs_set_acl(struct inode *inode, struct posix_acl *acl, int type);
int reiserfs_acl_chmod(struct inode *inode); int reiserfs_acl_chmod(struct inode *inode);
int reiserfs_inherit_default_acl(struct reiserfs_transaction_handle *th, int reiserfs_inherit_default_acl(struct reiserfs_transaction_handle *th,
struct inode *dir, struct dentry *dentry, struct inode *dir, struct dentry *dentry,
struct inode *inode); struct inode *inode);
int reiserfs_cache_default_acl(struct inode *dir); int reiserfs_cache_default_acl(struct inode *dir);
extern const struct xattr_handler reiserfs_posix_acl_default_handler;
extern const struct xattr_handler reiserfs_posix_acl_access_handler;
#else #else
#define reiserfs_cache_default_acl(inode) 0 #define reiserfs_cache_default_acl(inode) 0
#define reiserfs_get_acl NULL #define reiserfs_get_acl NULL
#define reiserfs_set_acl NULL
static inline int reiserfs_acl_chmod(struct inode *inode) static inline int reiserfs_acl_chmod(struct inode *inode)
{ {
......
...@@ -260,4 +260,5 @@ const struct inode_operations reiserfs_file_inode_operations = { ...@@ -260,4 +260,5 @@ const struct inode_operations reiserfs_file_inode_operations = {
.removexattr = reiserfs_removexattr, .removexattr = reiserfs_removexattr,
.permission = reiserfs_permission, .permission = reiserfs_permission,
.get_acl = reiserfs_get_acl, .get_acl = reiserfs_get_acl,
.set_acl = reiserfs_set_acl,
}; };
...@@ -1522,6 +1522,7 @@ const struct inode_operations reiserfs_dir_inode_operations = { ...@@ -1522,6 +1522,7 @@ const struct inode_operations reiserfs_dir_inode_operations = {
.removexattr = reiserfs_removexattr, .removexattr = reiserfs_removexattr,
.permission = reiserfs_permission, .permission = reiserfs_permission,
.get_acl = reiserfs_get_acl, .get_acl = reiserfs_get_acl,
.set_acl = reiserfs_set_acl,
}; };
/* /*
...@@ -1538,8 +1539,6 @@ const struct inode_operations reiserfs_symlink_inode_operations = { ...@@ -1538,8 +1539,6 @@ const struct inode_operations reiserfs_symlink_inode_operations = {
.listxattr = reiserfs_listxattr, .listxattr = reiserfs_listxattr,
.removexattr = reiserfs_removexattr, .removexattr = reiserfs_removexattr,
.permission = reiserfs_permission, .permission = reiserfs_permission,
.get_acl = reiserfs_get_acl,
}; };
/* /*
...@@ -1553,4 +1552,5 @@ const struct inode_operations reiserfs_special_inode_operations = { ...@@ -1553,4 +1552,5 @@ const struct inode_operations reiserfs_special_inode_operations = {
.removexattr = reiserfs_removexattr, .removexattr = reiserfs_removexattr,
.permission = reiserfs_permission, .permission = reiserfs_permission,
.get_acl = reiserfs_get_acl, .get_acl = reiserfs_get_acl,
.set_acl = reiserfs_set_acl,
}; };
...@@ -50,6 +50,7 @@ ...@@ -50,6 +50,7 @@
#include <linux/stat.h> #include <linux/stat.h>
#include <linux/quotaops.h> #include <linux/quotaops.h>
#include <linux/security.h> #include <linux/security.h>
#include <linux/posix_acl_xattr.h>
#define PRIVROOT_NAME ".reiserfs_priv" #define PRIVROOT_NAME ".reiserfs_priv"
#define XAROOT_NAME "xattrs" #define XAROOT_NAME "xattrs"
...@@ -904,8 +905,8 @@ static const struct xattr_handler *reiserfs_xattr_handlers[] = { ...@@ -904,8 +905,8 @@ static const struct xattr_handler *reiserfs_xattr_handlers[] = {
&reiserfs_xattr_security_handler, &reiserfs_xattr_security_handler,
#endif #endif
#ifdef CONFIG_REISERFS_FS_POSIX_ACL #ifdef CONFIG_REISERFS_FS_POSIX_ACL
&reiserfs_posix_acl_access_handler, &posix_acl_access_xattr_handler,
&reiserfs_posix_acl_default_handler, &posix_acl_default_xattr_handler,
#endif #endif
NULL NULL
}; };
......
...@@ -11,35 +11,19 @@ ...@@ -11,35 +11,19 @@
#include "acl.h" #include "acl.h"
#include <asm/uaccess.h> #include <asm/uaccess.h>
static int reiserfs_set_acl(struct reiserfs_transaction_handle *th, static int __reiserfs_set_acl(struct reiserfs_transaction_handle *th,
struct inode *inode, int type, struct inode *inode, int type,
struct posix_acl *acl); struct posix_acl *acl);
static int
reiserfs_posix_acl_set(struct dentry *dentry, const char *name, const void *value, int
size_t size, int flags, int type) reiserfs_set_acl(struct inode *inode, struct posix_acl *acl, int type)
{ {
struct inode *inode = dentry->d_inode;
struct posix_acl *acl;
int error, error2; int error, error2;
struct reiserfs_transaction_handle th; struct reiserfs_transaction_handle th;
size_t jcreate_blocks; size_t jcreate_blocks;
if (!reiserfs_posixacl(inode->i_sb)) int size = acl ? posix_acl_xattr_size(acl->a_count) : 0;
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);
} else if (acl) {
error = posix_acl_valid(acl);
if (error)
goto release_and_out;
}
} else
acl = NULL;
/* Pessimism: We can't assume that anything from the xattr root up /* Pessimism: We can't assume that anything from the xattr root up
* has been created. */ * has been created. */
...@@ -51,7 +35,7 @@ reiserfs_posix_acl_set(struct dentry *dentry, const char *name, const void *valu ...@@ -51,7 +35,7 @@ reiserfs_posix_acl_set(struct dentry *dentry, const char *name, const void *valu
error = journal_begin(&th, inode->i_sb, jcreate_blocks); error = journal_begin(&th, inode->i_sb, jcreate_blocks);
reiserfs_write_unlock(inode->i_sb); reiserfs_write_unlock(inode->i_sb);
if (error == 0) { if (error == 0) {
error = reiserfs_set_acl(&th, inode, type, acl); error = __reiserfs_set_acl(&th, inode, type, acl);
reiserfs_write_lock(inode->i_sb); reiserfs_write_lock(inode->i_sb);
error2 = journal_end(&th, inode->i_sb, jcreate_blocks); error2 = journal_end(&th, inode->i_sb, jcreate_blocks);
reiserfs_write_unlock(inode->i_sb); reiserfs_write_unlock(inode->i_sb);
...@@ -59,29 +43,6 @@ reiserfs_posix_acl_set(struct dentry *dentry, const char *name, const void *valu ...@@ -59,29 +43,6 @@ reiserfs_posix_acl_set(struct dentry *dentry, const char *name, const void *valu
error = error2; error = error2;
} }
release_and_out:
posix_acl_release(acl);
return error;
}
static int
reiserfs_posix_acl_get(struct dentry *dentry, const char *name, void *buffer,
size_t size, int type)
{
struct posix_acl *acl;
int error;
if (!reiserfs_posixacl(dentry->d_sb))
return -EOPNOTSUPP;
acl = reiserfs_get_acl(dentry->d_inode, type);
if (IS_ERR(acl))
return PTR_ERR(acl);
if (acl == NULL)
return -ENODATA;
error = posix_acl_to_xattr(&init_user_ns, acl, buffer, size);
posix_acl_release(acl);
return error; return error;
} }
...@@ -221,10 +182,6 @@ struct posix_acl *reiserfs_get_acl(struct inode *inode, int type) ...@@ -221,10 +182,6 @@ struct posix_acl *reiserfs_get_acl(struct inode *inode, int type)
int size; int size;
int retval; int retval;
acl = get_cached_acl(inode, type);
if (acl != ACL_NOT_CACHED)
return acl;
switch (type) { switch (type) {
case ACL_TYPE_ACCESS: case ACL_TYPE_ACCESS:
name = POSIX_ACL_XATTR_ACCESS; name = POSIX_ACL_XATTR_ACCESS;
...@@ -273,7 +230,7 @@ struct posix_acl *reiserfs_get_acl(struct inode *inode, int type) ...@@ -273,7 +230,7 @@ struct posix_acl *reiserfs_get_acl(struct inode *inode, int type)
* BKL held [before 2.5.x] * BKL held [before 2.5.x]
*/ */
static int static int
reiserfs_set_acl(struct reiserfs_transaction_handle *th, struct inode *inode, __reiserfs_set_acl(struct reiserfs_transaction_handle *th, struct inode *inode,
int type, struct posix_acl *acl) int type, struct posix_acl *acl)
{ {
char *name; char *name;
...@@ -281,9 +238,6 @@ reiserfs_set_acl(struct reiserfs_transaction_handle *th, struct inode *inode, ...@@ -281,9 +238,6 @@ reiserfs_set_acl(struct reiserfs_transaction_handle *th, struct inode *inode,
size_t size = 0; size_t size = 0;
int error; int error;
if (S_ISLNK(inode->i_mode))
return -EOPNOTSUPP;
switch (type) { switch (type) {
case ACL_TYPE_ACCESS: case ACL_TYPE_ACCESS:
name = POSIX_ACL_XATTR_ACCESS; name = POSIX_ACL_XATTR_ACCESS;
...@@ -343,7 +297,7 @@ reiserfs_inherit_default_acl(struct reiserfs_transaction_handle *th, ...@@ -343,7 +297,7 @@ reiserfs_inherit_default_acl(struct reiserfs_transaction_handle *th,
struct inode *dir, struct dentry *dentry, struct inode *dir, struct dentry *dentry,
struct inode *inode) struct inode *inode)
{ {
struct posix_acl *acl; struct posix_acl *default_acl, *acl;
int err = 0; int err = 0;
/* ACLs only get applied to files and directories */ /* ACLs only get applied to files and directories */
...@@ -363,37 +317,28 @@ reiserfs_inherit_default_acl(struct reiserfs_transaction_handle *th, ...@@ -363,37 +317,28 @@ reiserfs_inherit_default_acl(struct reiserfs_transaction_handle *th,
goto apply_umask; goto apply_umask;
} }
acl = reiserfs_get_acl(dir, ACL_TYPE_DEFAULT); err = posix_acl_create(dir, &inode->i_mode, &default_acl, &acl);
if (IS_ERR(acl)) if (err)
return PTR_ERR(acl); return err;
if (default_acl) {
err = __reiserfs_set_acl(th, inode, ACL_TYPE_DEFAULT,
default_acl);
posix_acl_release(default_acl);
}
if (acl) { if (acl) {
/* Copy the default ACL to the default ACL of a new directory */ if (!err)
if (S_ISDIR(inode->i_mode)) { err = __reiserfs_set_acl(th, inode, ACL_TYPE_ACCESS,
err = reiserfs_set_acl(th, inode, ACL_TYPE_DEFAULT, acl);
acl);
if (err)
goto cleanup;
}
/* Now we reconcile the new ACL and the mode,
potentially modifying both */
err = __posix_acl_create(&acl, GFP_NOFS, &inode->i_mode);
if (err < 0)
return err;
/* If we need an ACL.. */
if (err > 0)
err = reiserfs_set_acl(th, inode, ACL_TYPE_ACCESS, acl);
cleanup:
posix_acl_release(acl); posix_acl_release(acl);
} else {
apply_umask:
/* no ACL, apply umask */
inode->i_mode &= ~current_umask();
} }
return err; return err;
apply_umask:
/* no ACL, apply umask */
inode->i_mode &= ~current_umask();
return err;
} }
/* This is used to cache the default acl before a new object is created. /* This is used to cache the default acl before a new object is created.
...@@ -442,84 +387,11 @@ int reiserfs_cache_default_acl(struct inode *inode) ...@@ -442,84 +387,11 @@ int reiserfs_cache_default_acl(struct inode *inode)
*/ */
int reiserfs_acl_chmod(struct inode *inode) int reiserfs_acl_chmod(struct inode *inode)
{ {
struct reiserfs_transaction_handle th;
struct posix_acl *acl;
size_t size;
int error;
if (IS_PRIVATE(inode)) if (IS_PRIVATE(inode))
return 0; return 0;
if (S_ISLNK(inode->i_mode))
return -EOPNOTSUPP;
if (get_inode_sd_version(inode) == STAT_DATA_V1 || if (get_inode_sd_version(inode) == STAT_DATA_V1 ||
!reiserfs_posixacl(inode->i_sb)) { !reiserfs_posixacl(inode->i_sb))
return 0; return 0;
}
acl = reiserfs_get_acl(inode, ACL_TYPE_ACCESS); return posix_acl_chmod(inode, inode->i_mode);
if (!acl)
return 0;
if (IS_ERR(acl))
return PTR_ERR(acl);
error = __posix_acl_chmod(&acl, GFP_NOFS, inode->i_mode);
if (error)
return error;
size = reiserfs_xattr_nblocks(inode, reiserfs_acl_size(acl->a_count));
reiserfs_write_lock(inode->i_sb);
error = journal_begin(&th, inode->i_sb, size * 2);
reiserfs_write_unlock(inode->i_sb);
if (!error) {
int error2;
error = reiserfs_set_acl(&th, inode, ACL_TYPE_ACCESS, acl);
reiserfs_write_lock(inode->i_sb);
error2 = journal_end(&th, inode->i_sb, size * 2);
reiserfs_write_unlock(inode->i_sb);
if (error2)
error = error2;
}
posix_acl_release(acl);
return error;
}
static size_t posix_acl_access_list(struct dentry *dentry, char *list,
size_t list_size, const char *name,
size_t name_len, int type)
{
const size_t size = sizeof(POSIX_ACL_XATTR_ACCESS);
if (!reiserfs_posixacl(dentry->d_sb))
return 0;
if (list && size <= list_size)
memcpy(list, POSIX_ACL_XATTR_ACCESS, size);
return size;
} }
const struct xattr_handler reiserfs_posix_acl_access_handler = {
.prefix = POSIX_ACL_XATTR_ACCESS,
.flags = ACL_TYPE_ACCESS,
.get = reiserfs_posix_acl_get,
.set = reiserfs_posix_acl_set,
.list = posix_acl_access_list,
};
static size_t posix_acl_default_list(struct dentry *dentry, char *list,
size_t list_size, const char *name,
size_t name_len, int type)
{
const size_t size = sizeof(POSIX_ACL_XATTR_DEFAULT);
if (!reiserfs_posixacl(dentry->d_sb))
return 0;
if (list && size <= list_size)
memcpy(list, POSIX_ACL_XATTR_DEFAULT, size);
return size;
}
const struct xattr_handler reiserfs_posix_acl_default_handler = {
.prefix = POSIX_ACL_XATTR_DEFAULT,
.flags = ACL_TYPE_DEFAULT,
.get = reiserfs_posix_acl_get,
.set = reiserfs_posix_acl_set,
.list = posix_acl_default_list,
};
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment