forked from Minki/linux
fs: make posix_acl_chmod more useful
Rename the current posix_acl_chmod to __posix_acl_chmod and add a fully featured ACL chmod helper that uses the ->set_acl inode operation. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Jan Kara <jack@suse.cz> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
parent
2aeccbe957
commit
5bf3258fd2
@ -156,7 +156,7 @@ int v9fs_acl_chmod(struct inode *inode, struct p9_fid *fid)
|
|||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
acl = v9fs_get_cached_acl(inode, ACL_TYPE_ACCESS);
|
acl = v9fs_get_cached_acl(inode, ACL_TYPE_ACCESS);
|
||||||
if (acl) {
|
if (acl) {
|
||||||
retval = posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode);
|
retval = __posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode);
|
||||||
if (retval)
|
if (retval)
|
||||||
return retval;
|
return retval;
|
||||||
set_cached_acl(inode, ACL_TYPE_ACCESS, acl);
|
set_cached_acl(inode, ACL_TYPE_ACCESS, acl);
|
||||||
|
@ -256,7 +256,7 @@ int btrfs_acl_chmod(struct inode *inode)
|
|||||||
if (IS_ERR_OR_NULL(acl))
|
if (IS_ERR_OR_NULL(acl))
|
||||||
return PTR_ERR(acl);
|
return PTR_ERR(acl);
|
||||||
|
|
||||||
ret = posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode);
|
ret = __posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
ret = btrfs_set_acl(NULL, inode, acl, ACL_TYPE_ACCESS);
|
ret = btrfs_set_acl(NULL, inode, acl, ACL_TYPE_ACCESS);
|
||||||
|
@ -308,7 +308,7 @@ ext2_acl_chmod(struct inode *inode)
|
|||||||
acl = ext2_get_acl(inode, ACL_TYPE_ACCESS);
|
acl = ext2_get_acl(inode, ACL_TYPE_ACCESS);
|
||||||
if (IS_ERR(acl) || !acl)
|
if (IS_ERR(acl) || !acl)
|
||||||
return PTR_ERR(acl);
|
return PTR_ERR(acl);
|
||||||
error = posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode);
|
error = __posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode);
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
return error;
|
||||||
error = ext2_set_acl(inode, ACL_TYPE_ACCESS, acl);
|
error = ext2_set_acl(inode, ACL_TYPE_ACCESS, acl);
|
||||||
|
@ -314,7 +314,7 @@ ext3_acl_chmod(struct inode *inode)
|
|||||||
acl = ext3_get_acl(inode, ACL_TYPE_ACCESS);
|
acl = ext3_get_acl(inode, ACL_TYPE_ACCESS);
|
||||||
if (IS_ERR(acl) || !acl)
|
if (IS_ERR(acl) || !acl)
|
||||||
return PTR_ERR(acl);
|
return PTR_ERR(acl);
|
||||||
error = posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode);
|
error = __posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode);
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
return error;
|
||||||
retry:
|
retry:
|
||||||
|
@ -320,7 +320,7 @@ ext4_acl_chmod(struct inode *inode)
|
|||||||
acl = ext4_get_acl(inode, ACL_TYPE_ACCESS);
|
acl = ext4_get_acl(inode, ACL_TYPE_ACCESS);
|
||||||
if (IS_ERR(acl) || !acl)
|
if (IS_ERR(acl) || !acl)
|
||||||
return PTR_ERR(acl);
|
return PTR_ERR(acl);
|
||||||
error = posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode);
|
error = __posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode);
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
return error;
|
||||||
retry:
|
retry:
|
||||||
|
@ -311,7 +311,7 @@ int f2fs_acl_chmod(struct inode *inode)
|
|||||||
if (IS_ERR(acl) || !acl)
|
if (IS_ERR(acl) || !acl)
|
||||||
return PTR_ERR(acl);
|
return PTR_ERR(acl);
|
||||||
|
|
||||||
error = posix_acl_chmod(&acl, GFP_KERNEL, mode);
|
error = __posix_acl_chmod(&acl, GFP_KERNEL, mode);
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
|
@ -158,7 +158,7 @@ generic_acl_chmod(struct inode *inode)
|
|||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
acl = get_cached_acl(inode, ACL_TYPE_ACCESS);
|
acl = get_cached_acl(inode, ACL_TYPE_ACCESS);
|
||||||
if (acl) {
|
if (acl) {
|
||||||
error = posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode);
|
error = __posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode);
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
return error;
|
||||||
set_cached_acl(inode, ACL_TYPE_ACCESS, acl);
|
set_cached_acl(inode, ACL_TYPE_ACCESS, acl);
|
||||||
|
@ -162,7 +162,7 @@ int gfs2_acl_chmod(struct gfs2_inode *ip, struct iattr *attr)
|
|||||||
if (!acl)
|
if (!acl)
|
||||||
return gfs2_setattr_simple(inode, attr);
|
return gfs2_setattr_simple(inode, attr);
|
||||||
|
|
||||||
error = posix_acl_chmod(&acl, GFP_NOFS, attr->ia_mode);
|
error = __posix_acl_chmod(&acl, GFP_NOFS, attr->ia_mode);
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
|
@ -167,7 +167,7 @@ int hfsplus_posix_acl_chmod(struct inode *inode)
|
|||||||
if (IS_ERR(acl) || !acl)
|
if (IS_ERR(acl) || !acl)
|
||||||
return PTR_ERR(acl);
|
return PTR_ERR(acl);
|
||||||
|
|
||||||
err = posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode);
|
err = __posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode);
|
||||||
if (unlikely(err))
|
if (unlikely(err))
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
@ -335,7 +335,7 @@ int jffs2_acl_chmod(struct inode *inode)
|
|||||||
acl = jffs2_get_acl(inode, ACL_TYPE_ACCESS);
|
acl = jffs2_get_acl(inode, ACL_TYPE_ACCESS);
|
||||||
if (IS_ERR(acl) || !acl)
|
if (IS_ERR(acl) || !acl)
|
||||||
return PTR_ERR(acl);
|
return PTR_ERR(acl);
|
||||||
rc = posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode);
|
rc = __posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode);
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
rc = jffs2_set_acl(inode, ACL_TYPE_ACCESS, acl);
|
rc = jffs2_set_acl(inode, ACL_TYPE_ACCESS, acl);
|
||||||
|
@ -161,7 +161,7 @@ int jfs_acl_chmod(struct inode *inode)
|
|||||||
if (IS_ERR(acl) || !acl)
|
if (IS_ERR(acl) || !acl)
|
||||||
return PTR_ERR(acl);
|
return PTR_ERR(acl);
|
||||||
|
|
||||||
rc = posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode);
|
rc = __posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode);
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
|
@ -350,7 +350,7 @@ int ocfs2_acl_chmod(struct inode *inode)
|
|||||||
acl = ocfs2_get_acl(inode, ACL_TYPE_ACCESS);
|
acl = ocfs2_get_acl(inode, ACL_TYPE_ACCESS);
|
||||||
if (IS_ERR(acl) || !acl)
|
if (IS_ERR(acl) || !acl)
|
||||||
return PTR_ERR(acl);
|
return PTR_ERR(acl);
|
||||||
ret = posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode);
|
ret = __posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
ret = ocfs2_set_acl(NULL, inode, NULL, ACL_TYPE_ACCESS,
|
ret = ocfs2_set_acl(NULL, inode, NULL, ACL_TYPE_ACCESS,
|
||||||
|
@ -364,7 +364,7 @@ static int posix_acl_create_masq(struct posix_acl *acl, umode_t *mode_p)
|
|||||||
/*
|
/*
|
||||||
* Modify the ACL for the chmod syscall.
|
* Modify the ACL for the chmod syscall.
|
||||||
*/
|
*/
|
||||||
static int posix_acl_chmod_masq(struct posix_acl *acl, umode_t mode)
|
static int __posix_acl_chmod_masq(struct posix_acl *acl, umode_t mode)
|
||||||
{
|
{
|
||||||
struct posix_acl_entry *group_obj = NULL, *mask_obj = NULL;
|
struct posix_acl_entry *group_obj = NULL, *mask_obj = NULL;
|
||||||
struct posix_acl_entry *pa, *pe;
|
struct posix_acl_entry *pa, *pe;
|
||||||
@ -428,12 +428,12 @@ posix_acl_create(struct posix_acl **acl, gfp_t gfp, umode_t *mode_p)
|
|||||||
EXPORT_SYMBOL(posix_acl_create);
|
EXPORT_SYMBOL(posix_acl_create);
|
||||||
|
|
||||||
int
|
int
|
||||||
posix_acl_chmod(struct posix_acl **acl, gfp_t gfp, umode_t mode)
|
__posix_acl_chmod(struct posix_acl **acl, gfp_t gfp, umode_t mode)
|
||||||
{
|
{
|
||||||
struct posix_acl *clone = posix_acl_clone(*acl, gfp);
|
struct posix_acl *clone = posix_acl_clone(*acl, gfp);
|
||||||
int err = -ENOMEM;
|
int err = -ENOMEM;
|
||||||
if (clone) {
|
if (clone) {
|
||||||
err = posix_acl_chmod_masq(clone, mode);
|
err = __posix_acl_chmod_masq(clone, mode);
|
||||||
if (err) {
|
if (err) {
|
||||||
posix_acl_release(clone);
|
posix_acl_release(clone);
|
||||||
clone = NULL;
|
clone = NULL;
|
||||||
@ -443,6 +443,30 @@ posix_acl_chmod(struct posix_acl **acl, gfp_t gfp, umode_t mode)
|
|||||||
*acl = clone;
|
*acl = clone;
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL(__posix_acl_chmod);
|
||||||
|
|
||||||
|
int
|
||||||
|
posix_acl_chmod(struct inode *inode)
|
||||||
|
{
|
||||||
|
struct posix_acl *acl;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
if (!IS_POSIXACL(inode))
|
||||||
|
return 0;
|
||||||
|
if (!inode->i_op->set_acl)
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
|
acl = get_acl(inode, ACL_TYPE_ACCESS);
|
||||||
|
if (IS_ERR_OR_NULL(acl))
|
||||||
|
return PTR_ERR(acl);
|
||||||
|
|
||||||
|
ret = __posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
ret = inode->i_op->set_acl(inode, acl, ACL_TYPE_ACCESS);
|
||||||
|
posix_acl_release(acl);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
EXPORT_SYMBOL(posix_acl_chmod);
|
EXPORT_SYMBOL(posix_acl_chmod);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -463,7 +463,7 @@ int reiserfs_acl_chmod(struct inode *inode)
|
|||||||
return 0;
|
return 0;
|
||||||
if (IS_ERR(acl))
|
if (IS_ERR(acl))
|
||||||
return PTR_ERR(acl);
|
return PTR_ERR(acl);
|
||||||
error = posix_acl_chmod(&acl, GFP_NOFS, inode->i_mode);
|
error = __posix_acl_chmod(&acl, GFP_NOFS, inode->i_mode);
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
|
@ -334,7 +334,7 @@ xfs_acl_chmod(struct inode *inode)
|
|||||||
if (IS_ERR(acl) || !acl)
|
if (IS_ERR(acl) || !acl)
|
||||||
return PTR_ERR(acl);
|
return PTR_ERR(acl);
|
||||||
|
|
||||||
error = posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode);
|
error = __posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode);
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
|
@ -89,12 +89,14 @@ extern int posix_acl_permission(struct inode *, const struct posix_acl *, int);
|
|||||||
extern struct posix_acl *posix_acl_from_mode(umode_t, gfp_t);
|
extern struct posix_acl *posix_acl_from_mode(umode_t, gfp_t);
|
||||||
extern int posix_acl_equiv_mode(const struct posix_acl *, umode_t *);
|
extern int posix_acl_equiv_mode(const struct posix_acl *, umode_t *);
|
||||||
extern int posix_acl_create(struct posix_acl **, gfp_t, umode_t *);
|
extern int posix_acl_create(struct posix_acl **, gfp_t, umode_t *);
|
||||||
extern int posix_acl_chmod(struct posix_acl **, gfp_t, umode_t);
|
extern int __posix_acl_chmod(struct posix_acl **, gfp_t, umode_t);
|
||||||
|
|
||||||
extern struct posix_acl *get_posix_acl(struct inode *, int);
|
extern struct posix_acl *get_posix_acl(struct inode *, int);
|
||||||
extern int set_posix_acl(struct inode *, int, struct posix_acl *);
|
extern int set_posix_acl(struct inode *, int, struct posix_acl *);
|
||||||
|
|
||||||
#ifdef CONFIG_FS_POSIX_ACL
|
#ifdef CONFIG_FS_POSIX_ACL
|
||||||
|
extern int posix_acl_chmod(struct inode *);
|
||||||
|
|
||||||
static inline struct posix_acl **acl_by_type(struct inode *inode, int type)
|
static inline struct posix_acl **acl_by_type(struct inode *inode, int type)
|
||||||
{
|
{
|
||||||
switch (type) {
|
switch (type) {
|
||||||
@ -165,15 +167,22 @@ static inline void forget_all_cached_acls(struct inode *inode)
|
|||||||
if (old_default != ACL_NOT_CACHED)
|
if (old_default != ACL_NOT_CACHED)
|
||||||
posix_acl_release(old_default);
|
posix_acl_release(old_default);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
static inline void cache_no_acl(struct inode *inode)
|
static inline void cache_no_acl(struct inode *inode)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_FS_POSIX_ACL
|
|
||||||
inode->i_acl = NULL;
|
inode->i_acl = NULL;
|
||||||
inode->i_default_acl = NULL;
|
inode->i_default_acl = NULL;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
static inline int posix_acl_chmod(struct inode *inode)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void cache_no_acl(struct inode *inode)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_FS_POSIX_ACL */
|
||||||
|
|
||||||
struct posix_acl *get_acl(struct inode *inode, int type);
|
struct posix_acl *get_acl(struct inode *inode, int type);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user