diff options
-rwxr-xr-x | tests/bugs/posix/bug-1619720.t | 3 | ||||
-rw-r--r-- | xlators/cluster/dht/src/dht-rename.c | 254 |
2 files changed, 134 insertions, 123 deletions
diff --git a/tests/bugs/posix/bug-1619720.t b/tests/bugs/posix/bug-1619720.t index e5d9a80c601..bfd304dc809 100755 --- a/tests/bugs/posix/bug-1619720.t +++ b/tests/bugs/posix/bug-1619720.t @@ -48,10 +48,11 @@ 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 # Not required for the test but an extra check if required. # The linkto file was not renamed Without the fix. #TEST mv $M0/tmp/file-3 $M0/tmp/file-6 -#cleanup; +cleanup; diff --git a/xlators/cluster/dht/src/dht-rename.c b/xlators/cluster/dht/src/dht-rename.c index 62b72b7dc29..295d95232ec 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) { @@ -1078,98 +1163,23 @@ err: dht_iatt_merge (this, &local->postparent, postnewparent); } + /* 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: |