Blob Blame History Raw
From effeeb6b530a49370d3f4882238b1a9eb94e84b9 Mon Sep 17 00:00:00 2001
From: Susant Palai <spalai@redhat.com>
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 <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: https://code.engineering.redhat.com/gerrit/57566
Reviewed-by: Nithya Balachandran <nbalacha@redhat.com>
Reviewed-by: Raghavendra Gowdappa <rgowdapp@redhat.com>
Tested-by: Raghavendra Gowdappa <rgowdapp@redhat.com>
---
 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