summaryrefslogtreecommitdiffstats
path: root/xlators/cluster/afr/src
diff options
context:
space:
mode:
authorRaghavendra Bhat <raghavendrabhat@gluster.com>2012-02-24 15:23:08 +0530
committerVijay Bellur <vijay@gluster.com>2012-03-12 05:22:56 -0700
commitafae9366d220d79fb8b0b1ab96f0e95d25dc4a90 (patch)
treed27795aa808cc7a331354bc1474070e47ea6e30a /xlators/cluster/afr/src
parentc9322f64cc4b8c661cf282bf1a2b08e0d6567b16 (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/afr/src')
-rw-r--r--xlators/cluster/afr/src/afr-common.c24
-rw-r--r--xlators/cluster/afr/src/afr.h8
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 {