21ab4e
From e51e7575c8194fd9f98d1c26dd6395030d95e1b2 Mon Sep 17 00:00:00 2001
21ab4e
From: Susant Palai <spalai@redhat.com>
21ab4e
Date: Tue, 10 Jan 2017 16:11:50 +0530
21ab4e
Subject: [PATCH 431/473] cluster/dht: rebalance perf enhancement
21ab4e
21ab4e
Problem: Throttle settings "normal" and "aggressive" for rebalance
21ab4e
did not have performance difference.
21ab4e
21ab4e
normal mode spawns $(no. of cores - 4)/2 threads and aggressive
21ab4e
spawns $(no. of cores - 4) threads. Though aggressive mode has twice
21ab4e
the number of threads compared to that of normal mode, there was no
21ab4e
performance gain when switched to aggressive mode from normal mode.
21ab4e
21ab4e
RCA:
21ab4e
During the course of debugging the above problem, we tried assigning
21ab4e
migration job to migration threads spawned by rebalance, rather than
21ab4e
synctasks(as there is more overhead associated to manage the task
21ab4e
queue and threads). This gave us a significant improvement over rebalance
21ab4e
under synctasks. This patch does not really gurantee that there will be a
21ab4e
clear performance difference between normal and aggressive mode, but this
21ab4e
patch certainly maximized the disk utilization for 1GBfiles run.
21ab4e
21ab4e
Results:
21ab4e
21ab4e
Test enviroment:
21ab4e
Gluster Config:
21ab4e
Number of Bricks: 2 (one brick per disk(RAID-6 12 disk))
21ab4e
Bricks:
21ab4e
Brick1: server1:/brick/test1/1
21ab4e
Brick2: server2:/brick/test1/1
21ab4e
Options Reconfigured:
21ab4e
performance.readdir-ahead: on
21ab4e
server.event-threads: 4
21ab4e
client.event-threads: 4
21ab4e
21ab4e
1000 files with 1GB each were created/renamed such that all files will have
21ab4e
server1 as cached and server2 as hashed, so that all files will be migrated.
21ab4e
21ab4e
Test machines had 24 cores each.
21ab4e
21ab4e
Results  with/without synctask based migration:
21ab4e
-----------------------------------------------
21ab4e
21ab4e
mode                    normal(10threads)          aggressive(20threads)
21ab4e
21ab4e
timetaken               0:55:30 (h:m:s)            0:56:3 (h:m:s)
21ab4e
withsynctask
21ab4e
21ab4e
timetaken
21ab4e
with migrator           0:38:3 (h:m:s)             0:23:41 (h:m:s)
21ab4e
threads
21ab4e
21ab4e
From above table it can be seen that, there is a clear 2x perf gain between
21ab4e
rebalance with synctask vs rebalance with migrator threads.
21ab4e
21ab4e
Additionally this patch modifies the code so that caller will have the exact error
21ab4e
number returned by dht_migrate_file(earlier the errno meaning was overloaded). This
21ab4e
will help avoiding scenarios where migration failure due to ENOENT, can result in
21ab4e
rebalance abort/failure.
21ab4e
21ab4e
> Change-Id: I8904e2fb147419d4a51c1267be11a08ffd52168e
21ab4e
> BUG: 1420166
21ab4e
> Signed-off-by: Susant Palai <spalai@redhat.com>
21ab4e
> Reviewed-on: https://review.gluster.org/16427
21ab4e
> Smoke: Gluster Build System <jenkins@build.gluster.org>
21ab4e
> Reviewed-by: N Balachandran <nbalacha@redhat.com>
21ab4e
> Reviewed-by: Raghavendra G <rgowdapp@redhat.com>
21ab4e
> NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org>
21ab4e
> CentOS-regression: Gluster Build System <jenkins@build.gluster.org>
21ab4e
21ab4e
Change-Id: I8904e2fb147419d4a51c1267be11a08ffd52168e
21ab4e
BUG: 1381142
21ab4e
Signed-off-by: Susant Palai <spalai@redhat.com>
21ab4e
Reviewed-on: https://review.gluster.org/16427
21ab4e
Smoke: Gluster Build System <jenkins@build.gluster.org>
21ab4e
Reviewed-by: N Balachandran <nbalacha@redhat.com>
21ab4e
Reviewed-by: Raghavendra G <rgowdapp@redhat.com>
21ab4e
NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org>
21ab4e
CentOS-regression: Gluster Build System <jenkins@build.gluster.org>
21ab4e
Signed-off-by: Susant Palai <spalai@redhat.com>
21ab4e
Reviewed-on: https://code.engineering.redhat.com/gerrit/104898
21ab4e
Reviewed-by: Nithya Balachandran <nbalacha@redhat.com>
21ab4e
---
21ab4e
 libglusterfs/src/syncop.c               |   2 +-
21ab4e
 xlators/cluster/dht/src/dht-common.h    |   4 +-
21ab4e
 xlators/cluster/dht/src/dht-rebalance.c | 380 +++++++++++++++++++++++---------
21ab4e
 3 files changed, 280 insertions(+), 106 deletions(-)
21ab4e
21ab4e
diff --git a/libglusterfs/src/syncop.c b/libglusterfs/src/syncop.c
21ab4e
index 00a9b57..badb056 100644
21ab4e
--- a/libglusterfs/src/syncop.c
21ab4e
+++ b/libglusterfs/src/syncop.c
21ab4e
@@ -1566,7 +1566,7 @@ syncop_setxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
21ab4e
 
21ab4e
 int
21ab4e
 syncop_setxattr (xlator_t *subvol, loc_t *loc, dict_t *dict, int32_t flags,
21ab4e
-		 dict_t *xdata_in, dict_t **xdata_out)
21ab4e
+                 dict_t *xdata_in, dict_t **xdata_out)
21ab4e
 {
21ab4e
         struct syncargs args = {0, };
21ab4e
 
21ab4e
diff --git a/xlators/cluster/dht/src/dht-common.h b/xlators/cluster/dht/src/dht-common.h
21ab4e
index eb6d1e8..16cc056 100644
21ab4e
--- a/xlators/cluster/dht/src/dht-common.h
21ab4e
+++ b/xlators/cluster/dht/src/dht-common.h
21ab4e
@@ -1088,10 +1088,10 @@ gf_defrag_start (void *this);
21ab4e
 
21ab4e
 int32_t
21ab4e
 gf_defrag_handle_hardlink (xlator_t *this, loc_t *loc, dict_t  *xattrs,
21ab4e
-                           struct iatt *stbuf);
21ab4e
+                           struct iatt *stbuf, int *fop_errno);
21ab4e
 int
21ab4e
 dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to,
21ab4e
-                 int flag);
21ab4e
+                 int flag, int *fop_errno);
21ab4e
 int
21ab4e
 dht_inode_ctx_layout_get (inode_t *inode, xlator_t *this,
21ab4e
                           dht_layout_t **layout_int);
21ab4e
diff --git a/xlators/cluster/dht/src/dht-rebalance.c b/xlators/cluster/dht/src/dht-rebalance.c
21ab4e
index b2279d0..9a7d9ab 100644
21ab4e
--- a/xlators/cluster/dht/src/dht-rebalance.c
21ab4e
+++ b/xlators/cluster/dht/src/dht-rebalance.c
21ab4e
@@ -18,12 +18,12 @@
21ab4e
 #include <signal.h>
21ab4e
 #include "events.h"
21ab4e
 
21ab4e
-
21ab4e
 #define GF_DISK_SECTOR_SIZE             512
21ab4e
 #define DHT_REBALANCE_PID               4242 /* Change it if required */
21ab4e
 #define DHT_REBALANCE_BLKSIZE           (1024 * 1024)  /* 1 MB */
21ab4e
 #define MAX_MIGRATE_QUEUE_COUNT         500
21ab4e
 #define MIN_MIGRATE_QUEUE_COUNT         200
21ab4e
+#define MAX_REBAL_TYPE_SIZE             16
21ab4e
 
21ab4e
 #ifndef MAX
21ab4e
 #define MAX(a, b) (((a) > (b))?(a):(b))
21ab4e
@@ -165,7 +165,8 @@ dht_send_rebalance_event (xlator_t *this, int cmd, gf_defrag_status_t status)
21ab4e
 
21ab4e
 static int
21ab4e
 dht_write_with_holes (xlator_t *to, fd_t *fd, struct iovec *vec, int count,
21ab4e
-                      int32_t size, off_t offset, struct iobref *iobref)
21ab4e
+                      int32_t size, off_t offset, struct iobref *iobref,
21ab4e
+                      int *fop_errno)
21ab4e
 {
21ab4e
         int i            = 0;
21ab4e
         int ret          = -1;
21ab4e
@@ -199,6 +200,7 @@ dht_write_with_holes (xlator_t *to, fd_t *fd, struct iovec *vec, int count,
21ab4e
                                         gf_log (THIS->name, GF_LOG_WARNING,
21ab4e
                                                 "failed to write (%s)",
21ab4e
                                                 strerror (-ret));
21ab4e
+                                        *fop_errno = -ret;
21ab4e
                                         ret = -1;
21ab4e
                                         goto out;
21ab4e
                                 }
21ab4e
@@ -219,6 +221,7 @@ dht_write_with_holes (xlator_t *to, fd_t *fd, struct iovec *vec, int count,
21ab4e
                                 gf_log (THIS->name, GF_LOG_WARNING,
21ab4e
                                         "failed to write (%s)",
21ab4e
                                         strerror (-ret));
21ab4e
+                                *fop_errno = -ret;
21ab4e
                                 ret = -1;
21ab4e
                                 goto out;
21ab4e
                         }
21ab4e
@@ -272,7 +275,7 @@ be converted to "0" in dht_migrate_file.
21ab4e
 
21ab4e
 int32_t
21ab4e
 gf_defrag_handle_hardlink (xlator_t *this, loc_t *loc, dict_t  *xattrs,
21ab4e
-                           struct iatt *stbuf)
21ab4e
+                           struct iatt *stbuf, int *fop_errno)
21ab4e
 {
21ab4e
         int32_t                 ret             = -1;
21ab4e
         xlator_t               *cached_subvol   = NULL;
21ab4e
@@ -285,6 +288,9 @@ gf_defrag_handle_hardlink (xlator_t *this, loc_t *loc, dict_t  *xattrs,
21ab4e
         gf_loglevel_t          loglevel         = 0;
21ab4e
         dict_t                 *link_xattr      = NULL;
21ab4e
 
21ab4e
+
21ab4e
+        *fop_errno = EINVAL;
21ab4e
+
21ab4e
         GF_VALIDATE_OR_GOTO ("defrag", loc, out);
21ab4e
         GF_VALIDATE_OR_GOTO ("defrag", loc->name, out);
21ab4e
         GF_VALIDATE_OR_GOTO ("defrag", stbuf, out);
21ab4e
@@ -299,6 +305,8 @@ gf_defrag_handle_hardlink (xlator_t *this, loc_t *loc, dict_t  *xattrs,
21ab4e
                         DHT_MSG_MIGRATE_FILE_FAILED,
21ab4e
                         "Migrate file failed :"
21ab4e
                         "loc->pargfid is NULL for %s", loc->path);
21ab4e
+                *fop_errno = EINVAL;
21ab4e
+                ret = -1;
21ab4e
                 goto out;
21ab4e
         }
21ab4e
 
21ab4e
@@ -307,13 +315,15 @@ gf_defrag_handle_hardlink (xlator_t *this, loc_t *loc, dict_t  *xattrs,
21ab4e
                         DHT_MSG_MIGRATE_FILE_FAILED,
21ab4e
                         "Migrate file failed :"
21ab4e
                         "loc->gfid is NULL for %s", loc->path);
21ab4e
+                *fop_errno = EINVAL;
21ab4e
+                ret = -1;
21ab4e
                 goto out;
21ab4e
         }
