b7dd6f45c1
Resolves: bz#1479446 bz#1520882 bz#1579758 bz#1598407 bz#1599808 Resolves: bz#1603118 bz#1619357 bz#1622001 bz#1622308 bz#1631166 Resolves: bz#1631418 bz#1632563 bz#1634649 bz#1635071 bz#1635100 Resolves: bz#1635136 bz#1636291 bz#1638069 bz#1640347 bz#1642854 Resolves: bz#1643035 bz#1644120 bz#1644279 bz#1645916 bz#1647675 Signed-off-by: Milind Changire <mchangir@redhat.com>
366 lines
13 KiB
Diff
366 lines
13 KiB
Diff
From e76a777f3820e62948256a45a38d5e97f3eb08a9 Mon Sep 17 00:00:00 2001
|
|
From: N Balachandran <nbalacha@redhat.com>
|
|
Date: Tue, 28 Aug 2018 12:00:33 +0530
|
|
Subject: [PATCH 438/444] cluster/dht: In rename, unlink after creating linkto
|
|
file
|
|
|
|
The linkto file creation for the dst was done in parallel with
|
|
the unlink of the old src linkto. If these operations reached
|
|
the brick out of order, we end up with a dst linkto file without
|
|
a .glusterfs handle.
|
|
|
|
Fixed by unlinking only after the linkto file creation has
|
|
completed.
|
|
|
|
upstream patch: https://review.gluster.org/#/c/glusterfs/+/21023/
|
|
|
|
> Change-Id: I4246f7655f5bc180f5ded7fd34d263b7828a8110
|
|
> fixes: bz#1621981
|
|
> Signed-off-by: N Balachandran <nbalacha@redhat.com>
|
|
|
|
Change-Id: Ia845a68bb314997cadab57887a84dff9373400c4
|
|
BUG: 1622001
|
|
Signed-off-by: N Balachandran <nbalacha@redhat.com>
|
|
Reviewed-on: https://code.engineering.redhat.com/gerrit/154933
|
|
Tested-by: RHGS Build Bot <nigelb@redhat.com>
|
|
Reviewed-by: Raghavendra Gowdappa <rgowdapp@redhat.com>
|
|
---
|
|
tests/bugs/posix/bug-1619720.t | 1 +
|
|
xlators/cluster/dht/src/dht-rename.c | 254 ++++++++++++++++++-----------------
|
|
2 files changed, 133 insertions(+), 122 deletions(-)
|
|
|
|
diff --git a/tests/bugs/posix/bug-1619720.t b/tests/bugs/posix/bug-1619720.t
|
|
index 5e0d0f7..bfd304d 100755
|
|
--- a/tests/bugs/posix/bug-1619720.t
|
|
+++ b/tests/bugs/posix/bug-1619720.t
|
|
@@ -48,6 +48,7 @@ TEST mv $M0/tmp/file-2 $M0/tmp/file-3
|
|
|
|
TEST mv -f $M0/tmp/file-1 $M0/tmp/file-3
|
|
|
|
+
|
|
TEST getfattr -n $pgfid_xattr_name $B0/${V0}0/tmp/file-3
|
|
TEST getfattr -n $pgfid_xattr_name $B0/${V0}1/tmp/file-3
|
|
|
|
diff --git a/xlators/cluster/dht/src/dht-rename.c b/xlators/cluster/dht/src/dht-rename.c
|
|
index 1d0c2bb..378cb0a 100644
|
|
--- a/xlators/cluster/dht/src/dht-rename.c
|
|
+++ b/xlators/cluster/dht/src/dht-rename.c
|
|
@@ -849,8 +849,8 @@ dht_rename_cleanup (call_frame_t *frame)
|
|
if (src_cached == dst_cached)
|
|
goto nolinks;
|
|
|
|
- if (local->linked && (dst_hashed != src_hashed )&&
|
|
- (dst_hashed != src_cached)) {
|
|
+ if (local->linked && (dst_hashed != src_hashed) &&
|
|
+ (dst_hashed != src_cached)) {
|
|
call_cnt++;
|
|
}
|
|
|
|
@@ -935,6 +935,120 @@ nolinks:
|
|
|
|
|
|
int
|
|
+dht_rename_unlink (call_frame_t *frame, xlator_t *this)
|
|
+{
|
|
+ dht_local_t *local = NULL;
|
|
+ xlator_t *src_hashed = NULL;
|
|
+ xlator_t *src_cached = NULL;
|
|
+ xlator_t *dst_hashed = NULL;
|
|
+ xlator_t *dst_cached = NULL;
|
|
+ xlator_t *rename_subvol = NULL;
|
|
+ dict_t *xattr = NULL;
|
|
+
|
|
+ local = frame->local;
|
|
+
|
|
+ src_hashed = local->src_hashed;
|
|
+ src_cached = local->src_cached;
|
|
+ dst_hashed = local->dst_hashed;
|
|
+ dst_cached = local->dst_cached;
|
|
+
|
|
+ local->call_cnt = 0;
|
|
+
|
|
+ /* NOTE: rename_subvol is the same subvolume from which dht_rename_cbk
|
|
+ * is called. since rename has already happened on rename_subvol,
|
|
+ * unlink shouldn't be sent for oldpath (either linkfile or cached-file)
|
|
+ * on rename_subvol. */
|
|
+ if (src_cached == dst_cached)
|
|
+ rename_subvol = src_cached;
|
|
+ else
|
|
+ rename_subvol = dst_hashed;
|
|
+
|
|
+ /* TODO: delete files in background */
|
|
+
|
|
+ if (src_cached != dst_hashed && src_cached != dst_cached)
|
|
+ local->call_cnt++;
|
|
+
|
|
+ if (src_hashed != rename_subvol && src_hashed != src_cached)
|
|
+ local->call_cnt++;
|
|
+
|
|
+ if (dst_cached && dst_cached != dst_hashed && dst_cached != src_cached)
|
|
+ local->call_cnt++;
|
|
+
|
|
+ if (local->call_cnt == 0)
|
|
+ goto unwind;
|
|
+
|
|
+ DHT_MARK_FOP_INTERNAL (xattr);
|
|
+
|
|
+ if (src_cached != dst_hashed && src_cached != dst_cached) {
|
|
+ dict_t *xattr_new = NULL;
|
|
+
|
|
+ xattr_new = dict_copy_with_ref (xattr, NULL);
|
|
+
|
|
+ gf_msg_trace (this->name, 0,
|
|
+ "deleting old src datafile %s @ %s",
|
|
+ local->loc.path, src_cached->name);
|
|
+
|
|
+ if (gf_uuid_compare (local->loc.pargfid,
|
|
+ local->loc2.pargfid) == 0) {
|
|
+ DHT_MARKER_DONT_ACCOUNT(xattr_new);
|
|
+ }
|
|
+
|
|
+ DHT_CHANGELOG_TRACK_AS_RENAME(xattr_new, &local->loc,
|
|
+ &local->loc2);
|
|
+ STACK_WIND_COOKIE (frame, dht_rename_unlink_cbk, src_cached,
|
|
+ src_cached, src_cached->fops->unlink,
|
|
+ &local->loc, 0, xattr_new);
|
|
+
|
|
+ dict_unref (xattr_new);
|
|
+ xattr_new = NULL;
|
|
+ }
|
|
+
|
|
+ if (src_hashed != rename_subvol && src_hashed != src_cached) {
|
|
+ dict_t *xattr_new = NULL;
|
|
+
|
|
+ xattr_new = dict_copy_with_ref (xattr, NULL);
|
|
+
|
|
+ gf_msg_trace (this->name, 0,
|
|
+ "deleting old src linkfile %s @ %s",
|
|
+ local->loc.path, src_hashed->name);
|
|
+
|
|
+ DHT_MARKER_DONT_ACCOUNT(xattr_new);
|
|
+
|
|
+ STACK_WIND_COOKIE (frame, dht_rename_unlink_cbk, src_hashed,
|
|
+ src_hashed, src_hashed->fops->unlink,
|
|
+ &local->loc, 0, xattr_new);
|
|
+
|
|
+ dict_unref (xattr_new);
|
|
+ xattr_new = NULL;
|
|
+ }
|
|
+
|
|
+ if (dst_cached &&
|
|
+ (dst_cached != dst_hashed) &&
|
|
+ (dst_cached != src_cached)) {
|
|
+ gf_msg_trace (this->name, 0,
|
|
+ "deleting old dst datafile %s @ %s",
|
|
+ local->loc2.path, dst_cached->name);
|
|
+
|
|
+ STACK_WIND_COOKIE (frame, dht_rename_unlink_cbk, dst_cached,
|
|
+ dst_cached, dst_cached->fops->unlink,
|
|
+ &local->loc2, 0, xattr);
|
|
+ }
|
|
+ if (xattr)
|
|
+ dict_unref (xattr);
|
|
+ return 0;
|
|
+
|
|
+unwind:
|
|
+ WIPE (&local->preoldparent);
|
|
+ WIPE (&local->postoldparent);
|
|
+ WIPE (&local->preparent);
|
|
+ WIPE (&local->postparent);
|
|
+
|
|
+ dht_rename_done (frame, this);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+int
|
|
dht_rename_links_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
|
|
int32_t op_ret, int32_t op_errno,
|
|
inode_t *inode, struct iatt *stbuf,
|
|
@@ -947,6 +1061,7 @@ dht_rename_links_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
|
|
prev = cookie;
|
|
local = frame->local;
|
|
|
|
+ /* TODO: Handle this case in lookup-optimize */
|
|
if (op_ret == -1) {
|
|
gf_msg (this->name, GF_LOG_WARNING, op_errno,
|
|
DHT_MSG_CREATE_LINK_FAILED,
|
|
@@ -958,8 +1073,8 @@ dht_rename_links_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
|
|
local->linked = _gf_false;
|
|
dht_linkfile_attr_heal (frame, this);
|
|
}
|
|
- DHT_STACK_DESTROY (frame);
|
|
|
|
+ dht_rename_unlink (frame, this);
|
|
return 0;
|
|
}
|
|
|
|
@@ -973,19 +1088,14 @@ dht_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
|
|
{
|
|
dht_local_t *local = NULL;
|
|
xlator_t *prev = NULL;
|
|
- xlator_t *src_hashed = NULL;
|
|
xlator_t *src_cached = NULL;
|
|
xlator_t *dst_hashed = NULL;
|
|
xlator_t *dst_cached = NULL;
|
|
- xlator_t *rename_subvol = NULL;
|
|
- call_frame_t *link_frame = NULL;
|
|
- dht_local_t *link_local = NULL;
|
|
- dict_t *xattr = NULL;
|
|
+ loc_t link_loc = {0};
|
|
|
|
local = frame->local;
|
|
prev = cookie;
|
|
|
|
- src_hashed = local->src_hashed;
|
|
src_cached = local->src_cached;
|
|
dst_hashed = local->dst_hashed;
|
|
dst_cached = local->dst_cached;
|
|
@@ -1043,31 +1153,6 @@ dht_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
|
|
local->xattr = dict_copy_with_ref (xdata, local->xattr);
|
|
}
|
|
|
|
- if ((src_cached == dst_cached) && (dst_hashed != dst_cached)) {
|
|
- link_frame = copy_frame (frame);
|
|
- if (!link_frame) {
|
|
- goto err;
|
|
- }
|
|
-
|
|
- /* fop value sent as maxvalue because it is not used
|
|
- anywhere in this case */
|
|
- link_local = dht_local_init (link_frame, &local->loc2, NULL,
|
|
- GF_FOP_MAXVALUE);
|
|
- if (!link_local) {
|
|
- goto err;
|
|
- }
|
|
-
|
|
- if (link_local->loc.inode)
|
|
- inode_unref (link_local->loc.inode);
|
|
- link_local->loc.inode = inode_ref (local->loc.inode);
|
|
- gf_uuid_copy (link_local->gfid, local->loc.inode->gfid);
|
|
-
|
|
- dht_linkfile_create (link_frame, dht_rename_links_create_cbk,
|
|
- this, src_cached, dst_hashed,
|
|
- &link_local->loc);
|
|
- }
|
|
-
|
|
-err:
|
|
/* Merge attrs only from src_cached. In case there of src_cached !=
|
|
* dst_hashed, this ignores linkfile attrs. */
|
|
if (prev == src_cached) {
|
|
@@ -1080,98 +1165,23 @@ err:
|
|
dht_iatt_merge (this, &local->postparent, postnewparent, prev);
|
|
}
|
|
|
|
+ /* Create the linkto file for the dst file */
|
|
+ if ((src_cached == dst_cached) && (dst_hashed != dst_cached)) {
|
|
|
|
- /* NOTE: rename_subvol is the same subvolume from which dht_rename_cbk
|
|
- * is called. since rename has already happened on rename_subvol,
|
|
- * unlink should not be sent for oldpath (either linkfile or cached-file)
|
|
- * on rename_subvol. */
|
|
- if (src_cached == dst_cached)
|
|
- rename_subvol = src_cached;
|
|
- else
|
|
- rename_subvol = dst_hashed;
|
|
-
|
|
- /* TODO: delete files in background */
|
|
-
|
|
- if (src_cached != dst_hashed && src_cached != dst_cached)
|
|
- local->call_cnt++;
|
|
-
|
|
- if (src_hashed != rename_subvol && src_hashed != src_cached)
|
|
- local->call_cnt++;
|
|
-
|
|
- if (dst_cached && dst_cached != dst_hashed && dst_cached != src_cached)
|
|
- local->call_cnt++;
|
|
-
|
|
- if (local->call_cnt == 0)
|
|
- goto unwind;
|
|
-
|
|
- DHT_MARK_FOP_INTERNAL (xattr);
|
|
-
|
|
- if (src_cached != dst_hashed && src_cached != dst_cached) {
|
|
- dict_t *xattr_new = NULL;
|
|
-
|
|
- xattr_new = dict_copy_with_ref (xattr, NULL);
|
|
-
|
|
- gf_msg_trace (this->name, 0,
|
|
- "deleting old src datafile %s @ %s",
|
|
- local->loc.path, src_cached->name);
|
|
-
|
|
- if (gf_uuid_compare (local->loc.pargfid,
|
|
- local->loc2.pargfid) == 0) {
|
|
- DHT_MARKER_DONT_ACCOUNT(xattr_new);
|
|
- }
|
|
-
|
|
- DHT_CHANGELOG_TRACK_AS_RENAME(xattr_new, &local->loc,
|
|
- &local->loc2);
|
|
- STACK_WIND_COOKIE (frame, dht_rename_unlink_cbk, src_cached,
|
|
- src_cached, src_cached->fops->unlink,
|
|
- &local->loc, 0, xattr_new);
|
|
-
|
|
- dict_unref (xattr_new);
|
|
- xattr_new = NULL;
|
|
- }
|
|
-
|
|
- if (src_hashed != rename_subvol && src_hashed != src_cached) {
|
|
- dict_t *xattr_new = NULL;
|
|
-
|
|
- xattr_new = dict_copy_with_ref (xattr, NULL);
|
|
-
|
|
- gf_msg_trace (this->name, 0,
|
|
- "deleting old src linkfile %s @ %s",
|
|
- local->loc.path, src_hashed->name);
|
|
-
|
|
- DHT_MARKER_DONT_ACCOUNT(xattr_new);
|
|
-
|
|
- STACK_WIND_COOKIE (frame, dht_rename_unlink_cbk, src_hashed,
|
|
- src_hashed, src_hashed->fops->unlink,
|
|
- &local->loc, 0, xattr_new);
|
|
-
|
|
- dict_unref (xattr_new);
|
|
- xattr_new = NULL;
|
|
- }
|
|
+ loc_copy (&link_loc, &local->loc2);
|
|
+ if (link_loc.inode)
|
|
+ inode_unref (link_loc.inode);
|
|
+ link_loc.inode = inode_ref (local->loc.inode);
|
|
+ gf_uuid_copy (local->gfid, local->loc.inode->gfid);
|
|
+ gf_uuid_copy (link_loc.gfid, local->loc.inode->gfid);
|
|
|
|
- if (dst_cached
|
|
- && (dst_cached != dst_hashed)
|
|
- && (dst_cached != src_cached)) {
|
|
- gf_msg_trace (this->name, 0,
|
|
- "deleting old dst datafile %s @ %s",
|
|
- local->loc2.path, dst_cached->name);
|
|
-
|
|
- STACK_WIND_COOKIE (frame, dht_rename_unlink_cbk, dst_cached,
|
|
- dst_cached, dst_cached->fops->unlink,
|
|
- &local->loc2, 0, xattr);
|
|
+ dht_linkfile_create (frame, dht_rename_links_create_cbk,
|
|
+ this, src_cached, dst_hashed,
|
|
+ &link_loc);
|
|
+ return 0;
|
|
}
|
|
- if (xattr)
|
|
- dict_unref (xattr);
|
|
- return 0;
|
|
-
|
|
-unwind:
|
|
- WIPE (&local->preoldparent);
|
|
- WIPE (&local->postoldparent);
|
|
- WIPE (&local->preparent);
|
|
- WIPE (&local->postparent);
|
|
-
|
|
- dht_rename_done (frame, this);
|
|
|
|
+ dht_rename_unlink (frame, this);
|
|
return 0;
|
|
|
|
cleanup:
|
|
--
|
|
1.8.3.1
|
|
|