diff options
Diffstat (limited to 'fs/gfs2/acl.c')
-rw-r--r-- | fs/gfs2/acl.c | 58 |
1 files changed, 47 insertions, 11 deletions
diff --git a/fs/gfs2/acl.c b/fs/gfs2/acl.c index 791932617d1a..363ba9e9d8d0 100644 --- a/fs/gfs2/acl.c +++ b/fs/gfs2/acl.c @@ -24,6 +24,7 @@ #include "glock.h" #include "inode.h" #include "meta_io.h" +#include "rgrp.h" #include "trans.h" #include "util.h" @@ -38,7 +39,7 @@ static const char *gfs2_acl_name(int type) return NULL; } -struct posix_acl *gfs2_get_acl(struct inode *inode, int type) +static struct posix_acl *__gfs2_get_acl(struct inode *inode, int type) { struct gfs2_inode *ip = GFS2_I(inode); struct posix_acl *acl; @@ -50,29 +51,41 @@ struct posix_acl *gfs2_get_acl(struct inode *inode, int type) return NULL; name = gfs2_acl_name(type); - if (name == NULL) - return ERR_PTR(-EINVAL); - len = gfs2_xattr_acl_get(ip, name, &data); - if (len < 0) + if (len <= 0) return ERR_PTR(len); - if (len == 0) - return NULL; - acl = posix_acl_from_xattr(&init_user_ns, data, len); kfree(data); return acl; } -int gfs2_set_acl(struct inode *inode, struct posix_acl *acl, int type) +struct posix_acl *gfs2_get_acl(struct inode *inode, int type) +{ + struct gfs2_inode *ip = GFS2_I(inode); + struct gfs2_holder gh; + bool need_unlock = false; + struct posix_acl *acl; + + if (!gfs2_glock_is_locked_by_me(ip->i_gl)) { + int ret = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, + LM_FLAG_ANY, &gh); + if (ret) + return ERR_PTR(ret); + need_unlock = true; + } + acl = __gfs2_get_acl(inode, type); + if (need_unlock) + gfs2_glock_dq_uninit(&gh); + return acl; +} + +int __gfs2_set_acl(struct inode *inode, struct posix_acl *acl, int type) { int error; int len; char *data; const char *name = gfs2_acl_name(type); - BUG_ON(name == NULL); - if (acl && acl->a_count > GFS2_ACL_MAX_ENTRIES(GFS2_SB(inode))) return -E2BIG; @@ -115,3 +128,26 @@ out: kfree(data); return error; } + +int gfs2_set_acl(struct inode *inode, struct posix_acl *acl, int type) +{ + struct gfs2_inode *ip = GFS2_I(inode); + struct gfs2_holder gh; + bool need_unlock = false; + int ret; + + ret = gfs2_rsqa_alloc(ip); + if (ret) + return ret; + + if (!gfs2_glock_is_locked_by_me(ip->i_gl)) { + ret = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); + if (ret) + return ret; + need_unlock = true; + } + ret = __gfs2_set_acl(inode, acl, type); + if (need_unlock) + gfs2_glock_dq_uninit(&gh); + return ret; +} |