21ab4e
 
21ab4e
         link_xattr = dict_new ();
21ab4e
         if (!link_xattr) {
21ab4e
                 ret = -1;
21ab4e
-                errno = ENOMEM;
21ab4e
+                *fop_errno = ENOMEM;
21ab4e
                 goto out;
21ab4e
         }
21ab4e
 
21ab4e
@@ -354,6 +364,7 @@ gf_defrag_handle_hardlink (xlator_t *this, loc_t *loc, dict_t  *xattrs,
21ab4e
                         DHT_MSG_MIGRATE_FILE_FAILED,
21ab4e
                         "Migrate file failed:%s lookup failed with ret = %d",
21ab4e
                         loc->path, ret);
21ab4e
+                *fop_errno = -ret;
21ab4e
                 ret = -1;
21ab4e
                 goto out;
21ab4e
         }
21ab4e
@@ -365,6 +376,8 @@ gf_defrag_handle_hardlink (xlator_t *this, loc_t *loc, dict_t  *xattrs,
21ab4e
                         "Migrate file failed :"
21ab4e
                         "Failed to get cached subvol"
21ab4e
                         " for %s on %s", loc->name, this->name);
21ab4e
+                *fop_errno = EINVAL;
21ab4e
+                ret = -1;
21ab4e
                 goto out;
21ab4e
         }
21ab4e
 
21ab4e
@@ -375,6 +388,8 @@ gf_defrag_handle_hardlink (xlator_t *this, loc_t *loc, dict_t  *xattrs,
21ab4e
                         "Migrate file failed :"
21ab4e
                         "Failed to get hashed subvol"
21ab4e
                         " for %s on %s", loc->name, this->name);
21ab4e
+                *fop_errno = EINVAL;
21ab4e
+                ret = -1;
21ab4e
                 goto out;
21ab4e
         }
21ab4e
 
21ab4e
@@ -398,6 +413,8 @@ gf_defrag_handle_hardlink (xlator_t *this, loc_t *loc, dict_t  *xattrs,
21ab4e
                                 "Failed to set dictionary value:"
21ab4e
                                 " key = %s for %s",
21ab4e
                                 conf->link_xattr_name, loc->name);
21ab4e
+                        *fop_errno = ENOMEM;
21ab4e
+                        ret = -1;
21ab4e
                         goto out;
21ab4e
                 }
21ab4e
 
21ab4e
@@ -410,6 +427,7 @@ gf_defrag_handle_hardlink (xlator_t *this, loc_t *loc, dict_t  *xattrs,
21ab4e
                                 "Linkto setxattr failed %s -> %s (%s)",
21ab4e
                                 cached_subvol->name,
21ab4e
                                 loc->name, strerror (-ret));
21ab4e
+                        *fop_errno = -ret;
21ab4e
                         ret = -1;
21ab4e
                         goto out;
21ab4e
                 }
21ab4e
@@ -439,8 +457,10 @@ gf_defrag_handle_hardlink (xlator_t *this, loc_t *loc, dict_t  *xattrs,
21ab4e
                                 " failed on  subvol %s", loc->name,
21ab4e
                                 uuid_utoa(loc->gfid),
21ab4e
                                 hashed_subvol->name);
21ab4e
-                        if (op_errno != EEXIST)
21ab4e
+                        if (op_errno != EEXIST) {
21ab4e
+                                *fop_errno = op_errno;
21ab4e
                                 goto out;
21ab4e
+                        }
21ab4e
                 }
21ab4e
         }
21ab4e
         ret = syncop_lookup (hashed_subvol, loc, &iatt, NULL, NULL, NULL);
21ab4e
@@ -450,15 +470,18 @@ gf_defrag_handle_hardlink (xlator_t *this, loc_t *loc, dict_t  *xattrs,
21ab4e
                         "Migrate file failed :Failed lookup %s on %s ",
21ab4e
                         loc->name, hashed_subvol->name);
21ab4e
 
21ab4e
+                *fop_errno = -ret;
21ab4e
                 ret = -1;
21ab4e
                 goto out;
21ab4e
         }
21ab4e
 
21ab4e
         if (iatt.ia_nlink == stbuf->ia_nlink) {
21ab4e
                 ret = dht_migrate_file (this, loc, cached_subvol, hashed_subvol,
21ab4e
-                                        GF_DHT_MIGRATE_HARDLINK_IN_PROGRESS);
21ab4e
-                if (ret)
21ab4e
+                                        GF_DHT_MIGRATE_HARDLINK_IN_PROGRESS,
21ab4e
+                                        fop_errno);
21ab4e
+                if (ret) {
21ab4e
                         goto out;
21ab4e
+                }
21ab4e
         }
21ab4e
         ret = -2;
21ab4e
 out:
21ab4e
@@ -470,8 +493,8 @@ out:
21ab4e
 
21ab4e
 static int
