summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--xlators/cluster/dht/src/dht-common.c34
-rw-r--r--xlators/cluster/dht/src/dht-common.h7
-rw-r--r--xlators/cluster/dht/src/dht-layout.c5
-rw-r--r--xlators/cluster/dht/src/dht-selfheal.c3
-rw-r--r--xlators/cluster/dht/src/dht.c35
5 files changed, 80 insertions, 4 deletions
diff --git a/xlators/cluster/dht/src/dht-common.c b/xlators/cluster/dht/src/dht-common.c
index 237a0789426..d5ee7ad1b90 100644
--- a/xlators/cluster/dht/src/dht-common.c
+++ b/xlators/cluster/dht/src/dht-common.c
@@ -2062,8 +2062,8 @@ err:
static int
-dht_fix_layout_cbk (call_frame_t *frame, void *cookie,
- xlator_t *this, int32_t op_ret, int32_t op_errno)
+dht_common_setxattr_cbk (call_frame_t *frame, void *cookie,
+ xlator_t *this, int32_t op_ret, int32_t op_errno)
{
DHT_STACK_UNWIND (setxattr, frame, op_ret, op_errno);
@@ -2082,6 +2082,9 @@ dht_setxattr (call_frame_t *frame, xlator_t *this,
int op_errno = EINVAL;
int ret = -1;
data_t *tmp = NULL;
+ uint32_t dir_spread = 0;
+ char value[4096] = {0,};
+
VALIDATE_OR_GOTO (frame, err);
VALIDATE_OR_GOTO (this, err);
@@ -2123,11 +2126,36 @@ dht_setxattr (call_frame_t *frame, xlator_t *this,
goto err;
}
- dht_fix_directory_layout (frame, dht_fix_layout_cbk,
+ dht_fix_directory_layout (frame, dht_common_setxattr_cbk,
layout);
return 0;
}
+ tmp = dict_get (xattr, "distribute.directory-spread-count");
+ if (tmp) {
+ /* Setxattr value is packed as 'binary', not string */
+ memcpy (value, tmp->data, ((tmp->len < 4095)?tmp->len:4095));
+ ret = gf_string2uint32 (value, &dir_spread);
+ if (!ret && ((dir_spread <= conf->subvolume_cnt) &&
+ (dir_spread > 0))) {
+ layout->spread_cnt = dir_spread;
+
+ ret = loc_dup (loc, &local->loc);
+ if (ret == -1) {
+ op_errno = ENOMEM;
+ goto err;
+ }
+ dht_fix_directory_layout (frame,
+ dht_common_setxattr_cbk,
+ layout);
+ return 0;
+ }
+ gf_log (this->name, GF_LOG_ERROR,
+ "wrong 'directory-spread-count' value (%s)", value);
+ op_errno = ENOTSUP;
+ goto err;
+ }
+
local->call_cnt = layout->cnt;
for (i = 0; i < layout->cnt; i++) {
diff --git a/xlators/cluster/dht/src/dht-common.h b/xlators/cluster/dht/src/dht-common.h
index c85ba9cfcc2..43056c78c9f 100644
--- a/xlators/cluster/dht/src/dht-common.h
+++ b/xlators/cluster/dht/src/dht-common.h
@@ -41,6 +41,9 @@ typedef int (*dht_selfheal_dir_cbk_t) (call_frame_t *frame, void *cookie,
struct dht_layout {
+ int spread_cnt; /* layout spread count per directory,
+ is controlled by 'setxattr()' with
+ special key */
int cnt;
int preset;
int gen;
@@ -171,6 +174,10 @@ struct dht_conf {
char vol_uuid[UUID_SIZE + 1];
gf_boolean_t assert_no_child_down;
time_t *subvol_up_time;
+
+ /* This is the count used as the distribute layout for a directory */
+ /* Will be a global flag to control the layout spread count */
+ uint32_t dir_spread_cnt;
};
typedef struct dht_conf dht_conf_t;
diff --git a/xlators/cluster/dht/src/dht-layout.c b/xlators/cluster/dht/src/dht-layout.c
index 16767adb9fa..e1ab6c7f170 100644
--- a/xlators/cluster/dht/src/dht-layout.c
+++ b/xlators/cluster/dht/src/dht-layout.c
@@ -52,8 +52,11 @@ dht_layout_new (xlator_t *this, int cnt)
layout->type = DHT_HASH_TYPE_DM;
layout->cnt = cnt;
- if (conf)
+
+ if (conf) {
+ layout->spread_cnt = conf->dir_spread_cnt;
layout->gen = conf->gen;
+ }
layout->ref = 1;
out:
diff --git a/xlators/cluster/dht/src/dht-selfheal.c b/xlators/cluster/dht/src/dht-selfheal.c
index a20526067b4..3d4f13c6f3f 100644
--- a/xlators/cluster/dht/src/dht-selfheal.c
+++ b/xlators/cluster/dht/src/dht-selfheal.c
@@ -482,6 +482,9 @@ dht_get_layout_count (xlator_t *this, dht_layout_t *layout)
}
}
+ count = ((layout->spread_cnt) ? layout->spread_cnt :
+ ((count) ? count : 1));
+
return count;
}
diff --git a/xlators/cluster/dht/src/dht.c b/xlators/cluster/dht/src/dht.c
index 3abba0dfe40..42f0c0d75e8 100644
--- a/xlators/cluster/dht/src/dht.c
+++ b/xlators/cluster/dht/src/dht.c
@@ -290,6 +290,7 @@ reconfigure (xlator_t *this, dict_t *options)
gf_boolean_t search_unhashed;
uint32_t temp_free_disk = 0;
int ret = -1;
+ uint32_t dir_spread = 0;
GF_VALIDATE_OR_GOTO ("dht", this, out);
GF_VALIDATE_OR_GOTO ("dht", options, out);
@@ -340,6 +341,22 @@ reconfigure (xlator_t *this, dict_t *options)
" min-free-disk reconfigured to %s",
temp_str);
}
+
+ if (dict_get_str (options, "directory-layout-spread", &temp_str) == 0) {
+ ret = gf_string2uint32 (temp_str, &dir_spread);
+ if (ret ||
+ (dir_spread > conf->subvolume_cnt) ||
+ (dir_spread < 1)) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "wrong 'directory-layout-spread' option given "
+ "(%s). setting to earlier value (%d)",
+ temp_str, conf->dir_spread_cnt);
+ ret = -1;
+ goto out;
+ }
+ conf->dir_spread_cnt = dir_spread;
+ }
+
ret = 0;
out:
return ret;
@@ -433,6 +450,21 @@ init (xlator_t *this)
}
}
+ conf->dir_spread_cnt = conf->subvolume_cnt;
+ if (dict_get_str (this->options, "directory-layout-spread",
+ &temp_str) == 0) {
+ ret = gf_string2uint32 (temp_str, &conf->dir_spread_cnt);
+ if (ret ||
+ (conf->dir_spread_cnt > conf->subvolume_cnt) ||
+ (conf->dir_spread_cnt < 1)) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "wrong 'directory-layout-spread' option given "
+ "(%s). setting it to subvolume count",
+ temp_str);
+ conf->dir_spread_cnt = conf->subvolume_cnt;
+ }
+ }
+
conf->assert_no_child_down = 0;
ret = dict_get_str_boolean (this->options, "assert-no-child-down", 0);
@@ -574,5 +606,8 @@ struct volume_options options[] = {
{ .key = {"assert-no-child-down"},
.type = GF_OPTION_TYPE_BOOL
},
+ { .key = {"directory-layout-spread"},
+ .type = GF_OPTION_TYPE_INT,
+ },
{ .key = {NULL} },
};