diff options
| author | Vikas Gorur <vikas@gluster.com> | 2009-10-29 07:44:24 +0000 | 
|---|---|---|
| committer | Anand V. Avati <avati@dev.gluster.com> | 2009-10-29 12:02:50 -0700 | 
| commit | b9e3c902bf6eed825ebd6323a5905d64a3153269 (patch) | |
| tree | 6cc4a9d23574736441dd4dff8170113cf6cb2c61 | |
| parent | f1f80d5f037800fd8c653c6985fe0874c1d7bca6 (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
| -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 5ffda9f678d..f2451a41498 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) {  | 
