summaryrefslogtreecommitdiffstats
path: root/xlators/storage
diff options
context:
space:
mode:
authorshishir gowda <sgowda@redhat.com>2013-06-20 14:06:04 +0530
committerVijay Bellur <vbellur@redhat.com>2013-07-30 23:56:41 -0700
commitacf8cfdf698aa3ebe42ed55bba8be4f85b751c29 (patch)
tree74766b510c2f4881e53429dcdd4289c1ebf4de5d /xlators/storage
parente306698b00d2d3e736cbc97a1383bfb5d3724796 (diff)
Revert "storage/posix: Remove the interim fix that handles the gfid race"
This reverts commit 97807e75956a2d240282bc64fab1b71762de0546. In a distribute or distribute-replica volume, this fix is required to prevent gfid mis-match due to race issues. test script bug-767585-gfid.t needs a sleep of 2, cause after setting backend gfid directly, we try to heal, and with this fix, we do not allow setxattr of gfid within creation of 1 second if not created by itself Change-Id: Ie3f4b385416889fd5de444638a64a7eaaf24cd60 BUG: 951195 Signed-off-by: shishir gowda <sgowda@redhat.com> Reviewed-on: http://review.gluster.org/5240 Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Amar Tumballi <amarts@redhat.com>
Diffstat (limited to 'xlators/storage')
-rw-r--r--xlators/storage/posix/src/posix-helpers.c68
-rw-r--r--xlators/storage/posix/src/posix.c2
-rw-r--r--xlators/storage/posix/src/posix.h2
3 files changed, 70 insertions, 2 deletions
diff --git a/xlators/storage/posix/src/posix-helpers.c b/xlators/storage/posix/src/posix-helpers.c
index 616664a3d..2fa55eda0 100644
--- a/xlators/storage/posix/src/posix-helpers.c
+++ b/xlators/storage/posix/src/posix-helpers.c
@@ -901,6 +901,74 @@ unlock:
UNLOCK (&priv->lock);
}
+static int
+is_fresh_file (struct stat *stat)
+{
+ struct timeval tv;
+
+ gettimeofday (&tv, NULL);
+
+ if ((stat->st_ctime >= (tv.tv_sec - 1))
+ && (stat->st_ctime <= tv.tv_sec))
+ return 1;
+
+ return 0;
+}
+
+
+int
+posix_gfid_heal (xlator_t *this, const char *path, loc_t *loc, dict_t *xattr_req)
+{
+ /* The purpose of this function is to prevent a race
+ where an inode creation FOP (like mkdir/mknod/create etc)
+ races with lookup in the following way:
+
+ {create thread} | {lookup thread}
+ |
+ t0
+ mkdir ("name") |
+ t1
+ | posix_gfid_set ("name", 2);
+ t2
+ posix_gfid_set ("name", 1); |
+ t3
+ lstat ("name"); | lstat ("name");
+
+ In the above case mkdir FOP would have resulted with GFID 2 while
+ it should have been GFID 1. It matters in the case where GFID would
+ have gotten set to 1 on other subvolumes of replciate/distribute
+
+ The "solution" here is that, if we detect lookup is attempting to
+ set a GFID on a file which is created very recently, but does not
+ yet have a GFID (i.e, between t1 and t2), then "fake" it as though
+ posix_gfid_heal was called at t0 instead.
+ */
+
+ uuid_t uuid_curr;
+ int ret = 0;
+ struct stat stat = {0, };
+
+ if (!xattr_req)
+ goto out;
+
+ if (sys_lstat (path, &stat) != 0)
+ goto out;
+
+ ret = sys_lgetxattr (path, GFID_XATTR_KEY, uuid_curr, 16);
+ if (ret != 16) {
+ if (is_fresh_file (&stat)) {
+ ret = -1;
+ errno = ENOENT;
+ goto out;
+ }
+ }
+
+ ret = posix_gfid_set (this, path, loc, xattr_req);
+out:
+ return ret;
+}
+
+
int
posix_acl_xattr_set (xlator_t *this, const char *path, dict_t *xattr_req)
{
diff --git a/xlators/storage/posix/src/posix.c b/xlators/storage/posix/src/posix.c
index e917766b5..0a7030213 100644
--- a/xlators/storage/posix/src/posix.c
+++ b/xlators/storage/posix/src/posix.c
@@ -129,7 +129,7 @@ posix_lookup (call_frame_t *frame, xlator_t *this,
MAKE_ENTRY_HANDLE (real_path, par_path, this, loc, &buf);
if (uuid_is_null (loc->inode->gfid)) {
- posix_gfid_set (this, real_path, loc, xdata);
+ posix_gfid_heal (this, real_path, loc, xdata);
MAKE_ENTRY_HANDLE (real_path, par_path, this,
loc, &buf);
}
diff --git a/xlators/storage/posix/src/posix.h b/xlators/storage/posix/src/posix.h
index c834b29d9..a957e1876 100644
--- a/xlators/storage/posix/src/posix.h
+++ b/xlators/storage/posix/src/posix.h
@@ -188,7 +188,7 @@ int posix_get_file_contents (xlator_t *this, uuid_t pargfid,
int posix_set_file_contents (xlator_t *this, const char *path, char *key,
data_t *value, int flags);
int posix_acl_xattr_set (xlator_t *this, const char *path, dict_t *xattr_req);
-int posix_gfid_heal (xlator_t *this, const char *path, dict_t *xattr_req);
+int posix_gfid_heal (xlator_t *this, const char *path, loc_t *loc, dict_t *xattr_req);
int posix_entry_create_xattr_set (xlator_t *this, const char *path,
dict_t *dict);