diff options
author | Susant Palai <spalai@redhat.com> | 2015-09-04 05:14:05 -0400 |
---|---|---|
committer | Raghavendra G <rgowdapp@redhat.com> | 2015-09-13 22:46:58 -0700 |
commit | 23e522eea17e15b37d395e2005139dd3d5a9e3a1 (patch) | |
tree | 99b03b9e47ecd0fc1c57cae5d49257802ad04710 | |
parent | e89b7dc4f88644cb4538bd1dd3cd493028808bd6 (diff) |
dht/remove-brick: Avoid data loss for hard link migration
Problem: If the hashed subvol of a file has reached cluster.min-free-disk,
for a create opertaion a linkto file will be created on the hashed and
the data file will be created on some other brick.
For creation of the linkfile we populate the dictionary with linkto key
and value as the cached subvol. After successful linkto file creation,
the linkto-key-value pair is not deleted form the dictionary and hence,
the data file will also have linkto xattr which points to itself.This looks
something like this.
client-0 client-1
-------T file rwx------file
linkto.xattr=client-1 linkto.xattr=client-1
Now coming to the data loss part. Hardlink migration highly depend on this
linkto xattr on the data file. This value should be the new hashed subvol
of the first hardlink encountered post fix-layout. But when it tries to
read the linkto xattr it gets the same target as where it is sitting.
Now the source and destination are same for migration. At the end of
migration the source file is truncated and deleted, which in this case
is the destination and also the only data file it self resulting in
data loss.
BUG: 1262197
Change-Id: I5338a5704ac60ca9afb278977e178319266a0cc0
Signed-off-by: Susant Palai <spalai@redhat.com>
Reviewed-on: http://review.gluster.org/12105
Reviewed-by: N Balachandran <nbalacha@redhat.com>
Tested-by: NetBSD Build System <jenkins@build.gluster.org>
Reviewed-by: Raghavendra G <rgowdapp@redhat.com>
Signed-off-by: Susant Palai <spalai@redhat.com>
Reviewed-on: http://review.gluster.org/12156
Tested-by: Gluster Build System <jenkins@build.gluster.com>
-rw-r--r-- | xlators/cluster/dht/src/dht-common.c | 57 |
1 files changed, 49 insertions, 8 deletions
diff --git a/xlators/cluster/dht/src/dht-common.c b/xlators/cluster/dht/src/dht-common.c index 9a8a161bd17..e41e17a2d4f 100644 --- a/xlators/cluster/dht/src/dht-common.c +++ b/xlators/cluster/dht/src/dht-common.c @@ -5038,20 +5038,33 @@ dht_mknod_linkfile_create_cbk (call_frame_t *frame, void *cookie, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { - dht_local_t *local = NULL; - xlator_t *cached_subvol = NULL; + dht_local_t *local = NULL; + xlator_t *cached_subvol = NULL; + dht_conf_t *conf = NULL; local = frame->local; - if (op_ret == -1) - goto err; if (!local || !local->cached_subvol) { op_errno = EINVAL; goto err; } + if (op_ret == -1) + goto err; + + conf = this->private; + if (!conf) { + local->op_errno = EINVAL; + goto err; + } + cached_subvol = local->cached_subvol; + if (local->params) { + dict_del (local->params, conf->link_xattr_name); + dict_del (local->params, GLUSTERFS_INTERNAL_FOP_KEY); + } + STACK_WIND_COOKIE (frame, dht_newfile_cbk, (void *)cached_subvol, cached_subvol, cached_subvol->fops->mknod, &local->loc, local->mode, local->rdev, local->umask, @@ -5059,8 +5072,13 @@ dht_mknod_linkfile_create_cbk (call_frame_t *frame, void *cookie, return 0; err: - if (local->lock.locks) + if (local && local->lock.locks) { local->refresh_layout_unlock (frame, this, -1); + } else { + DHT_STACK_UNWIND (mknod, frame, -1, + op_errno, NULL, NULL, NULL, + NULL, NULL); + } return 0; } @@ -5836,26 +5854,49 @@ dht_create_linkfile_create_cbk (call_frame_t *frame, void *cookie, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { - dht_local_t *local = NULL; - xlator_t *cached_subvol = NULL; + dht_local_t *local = NULL; + xlator_t *cached_subvol = NULL; + dht_conf_t *conf = NULL; local = frame->local; + if (!local) { + op_errno = EINVAL; + goto err; + } + if (op_ret == -1) { local->op_errno = op_errno; goto err; } + conf = this->private; + if (!conf) { + local->op_errno = EINVAL; + goto err; + } + cached_subvol = local->cached_subvol; + if (local->params) { + dict_del (local->params, conf->link_xattr_name); + dict_del (local->params, GLUSTERFS_INTERNAL_FOP_KEY); + } + STACK_WIND (frame, dht_create_cbk, cached_subvol, cached_subvol->fops->create, &local->loc, local->flags, local->mode, local->umask, local->fd, local->params); return 0; + err: - if (local->lock.locks) + if (local && local->lock.locks) { local->refresh_layout_unlock (frame, this, -1); + } else { + DHT_STACK_UNWIND (create, frame, -1, + op_errno, NULL, NULL, NULL, + NULL, NULL, NULL); + } return 0; } |