summaryrefslogtreecommitdiffstats
path: root/xlators/cluster
diff options
context:
space:
mode:
authorBrian Foster <bfoster@redhat.com>2012-07-25 08:14:38 -0400
committerAnand Avati <avati@redhat.com>2012-07-25 15:03:57 -0700
commit34d395fc16449ec3fe709d77609677992752b61a (patch)
treec769688517edf133a66aba75d19c16a48a84ae42 /xlators/cluster
parent75ee490213b7f7673970ef80dee3bcc567848c26 (diff)
cluster: fix crash on link of named pipe in stripe/replicate vol
A crash occurs when attempting to link a named pipe on a striped, replicated volume. The cause for this crash is attempting to deref a NULL inode pointer in stripe_link_cbk(). The RCA for this bug uncovered a couple of problems: - AFR ignores the inode pointer it receives on failure (returning NULL). - stripe assumes the inode pointer is valid on failure. Either one of these changes addresses the crash, but this patch includes both changes. AFR is modified to pass along the inode pointer it receives (which could still be NULL). stripe is modified to not assume the inode pointer is valid on fop failure. BUG: 842825 Change-Id: I9cb2cc918552620929c3ecbd69bc66d4635eafdc Signed-off-by: Brian Foster <bfoster@redhat.com> Reviewed-on: http://review.gluster.com/3727 Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Jeff Darcy <jdarcy@redhat.com> Reviewed-by: Anand Avati <avati@redhat.com>
Diffstat (limited to 'xlators/cluster')
-rw-r--r--xlators/cluster/afr/src/afr-dir-write.c3
-rw-r--r--xlators/cluster/stripe/src/stripe.c20
2 files changed, 11 insertions, 12 deletions
diff --git a/xlators/cluster/afr/src/afr-dir-write.c b/xlators/cluster/afr/src/afr-dir-write.c
index 759fa0581..4d86fa480 100644
--- a/xlators/cluster/afr/src/afr-dir-write.c
+++ b/xlators/cluster/afr/src/afr-dir-write.c
@@ -875,13 +875,12 @@ afr_link_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
local->cont.link.postparent = *postparent;
}
- local->cont.link.inode = inode;
-
fresh_children = local->fresh_children;
fresh_children[local->success_count] = child_index;
local->success_count++;
}
+ local->cont.link.inode = inode;
local->op_errno = op_errno;
}
UNLOCK (&frame->lock);
diff --git a/xlators/cluster/stripe/src/stripe.c b/xlators/cluster/stripe/src/stripe.c
index d17b2a912..e2176eeae 100644
--- a/xlators/cluster/stripe/src/stripe.c
+++ b/xlators/cluster/stripe/src/stripe.c
@@ -1951,16 +1951,6 @@ stripe_link_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
{
callcnt = --local->call_count;
- if (IA_ISREG(inode->ia_type)) {
- inode_ctx_get(inode, this, (uint64_t *) &fctx);
- if (!fctx) {
- gf_log(this->name, GF_LOG_ERROR,
- "failed to get stripe context");
- op_ret = -1;
- op_errno = EINVAL;
- }
- }
-
if (op_ret == -1) {
gf_log (this->name, GF_LOG_DEBUG,
"%s returned error %s",
@@ -1974,6 +1964,16 @@ stripe_link_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
if (op_ret >= 0) {
local->op_ret = 0;
+ if (IA_ISREG(inode->ia_type)) {
+ inode_ctx_get(inode, this, (uint64_t *) &fctx);
+ if (!fctx) {
+ gf_log(this->name, GF_LOG_ERROR,
+ "failed to get stripe context");
+ op_ret = -1;
+ op_errno = EINVAL;
+ }
+ }
+
if (FIRST_CHILD(this) == prev->this) {
local->inode = inode_ref (inode);
local->stbuf = *buf;