[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;