diff options
author | Mohit Agrawal <moagrawa@redhat.com> | 2016-11-17 16:20:40 +0530 |
---|---|---|
committer | Raghavendra G <rgowdapp@redhat.com> | 2016-11-29 00:34:23 -0800 |
commit | 71dd2e914d4a537bf74e1ec3a24512fc83bacb1d (patch) | |
tree | e637471c26bbc8c4c24f4f6475bbccf87f86f8d3 /xlators/cluster | |
parent | 77f03db0131c88d607886bb02dd2a4276ab584d4 (diff) |
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>
Diffstat (limited to 'xlators/cluster')
-rw-r--r-- | xlators/cluster/dht/src/dht-rebalance.c | 102 |
1 files changed, 62 insertions, 40 deletions
diff --git a/xlators/cluster/dht/src/dht-rebalance.c b/xlators/cluster/dht/src/dht-rebalance.c index df1bce3d8db..c92bb6ad4d7 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; @@ -1381,6 +1390,7 @@ dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to, ret = 0; goto out; } + /* Take care of the special files */ if (!IA_ISREG (stbuf.ia_type)) { /* Special files */ @@ -1424,9 +1434,13 @@ dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to, loc->path, from->name); 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,14 @@ 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; |