21ab4e
 __check_file_has_hardlink (xlator_t *this, loc_t *loc,
21ab4e
-                      struct iatt *stbuf, dict_t *xattrs, int flags,
21ab4e
-                                gf_defrag_info_t *defrag)
21ab4e
+                           struct iatt *stbuf, dict_t *xattrs, int flags,
21ab4e
+                           gf_defrag_info_t *defrag, int *fop_errno)
21ab4e
 {
21ab4e
        int ret = 0;
21ab4e
 
21ab4e
@@ -484,7 +507,7 @@ __check_file_has_hardlink (xlator_t *this, loc_t *loc,
21ab4e
                 if (flags == GF_DHT_MIGRATE_HARDLINK) {
21ab4e
                         synclock_lock (&defrag->link_lock);
21ab4e
                         ret = gf_defrag_handle_hardlink
21ab4e
-                                (this, loc, xattrs, stbuf);
21ab4e
+                                (this, loc, xattrs, stbuf, fop_errno);
21ab4e
                         synclock_unlock (&defrag->link_lock);
21ab4e
                         /*
21ab4e
                           Returning zero will force the file to be remigrated.
21ab4e
@@ -501,9 +524,10 @@ __check_file_has_hardlink (xlator_t *this, loc_t *loc,
21ab4e
                 } else {
21ab4e
                         gf_msg (this->name, GF_LOG_WARNING, 0,
21ab4e
                                 DHT_MSG_MIGRATE_FILE_FAILED,
21ab4e
-                                "Migrate file failed:"
21ab4e
+                                "Migration skipped for:"
21ab4e
                                 "%s: file has hardlinks", loc->path);
21ab4e
-                        ret = -ENOTSUP;
21ab4e
+                        *fop_errno = ENOTSUP;
21ab4e
+                        ret = -1;
21ab4e
                 }
21ab4e
        }
21ab4e
 
21ab4e
@@ -522,7 +546,7 @@ __check_file_has_hardlink (xlator_t *this, loc_t *loc,
21ab4e
 static int
21ab4e
 __is_file_migratable (xlator_t *this, loc_t *loc,
21ab4e
                       struct iatt *stbuf, dict_t *xattrs, int flags,
21ab4e
-                                gf_defrag_info_t *defrag)
21ab4e
+                                gf_defrag_info_t *defrag, int *fop_errno)
21ab4e
 {
21ab4e
         int ret = -1;
21ab4e
         int lock_count = 0;
21ab4e
@@ -532,6 +556,7 @@ __is_file_migratable (xlator_t *this, loc_t *loc,
21ab4e
                         DHT_MSG_MIGRATE_FILE_FAILED,
21ab4e
                         "Migrate file failed:"
21ab4e
                         "%s: migrate-file called on directory", loc->path);
21ab4e
+                *fop_errno = EISDIR;
21ab4e
                 ret = -1;
21ab4e
                 goto out;
21ab4e
         }
21ab4e
@@ -545,6 +570,7 @@ __is_file_migratable (xlator_t *this, loc_t *loc,
21ab4e
                                 "Migrate file failed:"
21ab4e
                                 "%s: Unable to get lock count for file",
21ab4e
                                 loc->path);
21ab4e
+                        *fop_errno = EINVAL;
21ab4e
                         ret = -1;
21ab4e
                         goto out;
21ab4e
                 }
21ab4e
@@ -554,6 +580,7 @@ __is_file_migratable (xlator_t *this, loc_t *loc,
21ab4e
                                 DHT_MSG_MIGRATE_FILE_FAILED,
21ab4e
                                 "Migrate file failed: %s: File has locks."
21ab4e
                                 " Skipping file migration", loc->path);
21ab4e
+                        *fop_errno = ENOTSUP;
21ab4e
                         ret = -1;
21ab4e
                         goto out;
21ab4e
                 }
21ab4e
@@ -561,17 +588,17 @@ __is_file_migratable (xlator_t *this, loc_t *loc,
21ab4e
 
21ab4e
         /* Check if file has hardlink*/
21ab4e
         ret = __check_file_has_hardlink (this, loc, stbuf, xattrs,
21ab4e
-                                         flags, defrag);
21ab4e
+                                         flags, defrag, fop_errno);
21ab4e
 out:
21ab4e
         return ret;
21ab4e
 }
21ab4e
 
21ab4e
 
21ab4e
 static int
21ab4e
-__dht_rebalance_create_dst_file (xlator_t *to, xlator_t *from, loc_t *loc, struct iatt *stbuf,
21ab4e
-                                 fd_t **dst_fd, dict_t *xattr)
21ab4e
+__dht_rebalance_create_dst_file (xlator_t *this, xlator_t *to, xlator_t *from,
21ab4e
+                                 loc_t *loc, struct iatt *stbuf, fd_t **dst_fd,
21ab4e
+                                 dict_t *xattr, int *fop_errno)
21ab4e
 {
21ab4e
-        xlator_t    *this = NULL;
21ab4e
         int          ret  = -1;
21ab4e
         fd_t        *fd   = NULL;
21ab4e
         struct iatt  new_stbuf = {0,};
21ab4e
@@ -579,15 +606,21 @@ __dht_rebalance_create_dst_file (xlator_t *to, xlator_t *from, loc_t *loc, struc
21ab4e
         dht_conf_t  *conf = NULL;
21ab4e
         dict_t      *dict = NULL;
21ab4e
 
21ab4e
-        this = THIS;
21ab4e
         conf = this->private;
21ab4e
 
21ab4e
         dict = dict_new ();
21ab4e
-        if (!dict)
21ab4e
+        if (!dict) {
21ab4e
+                *fop_errno = ENOMEM;
21ab4e
+                ret = -1;
21ab4e
+                gf_msg (this->name, GF_LOG_ERROR, ENOMEM,
21ab4e
+                        DHT_MSG_NO_MEMORY, "dictionary allocation failed for"
21ab4e
+                        "path:%s", loc->path);
21ab4e
                 goto out;
21ab4e
-
21ab4e
+        }
21ab4e
         ret = dict_set_static_bin (dict, "gfid-req", stbuf->ia_gfid, 16);
21ab4e
         if (ret) {
21ab4e
+                *fop_errno = ENOMEM;
21ab4e
+                ret = -1;
21ab4e
                 gf_msg (this->name, GF_LOG_ERROR, 0,
21ab4e
                         DHT_MSG_DICT_SET_FAILED,
21ab4e
                         "%s: failed to set dictionary value: key = gfid-req",
21ab4e
@@ -597,6 +630,8 @@ __dht_rebalance_create_dst_file (xlator_t *to, xlator_t *from, loc_t *loc, struc
21ab4e
 
21ab4e
         ret = dict_set_str (dict, conf->link_xattr_name, from->name);
21ab4e
         if (ret) {
21ab4e
+                *fop_errno = ENOMEM;
21ab4e
+                ret = -1;
21ab4e
                 gf_msg (this->name, GF_LOG_ERROR, 0,
21ab4e
                         DHT_MSG_DICT_SET_FAILED,
21ab4e
                         "%s: failed to set dictionary value: key = %s ",
21ab4e
@@ -606,11 +641,12 @@ __dht_rebalance_create_dst_file (xlator_t *to, xlator_t *from, loc_t *loc, struc
21ab4e
 
21ab4e
         fd = fd_create (loc->inode, DHT_REBALANCE_PID);
21ab4e
         if (!fd) {
21ab4e
-                gf_msg (this->name, GF_LOG_ERROR, 0,
21ab4e
-                        DHT_MSG_MIGRATE_FILE_FAILED,
21ab4e
-                        "%s: fd create failed (destination) (%s)",
21ab4e
-                        loc->path, strerror (errno));
21ab4e
+                *fop_errno = ENOMEM;
21ab4e
                 ret = -1;
21ab4e
+                gf_msg (this->name, GF_LOG_ERROR, ENOMEM,
21ab4e
+                        DHT_MSG_MIGRATE_FILE_FAILED,
21ab4e
+                        "%s: fd create failed (destination)",
21ab4e
+                        loc->path);
21ab4e
                 goto out;
21ab4e
         }
21ab4e
 
21ab4e
@@ -622,6 +658,7 @@ __dht_rebalance_create_dst_file (xlator_t *to, xlator_t *from, loc_t *loc, struc
21ab4e
                                 DHT_MSG_GFID_MISMATCH,
21ab4e
                                 "file %s exists in %s with different gfid",
21ab4e
                                 loc->path, to->name);
21ab4e
+                        *fop_errno = EINVAL;
21ab4e
                         ret = -1;
21ab4e
                         goto out;
21ab4e
                 }
21ab4e
@@ -632,6 +669,7 @@ __dht_rebalance_create_dst_file (xlator_t *to, xlator_t *from, loc_t *loc, struc
21ab4e
                         DHT_MSG_MIGRATE_FILE_FAILED,
21ab4e
                         "%s: failed to lookup file (%s)",
21ab4e
                         loc->path, strerror (-ret));
21ab4e
+                *fop_errno = -ret;
21ab4e
                 ret = -1;
21ab4e
                 goto out;
21ab4e
         }
21ab4e
@@ -648,6 +686,7 @@ __dht_rebalance_create_dst_file (xlator_t *to, xlator_t *from, loc_t *loc, struc
21ab4e
                                 DHT_MSG_MIGRATE_FILE_FAILED,
21ab4e
                                 "failed to open %s on %s",
21ab4e
                                 loc->path, to->name);
21ab4e
+                        *fop_errno = -ret;
21ab4e
                         ret = -1;
21ab4e
                         goto out;
21ab4e
                  }
21ab4e
@@ -659,6 +698,7 @@ __dht_rebalance_create_dst_file (xlator_t *to, xlator_t *from, loc_t *loc, struc
21ab4e
                                 DHT_MSG_MIGRATE_FILE_FAILED,
21ab4e
                                 "failed to create %s on %s",
21ab4e
                                 loc->path, to->name);
21ab4e
+                        *fop_errno = -ret;
21ab4e
                         ret = -1;
21ab4e
                         goto out;
21ab4e
                 }
21ab4e
@@ -686,6 +726,7 @@ __dht_rebalance_create_dst_file (xlator_t *to, xlator_t *from, loc_t *loc, struc
21ab4e
                                 "file %s exists in %s with different gfid,"
21ab4e
                                 "found in lookup after create",
21ab4e
                                 loc->path, to->name);
21ab4e
+                        *fop_errno = EINVAL;
21ab4e
                         ret = -1;
21ab4e
                         goto out;
21ab4e
                 }
21ab4e
@@ -696,23 +737,27 @@ __dht_rebalance_create_dst_file (xlator_t *to, xlator_t *from, loc_t *loc, struc
21ab4e
                 gf_msg (this->name, GF_LOG_ERROR, 0,
21ab4e
                         DHT_MSG_MIGRATE_FILE_FAILED, "%s: file does not exists"
21ab4e
                         "on %s (%s)", loc->path, to->name, strerror (-ret));
21ab4e
+                *fop_errno = -ret;
21ab4e
                 ret = -1;
21ab4e
                 goto out;
21ab4e
         }
21ab4e
 
21ab4e
         ret = syncop_fsetxattr (to, fd, xattr, 0, NULL, NULL);
21ab4e
-        if (ret < 0)
21ab4e
+        if (ret < 0) {
21ab4e
+                *fop_errno = -ret;
21ab4e
                 gf_msg (this->name, GF_LOG_WARNING, 0,
21ab4e
                         DHT_MSG_MIGRATE_FILE_FAILED,
21ab4e
                         "%s: failed to set xattr on %s (%s)",
21ab4e
                         loc->path, to->name, strerror (-ret));
21ab4e
 
21ab4e
+        }
21ab4e
 
21ab4e
         /* TODO: Need to add a detailed comment about why we moved away from
21ab4e
         ftruncate.
21ab4e
 
21ab4e
         ret = syncop_ftruncate (to, fd, stbuf->ia_size, NULL, NULL);
21ab4e
-        if (ret < 0)
21ab4e
+        if (ret < 0) {
21ab4e
+                *fop_errno = -ret;
21ab4e
                 gf_msg (this->name, GF_LOG_ERROR, 0,
21ab4e
                         DHT_MSG_MIGRATE_FILE_FAILED,
21ab4e
                         "ftruncate failed for %s on %s (%s)",
21ab4e
@@ -722,11 +767,13 @@ __dht_rebalance_create_dst_file (xlator_t *to, xlator_t *from, loc_t *loc, struc
21ab4e
         ret = syncop_fsetattr (to, fd, stbuf,
21ab4e
                                (GF_SET_ATTR_UID | GF_SET_ATTR_GID),
21ab4e
                                 NULL, NULL, NULL, NULL);
21ab4e
-        if (ret < 0)
21ab4e
+        if (ret < 0) {
21ab4e
+                *fop_errno = -ret;
21ab4e
                 gf_msg (this->name, GF_LOG_ERROR, 0,
21ab4e
                         DHT_MSG_MIGRATE_FILE_FAILED,
21ab4e
                         "chown failed for %s on %s (%s)",
21ab4e
                         loc->path, to->name, strerror (-ret));
21ab4e
+        }
21ab4e
 
21ab4e
         /* Fallocate does not work for size 0, hence the check. Anyway we don't
21ab4e
          * need to care about min-free-disk for 0 byte size file */
21ab4e
@@ -762,15 +809,14 @@ out:
21ab4e
 }
21ab4e
 
21ab4e
 static int
21ab4e
-__dht_check_free_space (xlator_t *to, xlator_t *from, loc_t *loc,
21ab4e
+__dht_check_free_space (xlator_t *this, xlator_t *to, xlator_t *from, loc_t *loc,
21ab4e
                         struct iatt *stbuf, int flag, dht_conf_t *conf,
21ab4e
                         gf_boolean_t *target_changed, xlator_t **new_subvol,
21ab4e
-                        gf_boolean_t *ignore_failure)
21ab4e
+                        gf_boolean_t *ignore_failure,  int *fop_errno)
21ab4e
 {
21ab4e
         struct statvfs  src_statfs = {0,};
21ab4e
         struct statvfs  dst_statfs = {0,};
21ab4e
         int             ret        = -1;
21ab4e
-        xlator_t       *this       = NULL;
21ab4e
         dict_t         *xdata      = NULL;
21ab4e
         dht_layout_t   *layout     = NULL;
21ab4e
         uint64_t        src_statfs_blocks = 1;
21ab4e
@@ -779,11 +825,10 @@ __dht_check_free_space (xlator_t *to, xlator_t *from, loc_t *loc,
21ab4e
         double   post_percent = 0;
21ab4e
         int             i = 0;
21ab4e
 
21ab4e
-        this = THIS;
21ab4e
-
21ab4e
         xdata = dict_new ();
21ab4e
         if (!xdata) {
21ab4e
-                errno = ENOMEM;
21ab4e
+                *fop_errno = ENOMEM;
21ab4e
+                ret = -1;
21ab4e
                 gf_msg (this->name, GF_LOG_ERROR, ENOMEM,
21ab4e
                         DHT_MSG_NO_MEMORY,
21ab4e
                         "failed to allocate dictionary");
21ab4e
@@ -796,6 +841,7 @@ __dht_check_free_space (xlator_t *to, xlator_t *from, loc_t *loc,
21ab4e
                         "Failed to set "
21ab4e
                         GF_INTERNAL_IGNORE_DEEM_STATFS" in dict");
21ab4e
                 ret = -1;
21ab4e
+                *fop_errno = ENOMEM;
21ab4e
                 goto out;
21ab4e
         }
21ab4e
 
21ab4e
@@ -805,6 +851,7 @@ __dht_check_free_space (xlator_t *to, xlator_t *from, loc_t *loc,
21ab4e
                         DHT_MSG_MIGRATE_FILE_FAILED,
21ab4e
                         "failed to get statfs of %s on %s (%s)",
21ab4e
                         loc->path, from->name, strerror (-ret));
21ab4e
+                *fop_errno = -ret;
21ab4e
                 ret = -1;
21ab4e
                 goto out;
21ab4e
         }
21ab4e
@@ -815,6 +862,7 @@ __dht_check_free_space (xlator_t *to, xlator_t *from, loc_t *loc,
21ab4e
                         DHT_MSG_MIGRATE_FILE_FAILED,
21ab4e
                         "failed to get statfs of %s on %s (%s)",
21ab4e
                         loc->path, to->name, strerror (-ret));
21ab4e
+                *fop_errno = -ret;
21ab4e
                 ret = -1;
21ab4e
                 goto out;
21ab4e
         }
21ab4e
@@ -857,6 +905,7 @@ __dht_check_free_space (xlator_t *to, xlator_t *from, loc_t *loc,
21ab4e
 
21ab4e
                         /* this is not a 'failure', but we don't want to
21ab4e
                            consider this as 'success' too :-/ */
21ab4e
+                        *fop_errno = ENOSPC;
21ab4e
                         ret = -1;
21ab4e
                         goto out;
21ab4e
                 }
21ab4e
@@ -898,6 +947,7 @@ find_new_subvol:
21ab4e
         layout = dht_layout_get (this, loc->parent);
21ab4e
         if (!layout) {
21ab4e
                 gf_log (this->name, GF_LOG_ERROR, "Layout is NULL");
21ab4e
+                *fop_errno = EINVAL;
21ab4e
                 ret = -1;
21ab4e
                 goto out;
21ab4e
         }
21ab4e
@@ -925,6 +975,7 @@ find_new_subvol:
21ab4e
                 }
21ab4e
 
21ab4e
                 *target_changed = _gf_false;
21ab4e
+                *fop_errno = ENOSPC;
21ab4e
                 ret = -1;
21ab4e
                 goto out;
21ab4e
         } else {
21ab4e
@@ -944,7 +995,7 @@ out:
21ab4e
 
21ab4e
 static int
21ab4e
 __dht_rebalance_migrate_data (xlator_t *from, xlator_t *to, fd_t *src, fd_t *dst,
21ab4e
-                              uint64_t ia_size, int hole_exists)
21ab4e
+                              uint64_t ia_size, int hole_exists, int *fop_errno)
21ab4e
 {
21ab4e
         int            ret    = 0;
21ab4e
         int            count  = 0;
21ab4e
@@ -963,18 +1014,26 @@ __dht_rebalance_migrate_data (xlator_t *from, xlator_t *to, fd_t *src, fd_t *dst
21ab4e
                                     offset, 0, &vector, &count, &iobref, NULL,
21ab4e
                                     NULL);
21ab4e
                 if (!ret || (ret < 0)) {
21ab4e
+                        *fop_errno = -ret;
21ab4e
                         break;
21ab4e
                 }
21ab4e
 
21ab4e
-                if (hole_exists)
21ab4e
+                if (hole_exists) {
21ab4e
                         ret = dht_write_with_holes (to, dst, vector, count,
21ab4e
-                                                    ret, offset, iobref);
21ab4e
-                else
21ab4e
+                                                    ret, offset, iobref,
21ab4e
+                                                    fop_errno);
21ab4e
+                } else {
21ab4e
                         ret = syncop_writev (to, dst, vector, count,
21ab4e
                                              offset, iobref, 0, NULL, NULL);
21ab4e
+                        if (ret < 0) {
21ab4e
+                                *fop_errno = -ret;
21ab4e
+                        }
21ab4e
+                }
21ab4e
+
21ab4e
                 if (ret < 0) {
21ab4e
                         break;
21ab4e
                 }
21ab4e
+
21ab4e
                 offset += ret;
21ab4e
                 total += ret;
21ab4e
 
21ab4e
@@ -998,7 +1057,7 @@ __dht_rebalance_migrate_data (xlator_t *from, xlator_t *to, fd_t *src, fd_t *dst
21ab4e
 
21ab4e
 static int
21ab4e
 __tier_migrate_data (gf_defrag_info_t *defrag, xlator_t *from, xlator_t *to, fd_t *src, fd_t *dst,
21ab4e
-                     uint64_t ia_size, int hole_exists)
21ab4e
+                     uint64_t ia_size, int hole_exists, int *fop_errno)
21ab4e
 {
21ab4e
         int            ret    = 0;
21ab4e
         int            count  = 0;
21ab4e
@@ -1018,15 +1077,20 @@ __tier_migrate_data (gf_defrag_info_t *defrag, xlator_t *from, xlator_t *to, fd_
21ab4e
                                     offset, 0, &vector, &count, &iobref, NULL,
21ab4e
                                     NULL);
21ab4e
                 if (!ret || (ret < 0)) {
21ab4e
+                        *fop_errno = -ret;
21ab4e
                         break;
21ab4e
                 }
21ab4e
 
21ab4e
-                if (hole_exists)
21ab4e
+                if (hole_exists) {
21ab4e
                         ret = dht_write_with_holes (to, dst, vector, count,
21ab4e
-                                                    ret, offset, iobref);
21ab4e
-                else
21ab4e
+                                                    ret, offset, iobref,
21ab4e
+                                                    fop_errno);
21ab4e
+                } else {
21ab4e
                         ret = syncop_writev (to, dst, vector, count,
21ab4e
                                              offset, iobref, 0, NULL, NULL);
21ab4e
+                        *fop_errno = -ret;
21ab4e
+                }
21ab4e
+
21ab4e
                 if (gf_defrag_get_pause_state (&defrag->tier_conf) != TIER_RUNNING) {
21ab4e
                         gf_msg ("tier", GF_LOG_INFO, 0,
21ab4e
                                 DHT_MSG_TIER_PAUSED,
21ab4e
@@ -1060,18 +1124,17 @@ __tier_migrate_data (gf_defrag_info_t *defrag, xlator_t *from, xlator_t *to, fd_
21ab4e
 
21ab4e
 
21ab4e
 static int
21ab4e
-__dht_rebalance_open_src_file (xlator_t *from, xlator_t *to, loc_t *loc,
21ab4e
+__dht_rebalance_open_src_file (xlator_t *this, xlator_t *from, xlator_t *to, loc_t *loc,
21ab4e
                                struct iatt *stbuf, fd_t **src_fd,
21ab4e
-                               gf_boolean_t *clean_src)
21ab4e
+                               gf_boolean_t *clean_src, int *fop_errno)
21ab4e
 {
21ab4e
+
21ab4e
         int          ret  = 0;
21ab4e
         fd_t        *fd   = NULL;
21ab4e
         dict_t      *dict = NULL;
21ab4e
-        xlator_t    *this = NULL;
21ab4e
         struct iatt  iatt = {0,};
21ab4e
         dht_conf_t  *conf = NULL;
21ab4e
 
21ab4e
-        this = THIS;
21ab4e
         conf = this->private;
21ab4e
 
21ab4e
         *clean_src = _gf_false;
21ab4e
@@ -1081,6 +1144,7 @@ __dht_rebalance_open_src_file (xlator_t *from, xlator_t *to, loc_t *loc,
21ab4e
                 gf_msg (this->name, GF_LOG_ERROR, 0,
21ab4e
                         DHT_MSG_MIGRATE_FILE_FAILED,
21ab4e
                         "%s: fd create failed (source)", loc->path);
21ab4e
+                *fop_errno = ENOMEM;
21ab4e
                 ret = -1;
21ab4e
                 goto out;
21ab4e
         }
21ab4e
@@ -1091,6 +1155,7 @@ __dht_rebalance_open_src_file (xlator_t *from, xlator_t *to, loc_t *loc,
21ab4e
                         DHT_MSG_MIGRATE_FILE_FAILED,
21ab4e
                         "failed to open file %s on %s (%s)",
21ab4e
                         loc->path, from->name, strerror (-ret));
21ab4e
+                *fop_errno = -ret;
21ab4e
                 ret = -1;
21ab4e
                 goto out;
21ab4e
         }
21ab4e
@@ -1102,14 +1167,22 @@ __dht_rebalance_open_src_file (xlator_t *from, xlator_t *to, loc_t *loc,
21ab4e
 
21ab4e
         ret = -1;
21ab4e
         dict = dict_new ();
21ab4e
-        if (!dict)
21ab4e
+        if (!dict) {
21ab4e
+                gf_msg (this->name, GF_LOG_ERROR, 0,
21ab4e
+                        DHT_MSG_MIGRATE_FILE_FAILED,
21ab4e
+                        "%s: Could not allocate memory for dict", loc->path);
21ab4e
+                *fop_errno = ENOMEM;
21ab4e
+                ret = -1;
21ab4e
                 goto out;
21ab4e
+        }
21ab4e
 
21ab4e
         ret = dict_set_str (dict, conf->link_xattr_name, to->name);
21ab4e
         if (ret) {
21ab4e
                 gf_log (this->name, GF_LOG_ERROR,
21ab4e
                         "failed to set xattr in dict for %s (linkto:%s)",
21ab4e
                         loc->path, to->name);
21ab4e
+                *fop_errno = ENOMEM;
21ab4e
+                ret = -1;
21ab4e
                 goto out;
21ab4e
         }
21ab4e
 
21ab4e
@@ -1121,6 +1194,7 @@ __dht_rebalance_open_src_file (xlator_t *from, xlator_t *to, loc_t *loc,
21ab4e
                         DHT_MSG_MIGRATE_FILE_FAILED,
21ab4e
                         "failed to set xattr on %s in %s (%s)",
21ab4e
                         loc->path, from->name, strerror (-ret));
21ab4e
+                *fop_errno = -ret;
21ab4e
                 ret = -1;
21ab4e
                 goto out;
21ab4e
         }
21ab4e
@@ -1141,6 +1215,7 @@ __dht_rebalance_open_src_file (xlator_t *from, xlator_t *to, loc_t *loc,
21ab4e
                         DHT_MSG_MIGRATE_FILE_FAILED,
21ab4e
                         "failed to set mode on %s in %s (%s)",
21ab4e
                         loc->path, from->name, strerror (-ret));
21ab4e
+                *fop_errno = -ret;
21ab4e
                 ret = -1;
21ab4e
                 goto out;
21ab4e
         }
21ab4e
@@ -1156,7 +1231,7 @@ out:
21ab4e
 
21ab4e
 int
21ab4e
 migrate_special_files (xlator_t *this, xlator_t *from, xlator_t *to, loc_t *loc,
21ab4e
-                       struct iatt *buf)
21ab4e
+                       struct iatt *buf, int *fop_errno)
21ab4e
 {
21ab4e
         int          ret      = -1;
21ab4e
         dict_t      *rsp_dict = NULL;
21ab4e
@@ -1166,11 +1241,15 @@ migrate_special_files (xlator_t *this, xlator_t *from, xlator_t *to, loc_t *loc,
21ab4e
         dht_conf_t  *conf     = this->private;
21ab4e
 
21ab4e
         dict = dict_new ();
21ab4e
-        if (!dict)
21ab4e
+        if (!dict) {
21ab4e
+                *fop_errno = ENOMEM;
21ab4e
+                ret = -1;
21ab4e
                 goto out;
21ab4e
-
21ab4e
+        }
21ab4e
         ret = dict_set_int32 (dict, conf->link_xattr_name, 256);
21ab4e
         if (ret) {
21ab4e
+                *fop_errno = ENOMEM;
21ab4e
+                ret = -1;
21ab4e
                 gf_log (this->name, GF_LOG_ERROR,
21ab4e
                         "%s: failed to set 'linkto' key in dict", loc->path);
21ab4e
                 goto out;
21ab4e
@@ -1183,6 +1262,7 @@ migrate_special_files (xlator_t *this, xlator_t *from, xlator_t *to, loc_t *loc,
21ab4e
                         DHT_MSG_MIGRATE_FILE_FAILED,
21ab4e
                         "%s: lookup failed (%s)",
21ab4e
                         loc->path, strerror (-ret));
21ab4e
+                *fop_errno = -ret;
21ab4e
                 ret = -1;
21ab4e
                 goto out;
21ab4e
         }
21ab4e
@@ -1198,6 +1278,7 @@ migrate_special_files (xlator_t *this, xlator_t *from, xlator_t *to, loc_t *loc,
21ab4e
                         gf_msg (this->name, GF_LOG_WARNING, 0,
21ab4e
                                 DHT_MSG_MIGRATE_FILE_FAILED,
21ab4e
                                 "%s: file exists in destination", loc->path);
21ab4e
+                        *fop_errno = EINVAL;
21ab4e
                         ret = -1;
21ab4e
                         goto out;
21ab4e
                 }
21ab4e
@@ -1209,6 +1290,7 @@ migrate_special_files (xlator_t *this, xlator_t *from, xlator_t *to, loc_t *loc,
21ab4e
                                 DHT_MSG_MIGRATE_FILE_FAILED,
21ab4e
                                 "%s: failed to delete the linkfile (%s)",
21ab4e
                                 loc->path, strerror (-ret));
21ab4e
+                        *fop_errno = -ret;
21ab4e
                         ret = -1;
21ab4e
                         goto out;
21ab4e
                 }
21ab4e
@@ -1217,6 +1299,8 @@ migrate_special_files (xlator_t *this, xlator_t *from, xlator_t *to, loc_t *loc,
21ab4e
         /* Set the gfid of the source file in dict */
21ab4e
         ret = dict_set_static_bin (dict, "gfid-req", buf->ia_gfid, 16);
21ab4e
         if (ret) {
21ab4e
+                *fop_errno = ENOMEM;
21ab4e
+                ret = -1;
21ab4e
                 gf_log (this->name, GF_LOG_ERROR,
21ab4e
                         "%s: failed to set gfid in dict for create", loc->path);
21ab4e
                 goto out;
21ab4e
@@ -1232,6 +1316,7 @@ migrate_special_files (xlator_t *this, xlator_t *from, xlator_t *to, loc_t *loc,
21ab4e
                                 DHT_MSG_MIGRATE_FILE_FAILED,
21ab4e
                                 "%s: readlink on symlink failed (%s)",
21ab4e
                                 loc->path, strerror (-ret));
21ab4e
+                        *fop_errno = -ret;
21ab4e
                         ret = -1;
21ab4e
                         goto out;
21ab4e
                 }
21ab4e
@@ -1242,6 +1327,7 @@ migrate_special_files (xlator_t *this, xlator_t *from, xlator_t *to, loc_t *loc,
21ab4e
                                 DHT_MSG_MIGRATE_FILE_FAILED,
21ab4e
                                 "%s: creating symlink failed (%s)",
21ab4e
                                 loc->path, strerror (-ret));
21ab4e
+                        *fop_errno = -ret;
21ab4e
                         ret = -1;
21ab4e
                         goto out;
21ab4e
                 }
21ab4e
@@ -1258,6 +1344,7 @@ migrate_special_files (xlator_t *this, xlator_t *from, xlator_t *to, loc_t *loc,
21ab4e
                         DHT_MSG_MIGRATE_FILE_FAILED,
21ab4e
                         "%s: mknod failed (%s)",
21ab4e
                         loc->path, strerror (-ret));
21ab4e
+                *fop_errno = -ret;
21ab4e
                 ret = -1;
21ab4e
                 goto out;
21ab4e
         }
21ab4e
@@ -1272,6 +1359,7 @@ done:
21ab4e
                         DHT_MSG_MIGRATE_FILE_FAILED,
21ab4e
                         "%s: failed to perform setattr on %s (%s)",
21ab4e
                         loc->path, to->name, strerror (-ret));
21ab4e
+                *fop_errno = -ret;
21ab4e
                 ret = -1;
21ab4e
         }
