[utterly untested] make gfs2_[gs]et_acl() take the lock if not held by caller ... killing special POSIX xattr handlers for gfs2, along with a bunch of pointless exports. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
diff --git a/fs/gfs2/acl.c b/fs/gfs2/acl.c index 7919326..343c489 100644 --- a/fs/gfs2/acl.c +++ b/fs/gfs2/acl.c
@@ -41,30 +41,35 @@ struct posix_acl *gfs2_get_acl(struct inode *inode, int type) { struct gfs2_inode *ip = GFS2_I(inode); - struct posix_acl *acl; - const char *name; - char *data; - int len; + struct gfs2_holder gh; + bool locked = gfs2_glock_is_locked_by_me(ip->i_gl); + struct posix_acl *acl = NULL; + int ret; - if (!ip->i_eattr) - return NULL; + if (!locked) { + ret = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, + &gh); + if (unlikely(ret)) + return ERR_PTR(ret); + } + if (ip->i_eattr) { + const char *name = gfs2_acl_name(type); + char *data; - name = gfs2_acl_name(type); - if (name == NULL) - return ERR_PTR(-EINVAL); - - len = gfs2_xattr_acl_get(ip, name, &data); - if (len < 0) - return ERR_PTR(len); - if (len == 0) - return NULL; - - acl = posix_acl_from_xattr(&init_user_ns, data, len); - kfree(data); + ret = gfs2_xattr_acl_get(ip, name, &data); + if (ret <= 0) { + acl = ERR_PTR(ret); + } else { + acl = posix_acl_from_xattr(&init_user_ns, data, ret); + kfree(data); + } + } + if (!locked) + gfs2_glock_dq_uninit(&gh); return acl; } -int gfs2_set_acl(struct inode *inode, struct posix_acl *acl, int type) +int __gfs2_set_acl(struct inode *inode, struct posix_acl *acl, int type) { int error; int len; @@ -115,3 +120,15 @@ 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; + int ret = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); + if (ret == 0) { + ret = __gfs2_set_acl(inode, acl, type); + gfs2_glock_dq_uninit(&gh); + } + return ret; +}
diff --git a/fs/gfs2/acl.h b/fs/gfs2/acl.h index 3af4f40..f674fdd 100644 --- a/fs/gfs2/acl.h +++ b/fs/gfs2/acl.h
@@ -15,6 +15,7 @@ #define GFS2_ACL_MAX_ENTRIES(sdp) ((300 << (sdp)->sd_sb.sb_bsize_shift) >> 12) extern struct posix_acl *gfs2_get_acl(struct inode *inode, int type); +extern int __gfs2_set_acl(struct inode *inode, struct posix_acl *acl, int type); extern int gfs2_set_acl(struct inode *inode, struct posix_acl *acl, int type); #endif /* __ACL_DOT_H__ */
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index 3398342..72e9c64 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c
@@ -692,12 +692,12 @@ considered free. Any failures need to undo the gfs2 structures. */ if (default_acl) { - error = gfs2_set_acl(inode, default_acl, ACL_TYPE_DEFAULT); + error = __gfs2_set_acl(inode, default_acl, ACL_TYPE_DEFAULT); posix_acl_release(default_acl); } if (acl) { if (!error) - error = gfs2_set_acl(inode, acl, ACL_TYPE_ACCESS); + error = __gfs2_set_acl(inode, acl, ACL_TYPE_ACCESS); posix_acl_release(acl); }
diff --git a/fs/gfs2/xattr.c b/fs/gfs2/xattr.c index 92d5b4c..216ab4cc 100644 --- a/fs/gfs2/xattr.c +++ b/fs/gfs2/xattr.c
@@ -1472,63 +1472,6 @@ return error; } -static int gfs2_posix_acl_xattr_get(const struct xattr_handler *handler, - struct dentry *dentry, struct inode *inode, - const char *name, void *buffer, size_t size) -{ - struct gfs2_inode *ip = GFS2_I(inode); - struct gfs2_holder gh; - int ret; - - /* For selinux during lookup */ - if (gfs2_glock_is_locked_by_me(ip->i_gl)) - return posix_acl_xattr_get(handler, dentry, inode, name, buffer, size); - - gfs2_holder_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &gh); - ret = gfs2_glock_nq(&gh); - if (ret == 0) { - ret = posix_acl_xattr_get(handler, dentry, inode, name, buffer, size); - gfs2_glock_dq(&gh); - } - gfs2_holder_uninit(&gh); - return ret; -} - -static int gfs2_posix_acl_xattr_set(const struct xattr_handler *handler, - struct dentry *dentry, const char *name, - const void *value, size_t size, int flags) -{ - struct inode *inode = d_inode(dentry); - struct gfs2_inode *ip = GFS2_I(inode); - struct gfs2_holder gh; - int ret; - - gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); - ret = gfs2_glock_nq(&gh); - if (ret == 0) { - ret = posix_acl_xattr_set(handler, dentry, name, value, size, flags); - gfs2_glock_dq(&gh); - } - gfs2_holder_uninit(&gh); - return ret; -} - -static const struct xattr_handler gfs2_posix_acl_access_xattr_handler = { - .name = XATTR_NAME_POSIX_ACL_ACCESS, - .flags = ACL_TYPE_ACCESS, - .list = posix_acl_xattr_list, - .get = gfs2_posix_acl_xattr_get, - .set = gfs2_posix_acl_xattr_set, -}; - -static const struct xattr_handler gfs2_posix_acl_default_xattr_handler = { - .name = XATTR_NAME_POSIX_ACL_DEFAULT, - .flags = ACL_TYPE_DEFAULT, - .list = posix_acl_xattr_list, - .get = gfs2_posix_acl_xattr_get, - .set = gfs2_posix_acl_xattr_set, -}; - static const struct xattr_handler gfs2_xattr_user_handler = { .prefix = XATTR_USER_PREFIX, .flags = GFS2_EATYPE_USR, @@ -1546,8 +1489,8 @@ const struct xattr_handler *gfs2_xattr_handlers[] = { &gfs2_xattr_user_handler, &gfs2_xattr_security_handler, - &gfs2_posix_acl_access_xattr_handler, - &gfs2_posix_acl_default_xattr_handler, + &posix_acl_access_xattr_handler, + &posix_acl_default_xattr_handler, NULL, };
diff --git a/fs/posix_acl.c b/fs/posix_acl.c index 1da2c63..2c60f17 100644 --- a/fs/posix_acl.c +++ b/fs/posix_acl.c
@@ -795,7 +795,7 @@ } EXPORT_SYMBOL (posix_acl_to_xattr); -int +static int posix_acl_xattr_get(const struct xattr_handler *handler, struct dentry *unused, struct inode *inode, const char *name, void *value, size_t size) @@ -819,9 +819,8 @@ return error; } -EXPORT_SYMBOL(posix_acl_xattr_get); -int +static int posix_acl_xattr_set(const struct xattr_handler *handler, struct dentry *dentry, const char *name, const void *value, size_t size, int flags) @@ -857,14 +856,12 @@ posix_acl_release(acl); return ret; } -EXPORT_SYMBOL(posix_acl_xattr_set); -bool +static bool posix_acl_xattr_list(struct dentry *dentry) { return IS_POSIXACL(d_backing_inode(dentry)); } -EXPORT_SYMBOL(posix_acl_xattr_list); const struct xattr_handler posix_acl_access_xattr_handler = { .name = XATTR_NAME_POSIX_ACL_ACCESS,
diff --git a/include/linux/posix_acl_xattr.h b/include/linux/posix_acl_xattr.h index c92607c..e5e8ec4 100644 --- a/include/linux/posix_acl_xattr.h +++ b/include/linux/posix_acl_xattr.h
@@ -65,14 +65,6 @@ int posix_acl_to_xattr(struct user_namespace *user_ns, const struct posix_acl *acl, void *buffer, size_t size); -int posix_acl_xattr_get(const struct xattr_handler *handler, - struct dentry *unused, struct inode *inode, - const char *name, void *value, size_t size); -int posix_acl_xattr_set(const struct xattr_handler *handler, - struct dentry *dentry, const char *name, - const void *value, size_t size, int flags); -bool posix_acl_xattr_list(struct dentry *dentry); - extern const struct xattr_handler posix_acl_access_xattr_handler; extern const struct xattr_handler posix_acl_default_xattr_handler;