summaryrefslogtreecommitdiffstats
path: root/xlators/cluster/afr/src
diff options
context:
space:
mode:
authorVikas Gorur <vikas@gluster.com>2010-01-12 04:14:25 +0000
committerAnand V. Avati <avati@dev.gluster.com>2010-01-14 23:23:49 -0800
commit5522f6eaef99616efe01b8f4688be0486e511b12 (patch)
treebd0f04900ce755b08e0ad8d93fcc54fe9b0e8026 /xlators/cluster/afr/src
parentda09bf7fafa725db7f6e778f7fb5645276978948 (diff)
cluster/afr: Pick a source for metadata self-heal even if all nodes are innocent.
If metadata changelog has been disabled, all subvolumes will be innocent. In that case, simply pick the subvolume on which the file has the lowest uid as the source and sync other subvolumes to it. Signed-off-by: Vikas Gorur <vikas@gluster.com> Signed-off-by: Anand V. Avati <avati@dev.gluster.com> BUG: 451 (metadata self-heal does not a pick a source if mode/times have been changed at the backend) URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=451
Diffstat (limited to 'xlators/cluster/afr/src')
-rw-r--r--xlators/cluster/afr/src/afr-self-heal-common.c28
1 files changed, 28 insertions, 0 deletions
diff --git a/xlators/cluster/afr/src/afr-self-heal-common.c b/xlators/cluster/afr/src/afr-self-heal-common.c
index 4480140b5..a2c2e34ce 100644
--- a/xlators/cluster/afr/src/afr-self-heal-common.c
+++ b/xlators/cluster/afr/src/afr-self-heal-common.c
@@ -437,6 +437,27 @@ afr_sh_mark_biggest_as_source (afr_self_heal_t *sh, int child_count)
}
+static int
+afr_sh_mark_lowest_uid_as_source (afr_self_heal_t *sh, int child_count)
+{
+ uid_t smallest = 0;
+ int i;
+
+ for (i = 0; i < child_count; i++) {
+ if (!sh->buf)
+ break;
+
+ if (sh->buf[i].st_uid < sh->buf[smallest].st_uid) {
+ smallest = i;
+ }
+ }
+
+ sh->sources[smallest] = 1;
+
+ return 1;
+}
+
+
int
afr_sh_mark_sources (afr_self_heal_t *sh, int child_count,
afr_self_heal_type type)
@@ -486,6 +507,13 @@ afr_sh_mark_sources (afr_self_heal_t *sh, int child_count,
size_differs = afr_sh_mark_if_size_differs (sh, child_count);
}
+ if ((type == AFR_SELF_HEAL_METADATA)
+ && afr_sh_all_nodes_innocent (characters, child_count)) {
+
+ nsources = afr_sh_mark_lowest_uid_as_source (sh, child_count);
+ goto out;
+ }
+
if (afr_sh_all_nodes_innocent (characters, child_count)) {
if (size_differs) {
nsources = afr_sh_mark_biggest_as_source (sh,