21ab4e
 
21ab4e
@@ -1281,6 +1369,7 @@ done:
21ab4e
                         DHT_MSG_MIGRATE_FILE_FAILED,
21ab4e
                         "%s: unlink failed (%s)",
21ab4e
                         loc->path, strerror (-ret));
21ab4e
+                *fop_errno = -ret;
21ab4e
                 ret = -1;
21ab4e
         }
21ab4e
 
21ab4e
@@ -1369,7 +1458,7 @@ out:
21ab4e
 */
21ab4e
 int
21ab4e
 dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to,
21ab4e
-                  int flag)
21ab4e
+                  int flag, int *fop_errno)
21ab4e
 {
21ab4e
         int                     ret                     = -1;
21ab4e
         struct iatt             new_stbuf               = {0,};
21ab4e
@@ -1416,11 +1505,17 @@ dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to,
21ab4e
                 loc->path, from->name, to->name);
21ab4e
 
21ab4e
         dict = dict_new ();
21ab4e
-        if (!dict)
21ab4e
+        if (!dict) {
21ab4e
+                ret = -1;
21ab4e
+                *fop_errno = ENOMEM;
21ab4e
+                gf_msg (this->name, GF_LOG_ERROR, ENOMEM, DHT_MSG_NO_MEMORY,
21ab4e
+                        "Could not allocate memory for dict");
21ab4e
                 goto out;
21ab4e
-
21ab4e
+        }
21ab4e
         ret = dict_set_int32 (dict, conf->link_xattr_name, 256);
