cb8e9e
From effeeb6b530a49370d3f4882238b1a9eb94e84b9 Mon Sep 17 00:00:00 2001
cb8e9e
From: Susant Palai <spalai@redhat.com>
cb8e9e
Date: Fri, 4 Sep 2015 05:14:05 -0400
cb8e9e
Subject: [PATCH 325/330] dht/remove-brick: Avoid data loss for hard link migration
cb8e9e
cb8e9e
Problem: If the hashed subvol of a file has reached cluster.min-free-disk,
cb8e9e
for a create opertaion a linkto file will be created on the hashed and
cb8e9e
the data file will be created on some other brick.
cb8e9e
cb8e9e
For creation of the linkfile we populate the dictionary with linkto key
cb8e9e
and value as the cached subvol. After successful linkto file creation,
cb8e9e
the linkto-key-value pair is not deleted form the dictionary and hence,
cb8e9e
the data file will also have linkto xattr which points to itself.This looks
cb8e9e
something like this.
cb8e9e
cb8e9e
  client-0                                    client-1
cb8e9e
-------T file                               rwx------file
cb8e9e
linkto.xattr=client-1                       linkto.xattr=client-1
cb8e9e
cb8e9e
Now coming to the data loss part. Hardlink migration highly depend on this
cb8e9e
linkto xattr on the data file. This value should be the new hashed subvol
cb8e9e
of the first hardlink encountered post fix-layout. But when it tries to
cb8e9e
read the linkto xattr it gets the same target as where it is sitting.
cb8e9e
cb8e9e
Now the source and destination are same for migration. At the end of
cb8e9e
migration the source file is truncated and deleted, which in this case
cb8e9e
is the destination and also the only data file it self resulting in
cb8e9e
data loss.
cb8e9e
cb8e9e
BUG: 1259750
cb8e9e
Change-Id: Ie65204bfc63638164f10e17ed0552f86016bdf44
cb8e9e
Signed-off-by: Susant Palai <spalai@redhat.com>
cb8e9e
Reviewed-on: http://review.gluster.org/12105
cb8e9e
Reviewed-by: N Balachandran <nbalacha@redhat.com>
cb8e9e
Tested-by: NetBSD Build System <jenkins@build.gluster.org>
cb8e9e
Reviewed-by: Raghavendra G <rgowdapp@redhat.com>
cb8e9e
Signed-off-by: Susant Palai <spalai@redhat.com>
cb8e9e
Reviewed-on: https://code.engineering.redhat.com/gerrit/57566
cb8e9e
Reviewed-by: Nithya Balachandran <nbalacha@redhat.com>
cb8e9e
Reviewed-by: Raghavendra Gowdappa <rgowdapp@redhat.com>
cb8e9e
Tested-by: Raghavendra Gowdappa <rgowdapp@redhat.com>
cb8e9e
---
cb8e9e
 xlators/cluster/dht/src/dht-common.c |   42 +++++++++++++++++++++++++++++-----
cb8e9e
 1 files changed, 36 insertions(+), 6 deletions(-)
cb8e9e
cb8e9e
diff --git a/xlators/cluster/dht/src/dht-common.c b/xlators/cluster/dht/src/dht-common.c
cb8e9e
index e3fe7dd..1d27fba 100644
cb8e9e
--- a/xlators/cluster/dht/src/dht-common.c
cb8e9e
+++ b/xlators/cluster/dht/src/dht-common.c
cb8e9e
@@ -5022,20 +5022,33 @@ dht_mknod_linkfile_create_cbk (call_frame_t *frame, void *cookie,
cb8e9e
                                struct iatt *preparent, struct iatt *postparent,
cb8e9e
                                dict_t *xdata)
cb8e9e
 {
cb8e9e
-        dht_local_t  *local = NULL;
cb8e9e
-        xlator_t     *cached_subvol = NULL;
cb8e9e
+        dht_local_t     *local          = NULL;
cb8e9e
+        xlator_t        *cached_subvol  = NULL;
cb8e9e
+        dht_conf_t      *conf           = NULL;
cb8e9e
 
cb8e9e
         local = frame->local;
cb8e9e
-        if (op_ret == -1)
cb8e9e
-                goto err;
cb8e9e
 
cb8e9e
         if (!local || !local->cached_subvol) {
cb8e9e
                 op_errno = EINVAL;
cb8e9e
                 goto err;
cb8e9e
         }
cb8e9e
 
cb8e9e
+        if (op_ret == -1)
cb8e9e
+                goto err;
cb8e9e
+
cb8e9e
+        conf = this->private;
cb8e9e
+        if (!conf) {
cb8e9e
+                local->op_errno =  EINVAL;
cb8e9e
+                goto err;
cb8e9e
+        }
cb8e9e
+
cb8e9e
         cached_subvol = local->cached_subvol;
cb8e9e
 
cb8e9e
+        if (local->params) {
cb8e9e
+                 dict_del (local->params, conf->link_xattr_name);
cb8e9e
+                 dict_del (local->params, GLUSTERFS_INTERNAL_FOP_KEY);
cb8e9e
+        }
cb8e9e
+
cb8e9e
         STACK_WIND_COOKIE (frame, dht_newfile_cbk, (void *)cached_subvol,
cb8e9e
                            cached_subvol, cached_subvol->fops->mknod,
cb8e9e
                            &local->loc, local->mode, local->rdev, local->umask,
cb8e9e
@@ -5819,17 +5832,34 @@ dht_create_linkfile_create_cbk (call_frame_t *frame, void *cookie,
cb8e9e
                                 struct iatt *preparent, struct iatt *postparent,
cb8e9e
                                 dict_t *xdata)
cb8e9e
 {
cb8e9e
-        dht_local_t  *local = NULL;
cb8e9e
-        xlator_t     *cached_subvol = NULL;
cb8e9e
+        dht_local_t     *local             = NULL;
cb8e9e
+        xlator_t        *cached_subvol     = NULL;
cb8e9e
+        dht_conf_t      *conf              = NULL;
cb8e9e
 
cb8e9e
         local = frame->local;
cb8e9e
+        if (!local) {
cb8e9e
+                op_errno = EINVAL;
cb8e9e
+                goto err;
cb8e9e
+        }
cb8e9e
+
cb8e9e
         if (op_ret == -1) {
cb8e9e
                 local->op_errno = op_errno;
cb8e9e
                 goto err;
cb8e9e
         }
cb8e9e
 
cb8e9e
+        conf = this->private;
cb8e9e
+        if (!conf) {
cb8e9e
+                local->op_errno = EINVAL;
cb8e9e
+                goto err;
cb8e9e
+        }
cb8e9e
+
cb8e9e
         cached_subvol = local->cached_subvol;
cb8e9e
 
cb8e9e
+        if (local->params) {
cb8e9e
+                dict_del (local->params, conf->link_xattr_name);
cb8e9e
+                dict_del (local->params, GLUSTERFS_INTERNAL_FOP_KEY);
cb8e9e
+        }
cb8e9e
+
cb8e9e
         STACK_WIND (frame, dht_create_cbk,
cb8e9e
                     cached_subvol, cached_subvol->fops->create,
cb8e9e
                     &local->loc, local->flags, local->mode,
cb8e9e
-- 
cb8e9e
1.7.1
cb8e9e