From 290999db11feedb3021022edfaabef516bf5f6e6 Mon Sep 17 00:00:00 2001 From: Mohit Agrawal Date: Tue, 29 Nov 2016 11:04:06 +0530 Subject: 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 > (cherry picked from commit 4b8ccbed28837bd78894cb5ce3cf15bc8f364a93) BUG: 1399430 Change-Id: Idc869f2cf2355dacf54c36008840092b8e77acb9 Signed-off-by: Mohit Agrawal Reviewed-on: http://review.gluster.org/15955 Smoke: Gluster Build System NetBSD-regression: NetBSD Build System CentOS-regression: Gluster Build System Reviewed-by: Raghavendra G --- xlators/cluster/dht/src/dht-rebalance.c | 92 ++++++++++++++++++++++----------- 1 file changed, 62 insertions(+), 30 deletions(-) (limited to 'xlators') diff --git a/xlators/cluster/dht/src/dht-rebalance.c b/xlators/cluster/dht/src/dht-rebalance.c index 32814cd9035..049db08f9ec 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 @@ -517,35 +561,9 @@ __is_file_migratable (xlator_t *this, loc_t *loc, 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; @@ -1425,8 +1443,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 +1459,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; -- cgit