21ab4e
         if (ret) {
21ab4e
+                *fop_errno = ENOMEM;
21ab4e
+                ret = -1;
21ab4e
                 gf_msg (this->name, GF_LOG_ERROR, 0,
21ab4e
                         DHT_MSG_MIGRATE_FILE_FAILED,
21ab4e
                         "Migrate file failed:"
21ab4e
@@ -1435,6 +1530,8 @@ dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to,
21ab4e
                 ret = dict_set_int32 (dict,
21ab4e
                                  GLUSTERFS_POSIXLK_COUNT, sizeof(int32_t));
21ab4e
                 if (ret) {
21ab4e
+                        *fop_errno = ENOMEM;
21ab4e
+                        ret = -1;
21ab4e
                         gf_msg (this->name, GF_LOG_ERROR, 0,
21ab4e
                                 DHT_MSG_MIGRATE_FILE_FAILED,
21ab4e
                                 "Migrate file failed: %s: failed to "
21ab4e
@@ -1456,12 +1553,13 @@ dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to,
21ab4e
         ret = syncop_inodelk (from, DHT_FILE_MIGRATE_DOMAIN, &tmp_loc, F_SETLKW,
21ab4e
                               &flock, NULL, NULL);
21ab4e
         if (ret < 0) {
21ab4e
+                *fop_errno = -ret;
21ab4e
+                ret = -1;
21ab4e
                 gf_msg (this->name, GF_LOG_WARNING, 0,
21ab4e
                         DHT_MSG_MIGRATE_FILE_FAILED,
21ab4e
                         "migrate file failed: "
21ab4e
                         "%s: failed to lock file on %s (%s)",
21ab4e
-                        loc->path, from->name, strerror (-ret));
21ab4e
-                ret = -1;
21ab4e
+                        loc->path, from->name, strerror (*fop_errno));
21ab4e
                 goto out;
21ab4e
         }
21ab4e
 
21ab4e
@@ -1470,20 +1568,22 @@ dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to,
21ab4e
         /* Phase 1 - Data migration is in progress from now on */
21ab4e
         ret = syncop_lookup (from, loc, &stbuf, NULL, dict, &xattr_rsp);
21ab4e
         if (ret) {
21ab4e
+                *fop_errno = -ret;
21ab4e
+                ret = -1;
21ab4e
                 gf_msg (this->name, GF_LOG_ERROR, 0,
21ab4e
                         DHT_MSG_MIGRATE_FILE_FAILED,
21ab4e
                         "Migrate file failed:"
21ab4e
                         "%s: lookup failed on %s (%s)",
21ab4e
-                        loc->path, from->name, strerror (-ret));
21ab4e
-                ret = -1;
21ab4e
-                goto out;
21ab4e
+                        loc->path, from->name, strerror (*fop_errno));
21ab4e
+               goto out;
21ab4e
         }
21ab4e
 
21ab4e
         /* preserve source mode, so set the same to the destination */
21ab4e
         src_ia_prot = stbuf.ia_prot;
21ab4e
 
21ab4e
         /* Check if file can be migrated */
21ab4e
-        ret = __is_file_migratable (this, loc, &stbuf, xattr_rsp, flag, defrag);
21ab4e
+        ret = __is_file_migratable (this, loc, &stbuf, xattr_rsp, flag, defrag,
21ab4e
+                                    fop_errno);
21ab4e
         if (ret) {
21ab4e
                 if (ret == -2)
21ab4e
                         ret = 0;
21ab4e
@@ -1492,7 +1592,8 @@ dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to,
21ab4e
         /* Take care of the special files */
21ab4e
         if (!IA_ISREG (stbuf.ia_type)) {
21ab4e
                 /* Special files */
21ab4e
-                ret = migrate_special_files (this, from, to, loc, &stbuf);
21ab4e
+                ret = migrate_special_files (this, from, to, loc, &stbuf,
21ab4e
+                                             fop_errno);
21ab4e
                 goto out;
21ab4e
         }
21ab4e
 
21ab4e
@@ -1500,17 +1601,18 @@ dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to,
21ab4e
         /* TODO: move all xattr related operations to fd based operations */
21ab4e
         ret = syncop_listxattr (from, loc, &xattr, NULL, NULL);
21ab4e
         if (ret < 0) {
21ab4e
+                *fop_errno = -ret;
21ab4e
+                ret = -1;
21ab4e
                 gf_msg (this->name, GF_LOG_WARNING, 0,
21ab4e
                         DHT_MSG_MIGRATE_FILE_FAILED,
21ab4e
                         "Migrate file failed:"
21ab4e
                         "%s: failed to get xattr from %s (%s)",
21ab4e
-                        loc->path, from->name, strerror (-ret));
21ab4e
-                ret = -1;
21ab4e
+                        loc->path, from->name, strerror (*fop_errno));
21ab4e
         }
21ab4e
 
21ab4e
         /* create the destination, with required modes/xattr */
21ab4e
-        ret = __dht_rebalance_create_dst_file (to, from, loc, &stbuf,
21ab4e
-                                               &dst_fd, xattr);
21ab4e
+        ret = __dht_rebalance_create_dst_file (this, to, from, loc, &stbuf,
21ab4e
+                                               &dst_fd, xattr, fop_errno);
21ab4e
         if (ret) {
21ab4e
                 gf_msg (this->name, GF_LOG_ERROR, 0, 0, "Create dst failed"
21ab4e
                         " on - %s for file - %s", to->name, loc->path);
21ab4e
@@ -1519,8 +1621,8 @@ dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to,
21ab4e
 
21ab4e
         clean_dst = _gf_true;
21ab4e
 
21ab4e
-        ret = __dht_check_free_space (to, from, loc, &stbuf, flag, conf,
21ab4e
-                                      &target_changed, &new_target, &ignore_failure);
21ab4e
+        ret = __dht_check_free_space (this, to, from, loc, &stbuf, flag, conf,
21ab4e
+                                      &target_changed, &new_target, &ignore_failure, fop_errno);
21ab4e
         if (target_changed) {
21ab4e
                 /* Can't handle for hardlinks. Marking this as failure */
21ab4e
                 if (flag == GF_DHT_MIGRATE_HARDLINK_IN_PROGRESS || stbuf.ia_nlink > 1) {
21ab4e
@@ -1551,8 +1653,8 @@ dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to,
21ab4e
                  * destination. We need to do update this only post migration
21ab4e
                  * as in case of failure the linkto needs to point to the source
21ab4e
                  * subvol */
21ab4e
-                ret = __dht_rebalance_create_dst_file (to, from, loc, &stbuf,
21ab4e
-                                                       &dst_fd, xattr);
21ab4e
+                ret = __dht_rebalance_create_dst_file (this, to, from, loc, &stbuf,
21ab4e
+                                                       &dst_fd, xattr, fop_errno);
21ab4e
                 if (ret) {
21ab4e
                         gf_log (this->name, GF_LOG_ERROR, "Create dst failed"
21ab4e
                                 " on - %s for file - %s", to->name, loc->path);
21ab4e
@@ -1571,8 +1673,8 @@ dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to,
21ab4e
         }
21ab4e
 
21ab4e
         /* Open the source, and also update mode/xattr */
21ab4e
-        ret = __dht_rebalance_open_src_file (from, to, loc, &stbuf, &src_fd,
21ab4e
-                                             &clean_src);
21ab4e
+        ret = __dht_rebalance_open_src_file (this, from, to, loc, &stbuf, &src_fd,
21ab4e
+                                             &clean_src, fop_errno);
21ab4e
         if (ret) {
21ab4e
                 gf_msg (this->name, GF_LOG_ERROR, 0,
21ab4e
                         DHT_MSG_MIGRATE_FILE_FAILED,
21ab4e
@@ -1593,13 +1695,14 @@ dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to,
21ab4e
                         DHT_MSG_MIGRATE_FILE_FAILED,
21ab4e
                         "Migrate file failed:failed to lookup %s on %s ",
21ab4e
                         loc->path, from->name);
21ab4e
+                *fop_errno = -ret;
21ab4e
                 ret = -1;
21ab4e
                 goto out;
21ab4e
         }
21ab4e
 
21ab4e
         /* Check again if file has hardlink */
21ab4e
         ret = __check_file_has_hardlink (this, loc, &stbuf, xattr_rsp,
21ab4e
-                                         flag, defrag);
21ab4e
+                                         flag, defrag, fop_errno);
21ab4e
         if (ret) {
21ab4e
                 if (ret == -2)
21ab4e
                         ret = 0;
21ab4e
@@ -1614,10 +1717,12 @@ dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to,
21ab4e
         /* All I/O happens in this function */
21ab4e
         if (defrag->cmd == GF_DEFRAG_CMD_START_TIER) {
21ab4e
                 ret = __tier_migrate_data (defrag, from, to, src_fd, dst_fd,
21ab4e
-                                                    stbuf.ia_size, file_has_holes);
21ab4e
+                                                    stbuf.ia_size,
21ab4e
+                                                    file_has_holes, fop_errno);
21ab4e
         } else {
21ab4e
                 ret = __dht_rebalance_migrate_data (from, to, src_fd, dst_fd,
21ab4e
-                                                    stbuf.ia_size, file_has_holes);
21ab4e
+                                                    stbuf.ia_size,
21ab4e
+                                                    file_has_holes, fop_errno);
21ab4e
         }
21ab4e
 
21ab4e
         if (ret) {
21ab4e
@@ -1637,6 +1742,7 @@ dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to,
21ab4e
                 gf_log (this->name, GF_LOG_WARNING,
21ab4e
                         "%s: failed to fsync on %s (%s)",
21ab4e
                         loc->path, to->name, strerror (-ret));
21ab4e
+                *fop_errno = -ret;
21ab4e
                 ret = -1;
21ab4e
         }
21ab4e
 
21ab4e
@@ -1650,6 +1756,7 @@ dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to,
21ab4e
                         DHT_MSG_MIGRATE_FILE_FAILED,
21ab4e
                         "Migrate file failed: failed to fstat file %s on %s ",
21ab4e
                         loc->path, from->name);
21ab4e
+                *fop_errno = -ret;
21ab4e
                 ret = -1;
21ab4e
                 goto out;
21ab4e
         }
21ab4e
@@ -1672,8 +1779,9 @@ dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to,
21ab4e
                 if (!meta_dict) {
21ab4e
                         gf_msg (this->name, GF_LOG_ERROR, 0,
21ab4e
                                 DHT_MSG_MIGRATE_FILE_FAILED,
21ab4e
-                                "Trace dict_new failed");
21ab4e
+                                "dict_new failed");
21ab4e
 
21ab4e
+                        *fop_errno = ENOMEM;
21ab4e
                         ret = -1;
21ab4e
                         goto out;
21ab4e
                 }
