diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2016-05-12 21:59:17 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2016-05-12 22:28:05 -0400 |
commit | 1a39ba99b5d533647c5dac45cd6a3e0baa7cb66a (patch) | |
tree | 24f0508c7d380168e333f9ee8921d8b8550f9ef6 /fs/gfs2/xattr.c | |
parent | b971e94e8f4c09ff775cfb2c4f846b4431a00598 (diff) |
gfs2: Switch to generic xattr handlers
Switch to the generic xattr handlers and take the necessary glocks at
the layer below. The following are the new xattr "entry points"; they
are called with the glock held already in the following cases:
gfs2_xattr_get: From SELinux, during lookups.
gfs2_xattr_set: The glock is never held.
gfs2_get_acl: From gfs2_create_inode -> posix_acl_create and
gfs2_setattr -> posix_acl_chmod.
gfs2_set_acl: From gfs2_setattr -> posix_acl_chmod.
Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/gfs2/xattr.c')
-rw-r--r-- | fs/gfs2/xattr.c | 46 |
1 files changed, 40 insertions, 6 deletions
diff --git a/fs/gfs2/xattr.c b/fs/gfs2/xattr.c index 619886ba6e78..f42ab53bd30d 100644 --- a/fs/gfs2/xattr.c +++ b/fs/gfs2/xattr.c | |||
@@ -583,13 +583,11 @@ out: | |||
583 | * | 583 | * |
584 | * Returns: actual size of data on success, -errno on error | 584 | * Returns: actual size of data on success, -errno on error |
585 | */ | 585 | */ |
586 | static int gfs2_xattr_get(const struct xattr_handler *handler, | 586 | static int __gfs2_xattr_get(struct inode *inode, const char *name, |
587 | struct dentry *unused, struct inode *inode, | 587 | void *buffer, size_t size, int type) |
588 | const char *name, void *buffer, size_t size) | ||
589 | { | 588 | { |
590 | struct gfs2_inode *ip = GFS2_I(inode); | 589 | struct gfs2_inode *ip = GFS2_I(inode); |
591 | struct gfs2_ea_location el; | 590 | struct gfs2_ea_location el; |
592 | int type = handler->flags; | ||
593 | int error; | 591 | int error; |
594 | 592 | ||
595 | if (!ip->i_eattr) | 593 | if (!ip->i_eattr) |
@@ -611,6 +609,29 @@ static int gfs2_xattr_get(const struct xattr_handler *handler, | |||
611 | return error; | 609 | return error; |
612 | } | 610 | } |
613 | 611 | ||
612 | static int gfs2_xattr_get(const struct xattr_handler *handler, | ||
613 | struct dentry *unused, struct inode *inode, | ||
614 | const char *name, void *buffer, size_t size) | ||
615 | { | ||
616 | struct gfs2_inode *ip = GFS2_I(inode); | ||
617 | struct gfs2_holder gh; | ||
618 | bool need_unlock = false; | ||
619 | int ret; | ||
620 | |||
621 | /* During lookup, SELinux calls this function with the glock locked. */ | ||
622 | |||
623 | if (!gfs2_glock_is_locked_by_me(ip->i_gl)) { | ||
624 | ret = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &gh); | ||
625 | if (ret) | ||
626 | return ret; | ||
627 | need_unlock = true; | ||
628 | } | ||
629 | ret = __gfs2_xattr_get(inode, name, buffer, size, handler->flags); | ||
630 | if (need_unlock) | ||
631 | gfs2_glock_dq_uninit(&gh); | ||
632 | return ret; | ||
633 | } | ||
634 | |||
614 | /** | 635 | /** |
615 | * ea_alloc_blk - allocates a new block for extended attributes. | 636 | * ea_alloc_blk - allocates a new block for extended attributes. |
616 | * @ip: A pointer to the inode that's getting extended attributes | 637 | * @ip: A pointer to the inode that's getting extended attributes |
@@ -1233,8 +1254,21 @@ static int gfs2_xattr_set(const struct xattr_handler *handler, | |||
1233 | struct dentry *dentry, const char *name, | 1254 | struct dentry *dentry, const char *name, |
1234 | const void *value, size_t size, int flags) | 1255 | const void *value, size_t size, int flags) |
1235 | { | 1256 | { |
1236 | return __gfs2_xattr_set(d_inode(dentry), name, value, | 1257 | struct inode *inode = d_inode(dentry); |
1237 | size, flags, handler->flags); | 1258 | struct gfs2_inode *ip = GFS2_I(inode); |
1259 | struct gfs2_holder gh; | ||
1260 | int ret; | ||
1261 | |||
1262 | ret = gfs2_rsqa_alloc(ip); | ||
1263 | if (ret) | ||
1264 | return ret; | ||
1265 | |||
1266 | ret = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); | ||
1267 | if (ret) | ||
1268 | return ret; | ||
1269 | ret = __gfs2_xattr_set(inode, name, value, size, flags, handler->flags); | ||
1270 | gfs2_glock_dq_uninit(&gh); | ||
1271 | return ret; | ||
1238 | } | 1272 | } |
1239 | 1273 | ||
1240 | static int ea_dealloc_indirect(struct gfs2_inode *ip) | 1274 | static int ea_dealloc_indirect(struct gfs2_inode *ip) |