summaryrefslogtreecommitdiffstats
path: root/xlators
diff options
context:
space:
mode:
authorBrian Foster <bfoster@redhat.com>2012-07-25 08:14:38 -0400
committerVijay Bellur <vbellur@redhat.com>2012-08-09 08:10:20 -0700
commit475efecfba7194c598a94879852bcd37ac2deb5d (patch)
tree24060ce8bdc483c63c16cc4161f6683421ca06d3 /xlators
parente741983b740a26634b8d371521da2f668ec8e584 (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: I368849b7cfbb137a08ae5f89d26406814ff5bb09 Signed-off-by: Brian Foster <bfoster@redhat.com> Reviewed-on: http://review.gluster.com/3790 Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Vijay Bellur <vbellur@redhat.com>
Diffstat (limited to 'xlators')
-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 b7e9bd8748a..46f5dceebd4 100644
--- a/xlators/cluster/afr/src/afr-dir-write.c
+++ b/xlators/cluster/afr/src/afr-dir-write.c
@@ -862,13 +862,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 d0542d143a7..932e907dcce 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;