21ab4e
@@ -1685,6 +1793,7 @@ dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to,
21ab4e
                                 "Failed to set dictionary value: key = %s,"
21ab4e
                                 " path = %s", GLUSTERFS_INTERNAL_FOP_KEY,
21ab4e
                                  loc->path);
21ab4e
+                        *fop_errno = ENOMEM;
21ab4e
                         ret = -1;
21ab4e
                         goto out;
21ab4e
                 }
21ab4e
@@ -1694,7 +1803,7 @@ dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to,
21ab4e
                         gf_msg (this->name, GF_LOG_ERROR, 0,
21ab4e
                                 DHT_MSG_MIGRATE_FILE_FAILED,
21ab4e
                                 "Trace dict_set failed");
21ab4e
-
21ab4e
+                        *fop_errno = ENOMEM;
21ab4e
                         ret = -1;
21ab4e
                         goto out;
21ab4e
                 }
21ab4e
@@ -1705,6 +1814,7 @@ dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to,
21ab4e
                                 DHT_MSG_MIGRATE_FILE_FAILED,
21ab4e
                                 "Trace syncop_setxattr metalock failed");
21ab4e
 
21ab4e
+                        *fop_errno = -ret;
21ab4e
                         ret = -1;
21ab4e
                         goto out;
21ab4e
                 } else {
21ab4e
@@ -1725,6 +1835,7 @@ dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to,
21ab4e
                                 "Migrate file failed:"
21ab4e
                                 "%s: Failed to lock on %s",
21ab4e
                                 loc->path, from->name);
