diff options
author | Raghavendra Bhat <raghavendrabhat@gluster.com> | 2012-02-24 15:23:08 +0530 |
---|---|---|
committer | Vijay Bellur <vijay@gluster.com> | 2012-03-12 05:22:56 -0700 |
commit | afae9366d220d79fb8b0b1ab96f0e95d25dc4a90 (patch) | |
tree | d27795aa808cc7a331354bc1474070e47ea6e30a /xlators/cluster | |
parent | c9322f64cc4b8c661cf282bf1a2b08e0d6567b16 (diff) |
cluster/afr: save the xattr obtained in the {f}xattrop_cbk in local
If the {f}xattrop operation succeeds on one of the subvolumes and fails
on another (thus the xattr dict obtained from the failed subvolume in
the callback will be NULL), then afr would be unwinding with op_ret = 0
(since the operation was successful on one subvolume), but the xattr dict
would be NULL (afr is not saving the xattr it has received in the callback
in its local structure and will send the xattr it has received in the last
callback). xlators above afr might segfault when they access the xattr since
they would have assumed that xattr would be present as op_ret is 0.
Change-Id: I50761a302150285f31dfdaa397f890c9370a989a
BUG: 797119
Signed-off-by: Raghavendra Bhat <raghavendrabhat@gluster.com>
Reviewed-on: http://review.gluster.com/2813
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Amar Tumballi <amarts@redhat.com>
Reviewed-by: Vijay Bellur <vijay@gluster.com>
Diffstat (limited to 'xlators/cluster')
-rw-r--r-- | xlators/cluster/afr/src/afr-common.c | 24 | ||||
-rw-r--r-- | xlators/cluster/afr/src/afr.h | 8 |
2 files changed, 27 insertions, 5 deletions
diff --git a/xlators/cluster/afr/src/afr-common.c b/xlators/cluster/afr/src/afr-common.c index 3118601707c..4eafed34232 100644 --- a/xlators/cluster/afr/src/afr-common.c +++ b/xlators/cluster/afr/src/afr-common.c @@ -931,7 +931,14 @@ afr_local_cleanup (afr_local_t *local, xlator_t *this) { /* removexattr */ GF_FREE (local->cont.removexattr.name); } - + { /* xattrop */ + if (local->cont.xattrop.xattr) + dict_unref (local->cont.xattrop.xattr); + } + { /* fxattrop */ + if (local->cont.fxattrop.xattr) + dict_unref (local->cont.fxattrop.xattr); + } { /* symlink */ GF_FREE (local->cont.symlink.linkpath); } @@ -2636,8 +2643,11 @@ afr_xattrop_cbk (call_frame_t *frame, void *cookie, LOCK (&frame->lock); { - if (op_ret == 0) + if (op_ret == 0) { + if (!local->cont.xattrop.xattr) + local->cont.xattrop.xattr = dict_ref (xattr); local->op_ret = 0; + } local->op_errno = op_errno; } @@ -2647,7 +2657,7 @@ afr_xattrop_cbk (call_frame_t *frame, void *cookie, if (call_count == 0) AFR_STACK_UNWIND (xattrop, frame, local->op_ret, local->op_errno, - xattr); + local->cont.xattrop.xattr); return 0; } @@ -2714,8 +2724,12 @@ afr_fxattrop_cbk (call_frame_t *frame, void *cookie, LOCK (&frame->lock); { - if (op_ret == 0) + if (op_ret == 0) { + if (!local->cont.fxattrop.xattr) + local->cont.fxattrop.xattr = dict_ref (xattr); + local->op_ret = 0; + } local->op_errno = op_errno; } @@ -2725,7 +2739,7 @@ afr_fxattrop_cbk (call_frame_t *frame, void *cookie, if (call_count == 0) AFR_STACK_UNWIND (fxattrop, frame, local->op_ret, local->op_errno, - xattr); + local->cont.fxattrop.xattr); return 0; } diff --git a/xlators/cluster/afr/src/afr.h b/xlators/cluster/afr/src/afr.h index a1c1bb39846..23b0a4e279a 100644 --- a/xlators/cluster/afr/src/afr.h +++ b/xlators/cluster/afr/src/afr.h @@ -570,6 +570,14 @@ typedef struct _afr_local { char *name; } removexattr; + struct { + dict_t *xattr; + } xattrop; + + struct { + dict_t *xattr; + } fxattrop; + /* dir write */ struct { |