summaryrefslogtreecommitdiffstats
path: root/xlators
diff options
context:
space:
mode:
authorVikas Gorur <vikas@gluster.com>2009-10-29 07:32:46 +0000
committerAnand V. Avati <avati@dev.gluster.com>2009-10-29 09:45:41 -0700
commitc770322ca4c9ccf50530d6a05ac4107fa1236f60 (patch)
tree0a0014ca2d331bb9358bd4e9a2a29fdca7f70646 /xlators
parent32c963cfea91e196ee1ebf98a5579989c53fdc6c (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.c103
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) {