21ab4e
+                        *fop_errno = -ret;
21ab4e
                         ret = -1;
21ab4e
                         goto out;
21ab4e
                 }
21ab4e
@@ -1749,6 +1860,7 @@ dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to,
21ab4e
                                         DHT_MSG_LOCK_MIGRATION_FAILED,
21ab4e
                                         "write lock failed on:%s", loc->path);
21ab4e
 
21ab4e
+                                *fop_errno = -ret;
21ab4e
                                 ret = -1;
21ab4e
                                 goto metaunlock;
21ab4e
                         }
21ab4e
@@ -1756,6 +1868,7 @@ dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to,
21ab4e
                         gf_msg (this->name, GF_LOG_ERROR, 0,
21ab4e
                                 DHT_MSG_LOCK_MIGRATION_FAILED,
21ab4e
                                 "getactivelk failed for file: %s", loc->path);
21ab4e
+                        *fop_errno = -ret;
21ab4e
                 }
21ab4e
         }
21ab4e
 
21ab4e
@@ -1781,6 +1894,7 @@ dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to,
21ab4e
                         "Migrate file failed:"
21ab4e
                         "%s: failed to perform setattr on %s ",
21ab4e
                         loc->path, to->name);
21ab4e
+                *fop_errno = -ret;
21ab4e
                 ret = -1;
21ab4e
                 goto metaunlock;
21ab4e
         }
21ab4e
@@ -1793,6 +1907,7 @@ dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to,
21ab4e
                 gf_log (this->name, GF_LOG_WARNING,
21ab4e
                         "%s: failed to perform setattr on %s ",
21ab4e
                         loc->path, to->name);
21ab4e
+                *fop_errno = -ret;
21ab4e
                 ret = -1;
21ab4e
         }
21ab4e
 
21ab4e
@@ -1800,6 +1915,7 @@ dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to,
21ab4e
                if (!dict) {
21ab4e
                         dict = dict_new ();
21ab4e
                         if (!dict) {
21ab4e
+                                *fop_errno = ENOMEM;
21ab4e
                                 ret = -1;
21ab4e
                                 goto out;
21ab4e
                         }
21ab4e
@@ -1811,6 +1927,7 @@ dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to,
21ab4e
                                 gf_log (this->name, GF_LOG_ERROR,
21ab4e
                                         "failed to set xattr in dict for %s (linkto:%s)",
21ab4e
                                         loc->path, to->name);
21ab4e
+                                *fop_errno = ENOMEM;
21ab4e
                                 ret = -1;
21ab4e
                                 goto out;
21ab4e
                         }
21ab4e
@@ -1821,6 +1938,7 @@ dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to,
21ab4e
                                         DHT_MSG_MIGRATE_FILE_FAILED,
21ab4e
                                         "failed to set xattr on %s in %s (%s)",
21ab4e
                                         loc->path, old_target->name, strerror (-ret));
21ab4e
+                                *fop_errno = -ret;
21ab4e
                                 ret = -1;
21ab4e
                                 goto out;
21ab4e
                         } else if (-ret == ESTALE || -ret == ENOENT) {
21ab4e
@@ -1834,6 +1952,7 @@ dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to,
21ab4e
                                                 DHT_MSG_MIGRATE_FILE_FAILED,
21ab4e
                                                 "%s: fd create failed (%s)",
21ab4e
                                                 loc->path, strerror (errno));
21ab4e
+                                        *fop_errno = ENOMEM;
21ab4e
                                         ret = -1;
21ab4e
                                         goto out;
21ab4e
                                 }
21ab4e
@@ -1841,6 +1960,7 @@ dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to,
21ab4e
                                                      DHT_LINKFILE_MODE, linkto_fd,
21ab4e
                                                      NULL, dict, NULL);
21ab4e
                                 if (ret != 0 && -ret != EEXIST && -ret != ESTALE) {
21ab4e
+                                        *fop_errno = -ret;
21ab4e
                                         ret = -1;
21ab4e
                                         gf_msg (this->name, GF_LOG_ERROR, 0,
21ab4e
                                                 DHT_MSG_MIGRATE_FILE_FAILED,
21ab4e
@@ -1852,6 +1972,7 @@ dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to,
21ab4e
                                                                (GF_SET_ATTR_UID | GF_SET_ATTR_GID),
21ab4e
                                                                NULL, NULL, NULL, NULL);
21ab4e
                                         if (ret < 0)
21ab4e
+                                                *fop_errno = -ret;
21ab4e
                                                 gf_msg (this->name, GF_LOG_ERROR, 0,
21ab4e
                                                 DHT_MSG_MIGRATE_FILE_FAILED,
21ab4e
                                                 "chown failed for %s on %s (%s)",
21ab4e
@@ -1880,6 +2001,7 @@ dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to,
21ab4e
                         "Migrate file failed:"
21ab4e
                         "%s: failed to get xattr from %s (%s)",
21ab4e
                         loc->path, from->name, strerror (-ret));
21ab4e
+                *fop_errno = -ret;
21ab4e
                 ret = -1;
21ab4e
         } else {
21ab4e
                 ret = syncop_setxattr (to, loc, xattr, 0, NULL, NULL);
21ab4e
@@ -1892,6 +2014,7 @@ dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to,
21ab4e
                                 "Migrate file failed:"
21ab4e
                                 "%s: failed to set xattr on %s (%s)",
21ab4e
                                 loc->path, to->name, strerror (-ret));
21ab4e
+                        *fop_errno = -ret;
21ab4e
                         ret = -1;
21ab4e
                 }
21ab4e
         }
21ab4e
@@ -1921,6 +2044,7 @@ dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to,
21ab4e
                         "Migrate file failed:"
21ab4e
                         "%s: failed to perform setattr on %s ",
21ab4e
                         loc->path, from->name);
21ab4e
+                *fop_errno = -ret;
21ab4e
                 ret = -1;
21ab4e
                 goto metaunlock;
21ab4e
         }
21ab4e
@@ -1932,6 +2056,7 @@ dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to,
21ab4e
                 gf_log (this->name, GF_LOG_WARNING,
21ab4e
                         "%s: failed to perform truncate on %s (%s)",
21ab4e
                         loc->path, from->name, strerror (-ret));
21ab4e
+                *fop_errno = -ret;
21ab4e
                 ret = -1;
21ab4e
         }
21ab4e
 
21ab4e
@@ -1941,6 +2066,7 @@ dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to,
21ab4e
                 gf_log (this->name, GF_LOG_WARNING,
21ab4e
                         "%s: failed to perform removexattr on %s (%s)",
21ab4e
                         loc->path, to->name, strerror (-ret));
21ab4e
+                *fop_errno = -ret;
21ab4e
                 ret = -1;
21ab4e
         }
21ab4e
 
21ab4e
@@ -1962,6 +2088,7 @@ dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to,
21ab4e
                         loc->path, from->name, strerror (-ret));
21ab4e
 
21ab4e
                 if (-ret != ENOENT) {
21ab4e
+                        *fop_errno = -ret;
21ab4e
                         ret = -1;
21ab4e
                         goto metaunlock;
21ab4e
                 }
21ab4e
@@ -1979,6 +2106,7 @@ dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to,
21ab4e
                                 DHT_MSG_MIGRATE_FILE_FAILED,
21ab4e
                                 "%s: failed to perform unlink on %s (%s)",
21ab4e
                                 loc->path, from->name, strerror (-ret));
21ab4e
+                        *fop_errno = -ret;
21ab4e
                         ret = -1;
21ab4e
                         goto metaunlock;
21ab4e
                 }
21ab4e
@@ -1989,6 +2117,7 @@ dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to,
21ab4e
                 gf_msg_debug (this->name, 0,
21ab4e
                               "%s: failed to lookup the file on subvolumes (%s)",
21ab4e
                               loc->path, strerror (-ret));
21ab4e
+                *fop_errno = -ret;
21ab4e
                 ret = -1;
21ab4e
         }
21ab4e
 
21ab4e
@@ -2011,6 +2140,7 @@ metaunlock:
21ab4e
                                 DHT_MSG_MIGRATE_FILE_FAILED,
21ab4e
                                 "Trace dict_set failed");
21ab4e
 
21ab4e
+                        *fop_errno = ENOMEM;
21ab4e
                         ret = -1;
21ab4e
                         goto out;
21ab4e
                 }
21ab4e
@@ -2025,6 +2155,7 @@ metaunlock:
21ab4e
                                 DHT_MSG_MIGRATE_FILE_FAILED,
21ab4e
                                 "Trace dict_set failed");
21ab4e
 
21ab4e
+                        *fop_errno = ENOMEM;
21ab4e
                         ret = -1;
21ab4e
                         goto out;
21ab4e
                 }
21ab4e
@@ -2035,6 +2166,7 @@ metaunlock:
21ab4e
                                 DHT_MSG_MIGRATE_FILE_FAILED,
21ab4e
                                 "Trace syncop_setxattr meta unlock failed");
21ab4e
 
21ab4e
+                        *fop_errno = -ret;
21ab4e
                         ret = -1;
21ab4e
                         goto out;
21ab4e
                 }
21ab4e
@@ -2116,6 +2248,7 @@ rebalance_task (void *data)
21ab4e
         int           ret   = -1;
21ab4e
         dht_local_t  *local = NULL;
21ab4e
         call_frame_t *frame = NULL;
21ab4e
+        int           fop_errno = 0;
21ab4e
 
21ab4e
         frame = data;
21ab4e
 
21ab4e
@@ -2124,7 +2257,8 @@ rebalance_task (void *data)
21ab4e
         /* This function is 'synchrounous', hence if it returns,
21ab4e
            we are done with the task */
21ab4e
         ret = dht_migrate_file (THIS, &local->loc, local->rebalance.from_subvol,
21ab4e
-                                local->rebalance.target_node, local->flags);
21ab4e
+                                local->rebalance.target_node, local->flags,
21ab4e
+                                &fop_errno);
21ab4e
 
21ab4e
         return ret;
21ab4e
 }
21ab4e
@@ -2158,7 +2292,7 @@ rebalance_task_completion (int op_ret, call_frame_t *sync_frame, void *data)
21ab4e
 int
