diff options
author | Vikas Gorur <vikas@gluster.com> | 2009-10-29 07:32:46 +0000 |
---|---|---|
committer | Anand V. Avati <avati@dev.gluster.com> | 2009-10-29 09:45:41 -0700 |
commit | c770322ca4c9ccf50530d6a05ac4107fa1236f60 (patch) | |
tree | 0a0014ca2d331bb9358bd4e9a2a29fdca7f70646 /xlators | |
parent | 32c963cfea91e196ee1ebf98a5579989c53fdc6c (diff) |
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 <vikas@gluster.com>
Signed-off-by: Anand V. Avati <avati@dev.gluster.com>
BUG: 326 ([2.0.8rc9] Spurious self-heal)
URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=326
Diffstat (limited to 'xlators')
-rw-r--r-- | xlators/storage/posix/src/posix.c | 103 |
1 files changed, 58 insertions, 45 deletions
diff --git a/xlators/storage/posix/src/posix.c b/xlators/storage/posix/src/posix.c index e98a039c453..6e0cf6650fd 100644 --- a/xlators/storage/posix/src/posix.c +++ b/xlators/storage/posix/src/posix.c @@ -3483,7 +3483,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); @@ -3508,64 +3509,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) { |