Blob Blame History Raw
From 2ca340c34e820ef4232ee20f1084fe4803ca2140 Mon Sep 17 00:00:00 2001
From: moagrawa <moagrawa@redhat.com>
Date: Tue, 29 Nov 2016 11:12:00 +0530
Subject: [PATCH 206/206] cluster/dht: A hard link is lost during rebalance +
 lookup

Problem: A hard link is lost during rebalance + lookup.Rebalance skip
         files if file has hardlink.In dht_migrate_file
         __is_file_migratable () function checks if a file has hardlink,
         if yes file is not migrated but if link is created after call
         this function then link will lost.

Solution: Call __check_file_has_hardlink to check hardlink existence
          after (S+T) bits in migration process ,if file has hardlink
          then skip the file for migrate rebalance process.

> BUG: 1396048
> Change-Id: Ia53c07ef42f1128c2eedf959a757e8df517b9d12
> Signed-off-by: Mohit Agrawal <moagrawa@redhat.com>
> Reviewed-on: http://review.gluster.org/15866
> Reviewed-by: Susant Palai <spalai@redhat.com>
> Smoke: Gluster Build System <jenkins@build.gluster.org>
> NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org>
> CentOS-regression: Gluster Build System <jenkins@build.gluster.org>
> Reviewed-by: N Balachandran <nbalacha@redhat.com>
> Reviewed-by: Raghavendra G <rgowdapp@redhat.com>
> (cherry picked from commit 71dd2e914d4a537bf74e1ec3a24512fc83bacb1d)

BUG: 1392837
Change-Id: I7d96c56e497c0cefe40093c4588c53ef8540fc3d
Signed-off-by: moagrawa <moagrawa@redhat.com>
Reviewed-on: https://code.engineering.redhat.com/gerrit/91494
Reviewed-by: Raghavendra Gowdappa <rgowdapp@redhat.com>
---
 xlators/cluster/dht/src/dht-rebalance.c | 101 ++++++++++++++++++++------------
 1 file changed, 62 insertions(+), 39 deletions(-)

diff --git a/xlators/cluster/dht/src/dht-rebalance.c b/xlators/cluster/dht/src/dht-rebalance.c
index 2373e9d..c82700e 100644
--- a/xlators/cluster/dht/src/dht-rebalance.c
+++ b/xlators/cluster/dht/src/dht-rebalance.c
@@ -464,6 +464,50 @@ out:
         return ret;
 }
 
+
+static int
+__check_file_has_hardlink (xlator_t *this, loc_t *loc,
+                      struct iatt *stbuf, dict_t *xattrs, int flags,
+                                gf_defrag_info_t *defrag)
+{
+       int ret = 0;
+
+       if (flags == GF_DHT_MIGRATE_HARDLINK_IN_PROGRESS) {
+                ret = 0;
+                return ret;
+       }
+       if (stbuf->ia_nlink > 1) {
+                /* support for decomission */
+                if (flags == GF_DHT_MIGRATE_HARDLINK) {
+                        synclock_lock (&defrag->link_lock);
+                        ret = gf_defrag_handle_hardlink
+                                (this, loc, xattrs, stbuf);
+                        synclock_unlock (&defrag->link_lock);
+                        /*
+                          Returning zero will force the file to be remigrated.
+                          Checkout gf_defrag_handle_hardlink for more
+                          information.
+                        */
+                        if (ret && ret != -2) {
+                                gf_msg (this->name, GF_LOG_WARNING, 0,
+                                        DHT_MSG_MIGRATE_FILE_FAILED,
+                                        "Migrate file failed:"
+                                        "%s: failed to migrate file with link",
+                                        loc->path);
+                        }
+                } else {
+                        gf_msg (this->name, GF_LOG_WARNING, 0,
+                                DHT_MSG_MIGRATE_FILE_FAILED,
+                                "Migrate file failed:"
+                                "%s: file has hardlinks", loc->path);
+                        ret = -ENOTSUP;
+                }
+       }
+
+       return ret;
+}
+
+
 /*
      return values
      0 : File will be migrated
@@ -512,41 +556,9 @@ __is_file_migratable (xlator_t *this, loc_t *loc,
                 }
         }
 
-        if (flags == GF_DHT_MIGRATE_HARDLINK_IN_PROGRESS) {
-                ret = 0;
-                goto out;
-        }
-
-        if (stbuf->ia_nlink > 1) {
-                /* support for decomission */
-                if (flags == GF_DHT_MIGRATE_HARDLINK) {
-                        synclock_lock (&defrag->link_lock);
-                        ret = gf_defrag_handle_hardlink
-                                (this, loc, xattrs, stbuf);
-                        synclock_unlock (&defrag->link_lock);
-                        /*
-                        Returning zero will force the file to be remigrated.
-                        Checkout gf_defrag_handle_hardlink for more information.
-                        */
-                        if (ret && ret != -2) {
-                                gf_msg (this->name, GF_LOG_WARNING, 0,
-                                        DHT_MSG_MIGRATE_FILE_FAILED,
-                                        "Migrate file failed:"
-                                        "%s: failed to migrate file with link",
-                                        loc->path);
-                        }
-                } else {
-                        gf_msg (this->name, GF_LOG_WARNING, 0,
-                                DHT_MSG_MIGRATE_FILE_FAILED,
-                                "Migrate file failed:"
-                                "%s: file has hardlinks", loc->path);
-                        ret = -ENOTSUP;
-                }
-                goto out;
-        }
-
-        ret = 0;
-
+        /* Check if file has hardlink*/
+        ret = __check_file_has_hardlink (this, loc, stbuf, xattrs,
+                                         flags, defrag);
 out:
         return ret;
 }
@@ -1368,9 +1380,6 @@ dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to,
                 goto out;
         }
 
-        /* we no more require this key */
-        dict_del (dict, conf->link_xattr_name);
-
         /* preserve source mode, so set the same to the destination */
         src_ia_prot = stbuf.ia_prot;
 
@@ -1425,8 +1434,13 @@ dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to,
                 goto out;
         }
 
+        if (xattr_rsp) {
+                /* we no more require this key */
+                dict_del (dict, conf->link_xattr_name);
+                dict_unref (xattr_rsp);
+        }
 
-        ret = syncop_fstat (from, src_fd, &stbuf, NULL, NULL);
+        ret = syncop_fstat (from, src_fd, &stbuf, dict, &xattr_rsp);
         if (ret) {
                 gf_msg (this->name, GF_LOG_ERROR, -ret,
                         DHT_MSG_MIGRATE_FILE_FAILED,
@@ -1436,6 +1450,15 @@ dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to,
                 goto out;
         }
 
+        /* Check again if file has hardlink */
+        ret = __check_file_has_hardlink (this, loc, &stbuf, xattr_rsp,
+                                         flag, defrag);
+        if (ret) {
+                if (ret == -2)
+                        ret = 0;
+                goto out;
+        }
+
         /* Try to preserve 'holes' while migrating data */
         if (stbuf.ia_size > (stbuf.ia_blocks * GF_DISK_SECTOR_SIZE))
                 file_has_holes = 1;
-- 
2.9.3