21ab4e
 dht_start_rebalance_task (xlator_t *this, call_frame_t *frame)
21ab4e
 {
21ab4e
-        int         ret     = -1;
21ab4e
+        int           ret   = -1;
21ab4e
 
21ab4e
         ret = synctask_new (this->ctx->env, rebalance_task,
21ab4e
                             rebalance_task_completion,
21ab4e
@@ -2166,6 +2300,7 @@ dht_start_rebalance_task (xlator_t *this, call_frame_t *frame)
21ab4e
         return ret;
21ab4e
 }
21ab4e
 
21ab4e
+
21ab4e
 int
21ab4e
 gf_listener_stop (xlator_t *this)
21ab4e
 {
21ab4e
@@ -2309,23 +2444,28 @@ gf_defrag_ctx_subvols_init (dht_dfoffset_ctx_t *offset_var, xlator_t *this) {
21ab4e
 int
21ab4e
 gf_defrag_migrate_single_file (void *opaque)
21ab4e
 {
21ab4e
-        xlator_t                *this = NULL;
21ab4e
-        dht_conf_t              *conf = NULL;
21ab4e
-        gf_defrag_info_t        *defrag = NULL;
21ab4e
-        int                     ret = 0;
21ab4e
+        xlator_t                *this           = NULL;
21ab4e
+        dht_conf_t              *conf           = NULL;
21ab4e
+        gf_defrag_info_t        *defrag         = NULL;
21ab4e
+        int                      ret            = 0;
21ab4e
         gf_dirent_t             *entry          = NULL;
21ab4e
         struct timeval           start          = {0,};
21ab4e
         loc_t                    entry_loc      = {0,};
21ab4e
         loc_t                   *loc            = NULL;
21ab4e
         struct iatt              iatt           = {0,};
21ab4e
         dict_t                  *migrate_data   = NULL;
21ab4e
-        int32_t                  op_errno       = 0;
21ab4e
         struct timeval           end            = {0,};
21ab4e
         double                   elapsed        = {0,};
21ab4e
         struct dht_container    *rebal_entry    = NULL;
21ab4e
         inode_t                 *inode          = NULL;
21ab4e
         call_frame_t            *statfs_frame   = NULL;
21ab4e
         xlator_t                *old_THIS       = NULL;
21ab4e
+        xlator_t                *hashed_subvol  = NULL;
21ab4e
+        xlator_t                *cached_subvol  = NULL;
21ab4e
+        data_t                  *tmp            = NULL;
21ab4e
+        int                      fop_errno      = 0;
21ab4e
+        gf_dht_migrate_data_type_t rebal_type   = GF_DHT_MIGRATE_DATA;
21ab4e
+        char                     value[MAX_REBAL_TYPE_SIZE]    = {0,};
21ab4e
 
21ab4e
         rebal_entry = (struct dht_container *)opaque;
21ab4e
         if (!rebal_entry) {
21ab4e
@@ -2388,7 +2528,33 @@ gf_defrag_migrate_single_file (void *opaque)
21ab4e
                 gf_msg (this->name, GF_LOG_ERROR, 0,
21ab4e
                         DHT_MSG_MIGRATE_FILE_FAILED,
21ab4e
                         "Migrate file failed: %s lookup failed",
21ab4e
-                        entry_loc.name);
21ab4e
+                        entry_loc.path);
21ab4e
+                ret = 0;
21ab4e
+                goto out;
21ab4e
+        }
21ab4e
+
21ab4e
+        hashed_subvol = dht_subvol_get_hashed (this, &entry_loc);
21ab4e
+        if (!hashed_subvol) {
21ab4e
+                gf_msg (this->name, GF_LOG_ERROR, 0,
21ab4e
+                        DHT_MSG_HASHED_SUBVOL_GET_FAILED,
21ab4e
+                        "Failed to get hashed subvol for %s",
21ab4e
+                        entry_loc.path);
21ab4e
+                ret = 0;
21ab4e
+                goto out;
21ab4e
+        }
21ab4e
+
21ab4e
+        cached_subvol = dht_subvol_get_cached (this, entry_loc.inode);
21ab4e
+        if (!cached_subvol) {
21ab4e
+                gf_msg (this->name, GF_LOG_ERROR, 0,
21ab4e
+                        DHT_MSG_CACHED_SUBVOL_GET_FAILED,
21ab4e
+                        "Failed to get cached subvol for %s",
21ab4e
+                        entry_loc.path);
21ab4e
+
21ab4e
+                ret = 0;
21ab4e
+                goto out;
21ab4e
+        }
21ab4e
+
21ab4e
+        if (hashed_subvol == cached_subvol) {
21ab4e
                 ret = 0;
21ab4e
                 goto out;
21ab4e
         }
21ab4e
@@ -2412,12 +2578,20 @@ gf_defrag_migrate_single_file (void *opaque)
21ab4e
         dht_get_du_info (statfs_frame, this, loc);
21ab4e
         THIS = old_THIS;
21ab4e
 
21ab4e
-        ret = syncop_setxattr (this, &entry_loc, migrate_data, 0, NULL, NULL);
21ab4e
+        tmp = dict_get (migrate_data, GF_XATTR_FILE_MIGRATE_KEY);
21ab4e
+        if (tmp) {
21ab4e
+                memcpy (value, tmp->data, tmp->len);
21ab4e
+                if (strcmp (value, "force") == 0)
21ab4e
+                        rebal_type = GF_DHT_MIGRATE_DATA_EVEN_IF_LINK_EXISTS;
21ab4e
+
21ab4e
+                if (conf->decommission_in_progress)
21ab4e
+                        rebal_type = GF_DHT_MIGRATE_HARDLINK;
21ab4e
+        }
21ab4e
+
21ab4e
+        ret = dht_migrate_file (this, &entry_loc, cached_subvol,
21ab4e
+                                hashed_subvol, rebal_type, &fop_errno);
21ab4e
         if (ret < 0) {
21ab4e
-                op_errno = -ret;
21ab4e
-                /* errno is overloaded. See
21ab4e
-                 * rebalance_task_completion () */
21ab4e
-                if (op_errno == ENOSPC) {
21ab4e
+                if (fop_errno == ENOSPC) {
21ab4e
                         gf_msg_debug (this->name, 0, "migrate-data skipped for"
21ab4e
                                       " %s due to space constraints",
21ab4e
                                       entry_loc.path);
21ab4e
@@ -2426,9 +2600,17 @@ gf_defrag_migrate_single_file (void *opaque)
21ab4e
                                 defrag->skipped += 1;
21ab4e
                         }
21ab4e
                         UNLOCK (&defrag->lock);
21ab4e
-                } else if (op_errno != EEXIST) {
21ab4e
-                        gf_msg (this->name, GF_LOG_ERROR, 0,
21ab4e
-                                DHT_MSG_MIGRATE_FILE_FAILED,
21ab4e
+                } else if (fop_errno == ENOTSUP) {
21ab4e
+                        gf_msg_debug (this->name, 0, "migrate-data skipped for"
21ab4e
+                                      " hardlink %s ", entry_loc.path);
21ab4e
+                        LOCK (&defrag->lock);
21ab4e
+                        {
21ab4e
+                                defrag->skipped += 1;
21ab4e
+                        }
21ab4e
+                        UNLOCK (&defrag->lock);
21ab4e
+                } else if (fop_errno != EEXIST) {
21ab4e
+                        gf_msg (this->name, GF_LOG_ERROR,
21ab4e
+                                DHT_MSG_MIGRATE_FILE_FAILED, fop_errno,
21ab4e
                                 "migrate-data failed for %s", entry_loc.path);
21ab4e
 
21ab4e
                         LOCK (&defrag->lock);
21ab4e
@@ -2439,29 +2621,19 @@ gf_defrag_migrate_single_file (void *opaque)
21ab4e
 
21ab4e
                 }
21ab4e
 
21ab4e
-                ret = gf_defrag_handle_migrate_error (op_errno, defrag);
21ab4e
+                ret = gf_defrag_handle_migrate_error (fop_errno, defrag);
21ab4e
 
21ab4e
                 if (!ret) {
21ab4e
                         gf_msg(this->name, GF_LOG_ERROR, 0,
21ab4e
                                DHT_MSG_MIGRATE_FILE_FAILED,
21ab4e
                                "migrate-data on %s failed: %s", entry_loc.path,
21ab4e
-                               strerror (op_errno));
21ab4e
+                               strerror (fop_errno));
21ab4e
                 } else if (ret == 1) {
21ab4e
                         ret = 0;
21ab4e
                         goto out;
21ab4e
                 } else if (ret == -1) {
21ab4e
                         goto out;
21ab4e
                 }
21ab4e
-        } else if (ret > 0) {
21ab4e
-                gf_msg (this->name, GF_LOG_ERROR, 0,
21ab4e
-                        DHT_MSG_MIGRATE_FILE_FAILED,
21ab4e
-                        "migrate-data failed for %s", entry_loc.path);
21ab4e
-                ret = 0;
21ab4e
-                LOCK (&defrag->lock);
21ab4e
-                {
21ab4e
-                        defrag->total_failures += 1;
21ab4e
-                }
21ab4e
-                UNLOCK (&defrag->lock);
21ab4e
         }
21ab4e
 
21ab4e
         LOCK (&defrag->lock);
21ab4e
@@ -2499,7 +2671,7 @@ gf_defrag_task (void *opaque)
21ab4e
         struct dht_container    *iterator       = NULL;
21ab4e
         gf_defrag_info_t        *defrag         = NULL;
21ab4e
         int                      ret            = 0;
21ab4e
-
21ab4e
+        pid_t                    pid            = GF_CLIENT_PID_DEFRAG;
21ab4e
 
21ab4e
         defrag = (gf_defrag_info_t *)opaque;
21ab4e
         if (!defrag) {
21ab4e
@@ -2507,6 +2679,8 @@ gf_defrag_task (void *opaque)
21ab4e
                 goto out;
21ab4e
         }
21ab4e
 
21ab4e
+        syncopctx_setfspid (&pid;;
21ab4e
+
21ab4e
         q_head = &(defrag->queue[0].list);
21ab4e
 
21ab4e
        /* The following while loop will dequeue one entry from the defrag->queue
21ab4e
-- 
21ab4e
1.8.3.1
21ab4e