From b9e3c902bf6eed825ebd6323a5905d64a3153269 Mon Sep 17 00:00:00 2001 From: Vikas Gorur Date: Thu, 29 Oct 2009 07:44:24 +0000 Subject: storage/posix: Serialize do_xattrop. Hold a lock on the inode for the getxattr/add-array/setxattr section since multiple threads can enter into it causing wrong values to be written and triggering spurious replicate self-heal later. Signed-off-by: Vikas Gorur Signed-off-by: Anand V. Avati BUG: 326 ([2.0.8rc9] Spurious self-heal) URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=326 --- xlators/storage/posix/src/posix.c | 103 +++++++++++++++++++++----------------- 1 file changed, 58 insertions(+), 45 deletions(-) (limited to 'xlators/storage/posix/src/posix.c') diff --git a/xlators/storage/posix/src/posix.c b/xlators/storage/posix/src/posix.c index 5ffda9f67..f2451a414 100644 --- a/xlators/storage/posix/src/posix.c +++ b/xlators/storage/posix/src/posix.c @@ -3092,7 +3092,8 @@ do_xattrop (call_frame_t *frame, xlator_t *this, data_pair_t *trav = NULL; - char *path = NULL; + char * path = NULL; + inode_t * inode = NULL; VALIDATE_OR_GOTO (frame, out); VALIDATE_OR_GOTO (xattr, out); @@ -3117,64 +3118,76 @@ do_xattrop (call_frame_t *frame, xlator_t *this, MAKE_REAL_PATH (real_path, this, loc->path); if (loc) { - path = strdup (loc->path); + path = strdup (loc->path); + inode = loc->inode; } else { inode_path (fd->inode, NULL, &path); + inode = fd->inode; } while (trav) { count = trav->value->len / sizeof (int32_t); array = CALLOC (count, sizeof (int32_t)); - if (loc) { - size = sys_lgetxattr (real_path, trav->key, (char *)array, - trav->value->len); - } else { - size = sys_fgetxattr (_fd, trav->key, (char *)array, - trav->value->len); - } + LOCK (&inode->lock); + { + if (loc) { + size = sys_lgetxattr (real_path, trav->key, (char *)array, + trav->value->len); + } else { + size = sys_fgetxattr (_fd, trav->key, (char *)array, + trav->value->len); + } - op_errno = errno; - if ((size == -1) && (op_errno != ENODATA) && - (op_errno != ENOATTR)) { - if (op_errno == ENOTSUP) { - GF_LOG_OCCASIONALLY(gf_posix_xattr_enotsup_log, - this->name,GF_LOG_WARNING, - "Extended attributes not " - "supported by filesystem"); - } else { - gf_log (this->name, GF_LOG_ERROR, - "getxattr failed on %s while doing " - "xattrop: %s", path, - strerror (op_errno)); - } - goto out; - } + op_errno = errno; + if ((size == -1) && (op_errno != ENODATA) && + (op_errno != ENOATTR)) { + if (op_errno == ENOTSUP) { + GF_LOG_OCCASIONALLY(gf_posix_xattr_enotsup_log, + this->name,GF_LOG_WARNING, + "Extended attributes not " + "supported by filesystem"); + } else { + gf_log (this->name, GF_LOG_ERROR, + "getxattr failed on %s while doing " + "xattrop: %s", path, + strerror (op_errno)); + } - switch (optype) { + op_ret = -1; + goto unlock; + } - case GF_XATTROP_ADD_ARRAY: - __add_array (array, (int32_t *) trav->value->data, - trav->value->len / 4); - break; + switch (optype) { - default: - gf_log (this->name, GF_LOG_ERROR, - "Unknown xattrop type (%d) on %s. Please send " - "a bug report to gluster-devel@nongnu.org", - optype, path); - op_ret = -1; - op_errno = EINVAL; - goto out; - } + case GF_XATTROP_ADD_ARRAY: + __add_array (array, (int32_t *) trav->value->data, + trav->value->len / 4); + break; - if (loc) { - size = sys_lsetxattr (real_path, trav->key, array, - trav->value->len, 0); - } else { - size = sys_fsetxattr (_fd, trav->key, (char *)array, - trav->value->len, 0); + default: + gf_log (this->name, GF_LOG_ERROR, + "Unknown xattrop type (%d) on %s. Please send " + "a bug report to gluster-devel@nongnu.org", + optype, path); + op_ret = -1; + op_errno = EINVAL; + goto unlock; + } + + if (loc) { + size = sys_lsetxattr (real_path, trav->key, array, + trav->value->len, 0); + } else { + size = sys_fsetxattr (_fd, trav->key, (char *)array, + trav->value->len, 0); + } } + unlock: + UNLOCK (&inode->lock); + + if (op_ret == -1) + goto out; op_errno = errno; if (size == -1) { -- cgit