From fb034ba3036fadc7cf35edc5cae7481149a67ca0 Mon Sep 17 00:00:00 2001 From: Vikas Gorur Date: Thu, 9 Apr 2009 03:54:51 -0700 Subject: Compulsorily do self heal if file sizes differ. If file sizes differ, then compulsorily do self-heal. If no 'wise' sources are found, then pick a 'fool' with the biggest file size. If even 'fools' aren't found, pick the 'innocent' source with the biggest file size. Signed-off-by: Anand V. Avati --- xlators/cluster/afr/src/afr-self-heal-common.c | 99 ++++++++++++++++++++---- xlators/cluster/afr/src/afr-self-heal-common.h | 10 ++- xlators/cluster/afr/src/afr-self-heal-data.c | 4 +- xlators/cluster/afr/src/afr-self-heal-entry.c | 4 +- xlators/cluster/afr/src/afr-self-heal-metadata.c | 4 +- xlators/cluster/afr/src/afr-self-heal.h | 2 +- 6 files changed, 100 insertions(+), 23 deletions(-) (limited to 'xlators/cluster/afr/src') diff --git a/xlators/cluster/afr/src/afr-self-heal-common.c b/xlators/cluster/afr/src/afr-self-heal-common.c index 58ea4fdb992..7c2e403c72a 100644 --- a/xlators/cluster/afr/src/afr-self-heal-common.c +++ b/xlators/cluster/afr/src/afr-self-heal-common.c @@ -337,7 +337,7 @@ afr_sh_wise_nodes_exist (afr_node_character *characters, int child_count) /* - * The 'wisdom' of a wise node is 0 if any other wise node accuses to it. + * The 'wisdom' of a wise node is 0 if any other wise node accuses it. * It is 1 if no other wise node accuses it. * Only wise nodes with wisdom 1 are sources. * @@ -407,32 +407,97 @@ afr_sh_mark_wisest_as_sources (int sources[], return nsources; } + +static int +afr_sh_mark_if_size_differs (afr_self_heal_t *sh, int child_count) +{ + int32_t ** pending_matrix; + int i, j; + + int size_differs = 0; + + pending_matrix = sh->pending_matrix; + + for (i = 0; i < child_count; i++) { + for (j = 0; j < child_count; j++) { + if (SIZE_DIFFERS (&sh->buf[i], &sh->buf[j]) + && (pending_matrix[i][j] == 0) + && (pending_matrix[j][i] == 0)) { + + pending_matrix[i][j] = 1; + pending_matrix[j][i] = 1; + + size_differs = 1; + } + } + } + + return size_differs; +} + static int -afr_sh_mark_a_fool_as_source (int sources[], afr_node_character *characters, - int child_count) +afr_sh_mark_biggest_fool_as_source (afr_self_heal_t *sh, + afr_node_character *characters, + int child_count) { int i = 0; - - int nsources = 0; + int biggest = 0; for (i = 0; i < child_count; i++) { if (characters[i].type == AFR_NODE_FOOL) { - sources[i] = 1; - nsources++; + biggest = i; break; } } - return nsources; + for (i = 0; i < child_count; i++) { + if (characters[i].type != AFR_NODE_FOOL) + continue; + + if (SIZE_GREATER (&sh->buf[i], &sh->buf[biggest])) { + biggest = i; + } + } + + sh->sources[biggest] = 1; + + return 1; } - + +static int +afr_sh_mark_biggest_as_source (afr_self_heal_t *sh, int child_count) +{ + int biggest = 0; + int i; + + for (i = 0; i < child_count; i++) { + if (SIZE_GREATER (&sh->buf[i], &sh->buf[biggest])) { + biggest = i; + } + } + + sh->sources[biggest] = 1; + + return 1; +} + + int -afr_sh_mark_sources (int32_t *pending_matrix[], int sources[], int child_count) +afr_sh_mark_sources (afr_self_heal_t *sh, int child_count, + afr_self_heal_type type) { int i = 0; + int32_t ** pending_matrix; + int * sources; + + int size_differs = 0; + + pending_matrix = sh->pending_matrix; + sources = sh->sources; + int nsources = 0; /* stores the 'characters' (innocent, fool, wise) of the nodes */ @@ -463,9 +528,15 @@ afr_sh_mark_sources (int32_t *pending_matrix[], int sources[], int child_count) } } + if (type == AFR_SELF_HEAL_DATA) { + size_differs = afr_sh_mark_if_size_differs (sh, child_count); + } + if (afr_sh_all_nodes_innocent (characters, child_count)) { - /* no self-heal needed */ - goto out; + if (size_differs) { + nsources = afr_sh_mark_biggest_as_source (sh, + child_count); + } } else if (afr_sh_wise_nodes_exist (characters, child_count)) { afr_sh_compute_wisdom (pending_matrix, characters, child_count); @@ -482,8 +553,8 @@ afr_sh_mark_sources (int32_t *pending_matrix[], int sources[], int child_count) child_count); } } else { - nsources = afr_sh_mark_a_fool_as_source (sources, characters, - child_count); + nsources = afr_sh_mark_biggest_fool_as_source (sh, characters, + child_count); } out: diff --git a/xlators/cluster/afr/src/afr-self-heal-common.h b/xlators/cluster/afr/src/afr-self-heal-common.h index df786e99924..86f155b6897 100644 --- a/xlators/cluster/afr/src/afr-self-heal-common.h +++ b/xlators/cluster/afr/src/afr-self-heal-common.h @@ -22,6 +22,12 @@ #define FILE_HAS_HOLES(buf) (((buf)->st_size) > ((buf)->st_blocks * 512)) +typedef enum { + AFR_SELF_HEAL_ENTRY, + AFR_SELF_HEAL_METADATA, + AFR_SELF_HEAL_DATA, +} afr_self_heal_type; + int afr_sh_select_source (int sources[], int child_count); @@ -52,8 +58,8 @@ afr_sh_pending_to_delta (dict_t **xattr, char *key, int32_t *delta_matrix[], int32_t success[], int child_count); int -afr_sh_mark_sources (int32_t *pending_matrix[], int sources[], - int child_count); +afr_sh_mark_sources (afr_self_heal_t *sh, int child_count, + afr_self_heal_type type); int afr_sh_delta_to_xattr (int32_t *delta_matrix[], dict_t *xattr[], diff --git a/xlators/cluster/afr/src/afr-self-heal-data.c b/xlators/cluster/afr/src/afr-self-heal-data.c index 8dad39257eb..2c1ceafffa1 100644 --- a/xlators/cluster/afr/src/afr-self-heal-data.c +++ b/xlators/cluster/afr/src/afr-self-heal-data.c @@ -779,8 +779,8 @@ afr_sh_data_fix (call_frame_t *frame, xlator_t *this) afr_sh_print_pending_matrix (sh->pending_matrix, this); - nsources = afr_sh_mark_sources (sh->pending_matrix, sh->sources, - priv->child_count); + nsources = afr_sh_mark_sources (sh, priv->child_count, + AFR_SELF_HEAL_DATA); afr_sh_supress_empty_children (sh->sources, sh->xattr, sh->buf, priv->child_count, AFR_DATA_PENDING); diff --git a/xlators/cluster/afr/src/afr-self-heal-entry.c b/xlators/cluster/afr/src/afr-self-heal-entry.c index 665dfb93628..3906b707e0c 100644 --- a/xlators/cluster/afr/src/afr-self-heal-entry.c +++ b/xlators/cluster/afr/src/afr-self-heal-entry.c @@ -1830,8 +1830,8 @@ afr_sh_entry_fix (call_frame_t *frame, xlator_t *this) afr_sh_print_pending_matrix (sh->pending_matrix, this); - afr_sh_mark_sources (sh->pending_matrix, sh->sources, - priv->child_count); + afr_sh_mark_sources (sh, priv->child_count, + AFR_SELF_HEAL_ENTRY); afr_sh_supress_errenous_children (sh->sources, sh->child_errno, priv->child_count); diff --git a/xlators/cluster/afr/src/afr-self-heal-metadata.c b/xlators/cluster/afr/src/afr-self-heal-metadata.c index 9ce42691a83..6dce5d3afb0 100644 --- a/xlators/cluster/afr/src/afr-self-heal-metadata.c +++ b/xlators/cluster/afr/src/afr-self-heal-metadata.c @@ -520,8 +520,8 @@ afr_sh_metadata_fix (call_frame_t *frame, xlator_t *this) afr_sh_print_pending_matrix (sh->pending_matrix, this); - nsources = afr_sh_mark_sources (sh->pending_matrix, sh->sources, - priv->child_count); + nsources = afr_sh_mark_sources (sh, priv->child_count, + AFR_SELF_HEAL_METADATA); afr_sh_supress_errenous_children (sh->sources, sh->child_errno, priv->child_count); diff --git a/xlators/cluster/afr/src/afr-self-heal.h b/xlators/cluster/afr/src/afr-self-heal.h index c98831b8bca..73abd8fb96f 100644 --- a/xlators/cluster/afr/src/afr-self-heal.h +++ b/xlators/cluster/afr/src/afr-self-heal.h @@ -27,7 +27,7 @@ #define OWNERSHIP_DIFFERS(buf1,buf2) ((((struct stat *)buf1)->st_uid) != (((struct stat *)buf2)->st_uid) || (((struct stat *)buf1)->st_gid != (((struct stat *)buf2)->st_gid))) #define SIZE_DIFFERS(buf1,buf2) ((((struct stat *)buf1)->st_size) != (((struct stat *)buf2)->st_size)) - +#define SIZE_GREATER(buf1,buf2) ((((struct stat *)buf1)->st_size > (((struct stat *)buf2)->st_size))) int afr_sh_has_metadata_pending (dict_t *xattr, int child_count, xlator_t *this); -- cgit