From 32173e1c70dcb53470b0738ed4d0022388193113 Mon Sep 17 00:00:00 2001 From: Kaushal M Date: Thu, 20 Oct 2011 10:53:58 +0530 Subject: cluster/afr : Fix self-heal of special files Fixes self-heal of special files like device files, fifo files, socket files etc. Does it by doing the following: * Prevent setting of pending data xattr on a special file during entry self-heal when a new fils is created. * Allow data self-heal to be started on all file types other than directories. During data self-heal, for special files just erase pending xattrs, if those xattrs were set by previous releases of glusterfs. Change-Id: I34d8121e23ad00e85371ae2a36ef30cf3bd5db7a BUG: 3525 Reviewed-on: http://review.gluster.com/618 Tested-by: Gluster Build System Reviewed-by: Pranith Kumar Karampuri --- xlators/cluster/afr/src/afr-self-heal-data.c | 34 +++++++++++++++++++++++- xlators/cluster/afr/src/afr-self-heal-entry.c | 9 +++++-- xlators/cluster/afr/src/afr-self-heal-metadata.c | 13 +++------ 3 files changed, 44 insertions(+), 12 deletions(-) (limited to 'xlators/cluster') diff --git a/xlators/cluster/afr/src/afr-self-heal-data.c b/xlators/cluster/afr/src/afr-self-heal-data.c index 216017cbb..97d578c9b 100644 --- a/xlators/cluster/afr/src/afr-self-heal-data.c +++ b/xlators/cluster/afr/src/afr-self-heal-data.c @@ -366,6 +366,10 @@ afr_sh_data_erase_pending_cbk (call_frame_t *frame, void *cookie, if (call_count == 0) { local = frame->local; sh = &local->self_heal; + if (!IA_ISREG (sh->type)) { + afr_sh_data_finish (frame, this); + goto out; + } if (NULL == sh->old_loop_frame) { GF_ASSERT (sh->data_lock_held); afr_sh_data_fxattrop (frame, this, @@ -849,6 +853,27 @@ out: return read_child; } +int +afr_sh_data_special_file_fix (call_frame_t *frame, xlator_t *this) +{ + afr_private_t *priv = NULL; + afr_self_heal_t *sh = NULL; + afr_local_t *local = NULL; + int i = 0; + + local = frame->local; + sh = &local->self_heal; + priv = this->private; + + for (i = 0; i < priv->child_count ; i++) + if (1 == local->child_up[i]) + sh->success[i] = 1; + + afr_sh_data_erase_pending (frame, this); + + return 0; +} + int afr_sh_data_fstat_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, @@ -882,7 +907,14 @@ afr_sh_data_fstat_cbk (call_frame_t *frame, void *cookie, call_count = afr_frame_return (frame); if (call_count == 0) { - afr_sh_data_fix (frame, this); + /* Previous versions of glusterfs might have set + * the pending data xattrs which need to be erased + */ + if (IA_ISREG (buf->ia_type)) + afr_sh_data_fix (frame, this); + else + afr_sh_data_special_file_fix (frame, this); + } return 0; diff --git a/xlators/cluster/afr/src/afr-self-heal-entry.c b/xlators/cluster/afr/src/afr-self-heal-entry.c index 5a3302f7f..12cba1f49 100644 --- a/xlators/cluster/afr/src/afr-self-heal-entry.c +++ b/xlators/cluster/afr/src/afr-self-heal-entry.c @@ -1079,14 +1079,20 @@ afr_sh_entry_impunge_newfile_cbk (call_frame_t *impunge_frame, void *cookie, ret = -1; goto out; } + + /* Pending data xattrs shouldn't be set for special files + */ idx = afr_index_for_transaction_type (AFR_METADATA_TRANSACTION); pending_array[idx] = hton32 (1); if (IA_ISDIR (stbuf->ia_type)) idx = afr_index_for_transaction_type (AFR_ENTRY_TRANSACTION); - else + else if (IA_ISREG (stbuf->ia_type)) idx = afr_index_for_transaction_type (AFR_DATA_TRANSACTION); + else + goto cont; pending_array[idx] = hton32 (1); +cont: ret = dict_set_dynptr (xattr, priv->pending_key[child_index], pending_array, 3 * sizeof (*pending_array)); @@ -1096,7 +1102,6 @@ afr_sh_entry_impunge_newfile_cbk (call_frame_t *impunge_frame, void *cookie, } else { pending_array = NULL; } - valid = GF_SET_ATTR_ATIME | GF_SET_ATTR_MTIME; parentbuf = impunge_sh->parentbuf; setattr_frame = copy_frame (impunge_frame); diff --git a/xlators/cluster/afr/src/afr-self-heal-metadata.c b/xlators/cluster/afr/src/afr-self-heal-metadata.c index efc841261..c67748b2f 100644 --- a/xlators/cluster/afr/src/afr-self-heal-metadata.c +++ b/xlators/cluster/afr/src/afr-self-heal-metadata.c @@ -72,14 +72,6 @@ afr_sh_metadata_done (call_frame_t *frame, xlator_t *this) sh->op_failed = 1; sh->completion_cbk (frame, this); } else { - if (IA_ISREG (sh->type)) { - gf_log (this->name, GF_LOG_DEBUG, - "proceeding to data check on %s", - local->loc.path); - afr_self_heal_data (frame, this); - return 0; - } - if (IA_ISDIR (sh->type)) { gf_log (this->name, GF_LOG_DEBUG, "proceeding to entry check on %s", @@ -87,7 +79,10 @@ afr_sh_metadata_done (call_frame_t *frame, xlator_t *this) afr_self_heal_entry (frame, this); return 0; } - sh->completion_cbk (frame, this); + gf_log (this->name, GF_LOG_DEBUG, + "proceeding to data check on %s", + local->loc.path); + afr_self_heal_data (frame, this); } return 0; -- cgit