summaryrefslogtreecommitdiffstats
path: root/xlators/cluster/dht/src/dht-rebalance.c
diff options
context:
space:
mode:
Diffstat (limited to 'xlators/cluster/dht/src/dht-rebalance.c')
-rw-r--r--xlators/cluster/dht/src/dht-rebalance.c96
1 files changed, 78 insertions, 18 deletions
diff --git a/xlators/cluster/dht/src/dht-rebalance.c b/xlators/cluster/dht/src/dht-rebalance.c
index d963cfb2b8f..c1174225138 100644
--- a/xlators/cluster/dht/src/dht-rebalance.c
+++ b/xlators/cluster/dht/src/dht-rebalance.c
@@ -719,27 +719,30 @@ __dht_rebalance_create_dst_file (xlator_t *to, xlator_t *from, loc_t *loc, struc
loc->path, to->name, strerror (-ret));
*/
+ ret = syncop_fsetattr (to, fd, stbuf,
+ (GF_SET_ATTR_UID | GF_SET_ATTR_GID),
+ NULL, NULL, NULL, NULL);
+ if (ret < 0)
+ gf_msg (this->name, GF_LOG_ERROR, 0,
+ DHT_MSG_MIGRATE_FILE_FAILED,
+ "chown failed for %s on %s (%s)",
+ loc->path, to->name, strerror (-ret));
+
/* Fallocate does not work for size 0, hence the check. Anyway we don't
* need to care about min-free-disk for 0 byte size file */
if (stbuf->ia_size > 0) {
ret = syncop_fallocate (to, fd, 0, 0, stbuf->ia_size, NULL,
NULL);
- if (ret < 0)
+ if (ret < 0) {
gf_msg (this->name, GF_LOG_ERROR, 0,
DHT_MSG_MIGRATE_FILE_FAILED,
"fallocate failed for %s on %s (%s)",
loc->path, to->name, strerror (-ret));
+ ret = -1;
+ goto out;
+ }
}
- ret = syncop_fsetattr (to, fd, stbuf,
- (GF_SET_ATTR_UID | GF_SET_ATTR_GID),
- NULL, NULL, NULL, NULL);
- if (ret < 0)
- gf_msg (this->name, GF_LOG_ERROR, 0,
- DHT_MSG_MIGRATE_FILE_FAILED,
- "chown failed for %s on %s (%s)",
- loc->path, to->name, strerror (-ret));
-
/* success */
ret = 0;
@@ -761,7 +764,8 @@ out:
static int
__dht_check_free_space (xlator_t *to, xlator_t *from, loc_t *loc,
struct iatt *stbuf, int flag, dht_conf_t *conf,
- gf_boolean_t *target_changed, xlator_t **new_subvol)
+ gf_boolean_t *target_changed, xlator_t **new_subvol,
+ gf_boolean_t *ignore_failure)
{
struct statvfs src_statfs = {0,};
struct statvfs dst_statfs = {0,};
@@ -773,6 +777,7 @@ __dht_check_free_space (xlator_t *to, xlator_t *from, loc_t *loc,
uint64_t dst_statfs_blocks = 1;
double post_availspace = 0;
double post_percent = 0;
+ int i = 0;
this = THIS;
@@ -897,13 +902,27 @@ find_new_subvol:
goto out;
}
- *new_subvol = dht_subvol_with_free_space_inodes (this, to,
- layout, stbuf->ia_size);
- if (!(*new_subvol)) {
+ *new_subvol = dht_subvol_with_free_space_inodes (this, to, from, layout,
+ stbuf->ia_size);
+ if ((!(*new_subvol)) || (*new_subvol == from)) {
gf_msg (this->name, GF_LOG_WARNING, 0,
DHT_MSG_SUBVOL_INSUFF_SPACE, "Could not find any subvol"
- " with space accomodating the file. Consider adding "
- "bricks");
+ " with space accomodating the file - %s. Consider adding "
+ "bricks", loc->path);
+
+ /* For remove-brick case if the source is not one of the
+ * removed-brick, do not mark the error as failure */
+ if (conf->decommission_subvols_cnt) {
+ *ignore_failure = _gf_true;
+ for (i = 0; i < conf->decommission_subvols_cnt; i++) {
+ if (conf->decommissioned_bricks[i] == from) {
+ *ignore_failure = _gf_false;
+ break;
+ }
+ }
+ } else {
+ *ignore_failure = _gf_false;
+ }
*target_changed = _gf_false;
ret = -1;
@@ -1382,6 +1401,8 @@ dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to,
gf_boolean_t target_changed = _gf_false;
xlator_t *new_target = NULL;
xlator_t *old_target = NULL;
+ fd_t *linkto_fd = NULL;
+ gf_boolean_t ignore_failure = _gf_false;
defrag = conf->defrag;
if (!defrag)
@@ -1500,7 +1521,7 @@ dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to,
clean_dst = _gf_true;
ret = __dht_check_free_space (to, from, loc, &stbuf, flag, conf,
- &target_changed, &new_target);
+ &target_changed, &new_target, &ignore_failure);
if (target_changed) {
/* Can't handle for hardlinks. Marking this as failure */
if (flag == GF_DHT_MIGRATE_HARDLINK_IN_PROGRESS || stbuf.ia_nlink > 1) {
@@ -1544,6 +1565,9 @@ dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to,
}
if (ret) {
+ if (ignore_failure)
+ ret = 0;
+
goto out;
}
@@ -1791,13 +1815,47 @@ dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to,
}
ret = syncop_setxattr (old_target, loc, dict, 0, NULL, NULL);
- if (ret) {
+ if (ret && -ret != ESTALE && -ret != ENOENT) {
gf_msg (this->name, GF_LOG_ERROR, 0,
DHT_MSG_MIGRATE_FILE_FAILED,
"failed to set xattr on %s in %s (%s)",
loc->path, old_target->name, strerror (-ret));
ret = -1;
goto out;
+ } else if (-ret == ESTALE || -ret == ENOENT) {
+ /* The failure ESTALE indicates that the linkto
+ * file on the hashed subvol might have been deleted.
+ * In this case will create a linkto file with new target
+ * as linkto xattr value*/
+ linkto_fd = fd_create (loc->inode, DHT_REBALANCE_PID);
+ if (!linkto_fd) {
+ gf_msg (this->name, GF_LOG_ERROR, 0,
+ DHT_MSG_MIGRATE_FILE_FAILED,
+ "%s: fd create failed (%s)",
+ loc->path, strerror (errno));
+ ret = -1;
+ goto out;
+ }
+ ret = syncop_create (old_target, loc, O_RDWR,
+ DHT_LINKFILE_MODE, linkto_fd,
+ NULL, dict, NULL);
+ if (ret != 0 && -ret != EEXIST && -ret != ESTALE) {
+ ret = -1;
+ gf_msg (this->name, GF_LOG_ERROR, 0,
+ DHT_MSG_MIGRATE_FILE_FAILED,
+ "failed to create linkto file on %s in %s (%s)",
+ loc->path, old_target->name, strerror (-ret));
+ goto out;
+ } else if (ret == 0) {
+ ret = syncop_fsetattr (old_target, linkto_fd, &stbuf,
+ (GF_SET_ATTR_UID | GF_SET_ATTR_GID),
+ NULL, NULL, NULL, NULL);
+ if (ret < 0)
+ gf_msg (this->name, GF_LOG_ERROR, 0,
+ DHT_MSG_MIGRATE_FILE_FAILED,
+ "chown failed for %s on %s (%s)",
+ loc->path, old_target->name, strerror (-ret));
+ }
}
}
}
@@ -2043,6 +2101,8 @@ out:
syncop_close (dst_fd);
if (src_fd)
syncop_close (src_fd);
+ if (linkto_fd)
+ syncop_close (linkto_fd);
loc_wipe (&tmp_loc);