From effeeb6b530a49370d3f4882238b1a9eb94e84b9 Mon Sep 17 00:00:00 2001 From: Susant Palai Date: Fri, 4 Sep 2015 05:14:05 -0400 Subject: [PATCH 325/330] 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: 1259750 Change-Id: Ie65204bfc63638164f10e17ed0552f86016bdf44 Signed-off-by: Susant Palai Reviewed-on: http://review.gluster.org/12105 Reviewed-by: N Balachandran Tested-by: NetBSD Build System Reviewed-by: Raghavendra G Signed-off-by: Susant Palai Reviewed-on: https://code.engineering.redhat.com/gerrit/57566 Reviewed-by: Nithya Balachandran Reviewed-by: Raghavendra Gowdappa Tested-by: Raghavendra Gowdappa --- xlators/cluster/dht/src/dht-common.c | 42 +++++++++++++++++++++++++++++----- 1 files changed, 36 insertions(+), 6 deletions(-) diff --git a/xlators/cluster/dht/src/dht-common.c b/xlators/cluster/dht/src/dht-common.c index e3fe7dd..1d27fba 100644 --- a/xlators/cluster/dht/src/dht-common.c +++ b/xlators/cluster/dht/src/dht-common.c @@ -5022,20 +5022,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, @@ -5819,17 +5832,34 @@ 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, -- 1.7.1