diff options
| -rw-r--r-- | tests/basic/afr/ta.t | 22 | ||||
| -rw-r--r-- | xlators/cluster/afr/src/afr-common.c | 1 | ||||
| -rw-r--r-- | xlators/cluster/afr/src/afr-dir-write.c | 6 | ||||
| -rw-r--r-- | xlators/cluster/afr/src/afr-transaction.c | 94 | ||||
| -rw-r--r-- | xlators/cluster/afr/src/afr.h | 5 | 
5 files changed, 103 insertions, 25 deletions
diff --git a/tests/basic/afr/ta.t b/tests/basic/afr/ta.t index d8beb1be461..05d48431c95 100644 --- a/tests/basic/afr/ta.t +++ b/tests/basic/afr/ta.t @@ -27,18 +27,28 @@ EXPECT_WITHIN $PROCESS_DOWN_TIMEOUT "0" afr_child_up_status_meta $M0 $V0-replica  TEST touch $M0/b.txt  EXPECT "000000000000000000000001" get_hex_xattr trusted.afr.$V0-client-0 $B0/brick1  EXPECT "000000010000000200000000" get_hex_xattr trusted.afr.$V0-client-0 $B0/brick1/b.txt -#TODO: New entry mark lead to pending data on the file but no such marking happened on ta -#EXPECT "000000010000000100000001" get_hex_xattr trusted.afr.$V0-client-0 $B0/ta/trusted.afr.patchy-ta-2 +#New entry mark lead to pending data on the file and on ta +EXPECT "000000010000000100000000" get_hex_xattr trusted.afr.$V0-client-0 $B0/ta/trusted.afr.patchy-ta-2  TEST ! ls $B0/brick0/b.txt  TEST ls $B0/brick1/b.txt +#Try to create an entry while good brick is down and bad brick is UP. Should not create +TEST ta_start_brick_process brick0 +EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" afr_child_up_status_meta $M0 $V0-replicate-0 0 +TEST ta_kill_brick brick1 +EXPECT_WITHIN $PROCESS_DOWN_TIMEOUT "0" afr_child_up_status_meta $M0 $V0-replicate-0 1 +TEST ! touch $M0/d.txt +EXPECT "000000010000000100000000" get_hex_xattr trusted.afr.$V0-client-0 $B0/ta/trusted.afr.patchy-ta-2 + +TEST ta_start_brick_process brick1 +EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" afr_child_up_status_meta $M0 $V0-replicate-0 1 +TEST ta_kill_brick brick0 +EXPECT_WITHIN $PROCESS_DOWN_TIMEOUT "0" afr_child_up_status_meta $M0 $V0-replicate-0 0 +  TEST ta_kill_brick ta -# Entry create must fail since only 1 brick is up. +# Entry create must fail if only one brick is UP, even if that is a good brick.  TEST ! touch $M0/c.txt  TEST ! ls $B0/brick0/c.txt  TEST ! ls $B0/brick1/c.txt -TEST ta_start_brick_process brick0 -EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" afr_child_up_status_meta $M0 $V0-replicate-0 0 -  cleanup; diff --git a/xlators/cluster/afr/src/afr-common.c b/xlators/cluster/afr/src/afr-common.c index 54889e0a9b1..f030de5e5cc 100644 --- a/xlators/cluster/afr/src/afr-common.c +++ b/xlators/cluster/afr/src/afr-common.c @@ -5694,6 +5694,7 @@ afr_local_init(afr_local_t *local, afr_private_t *priv, int32_t *op_errno)          local->ta_child_up = priv->ta_child_up;          local->ta_failed_subvol = AFR_CHILD_UNKNOWN;      } +    local->is_new_entry = _gf_false;      INIT_LIST_HEAD(&local->healer);      return 0; diff --git a/xlators/cluster/afr/src/afr-dir-write.c b/xlators/cluster/afr/src/afr-dir-write.c index 5725b1c5cb3..a9a8e91c898 100644 --- a/xlators/cluster/afr/src/afr-dir-write.c +++ b/xlators/cluster/afr/src/afr-dir-write.c @@ -365,6 +365,12 @@ afr_mark_entry_pending_changelog(call_frame_t *frame, xlator_t *this)      if (pre_op_count == priv->child_count && !failed_count)          return; +    if (priv->thin_arbiter_count) { +        /*Mark new entry using ta file*/ +        local->is_new_entry = _gf_true; +        return; +    } +      afr_mark_new_entry_changelog(frame, this);      return; diff --git a/xlators/cluster/afr/src/afr-transaction.c b/xlators/cluster/afr/src/afr-transaction.c index fb78c198d9c..74c55f99ec2 100644 --- a/xlators/cluster/afr/src/afr-transaction.c +++ b/xlators/cluster/afr/src/afr-transaction.c @@ -28,6 +28,12 @@ typedef enum {  static void  afr_lock_resume_shared(struct list_head *list); +static void +afr_post_op_handle_success(call_frame_t *frame, xlator_t *this); + +static void +afr_post_op_handle_failure(call_frame_t *frame, xlator_t *this); +  void  __afr_transaction_wake_shared(afr_local_t *local, struct list_head *shared); @@ -660,6 +666,7 @@ afr_set_pending_dict(afr_private_t *priv, dict_t *xattr, int **pending)      return ret;  } +  static void  afr_ta_dom_lock_check_and_release(afr_local_t *local, xlator_t *this)  { @@ -739,9 +746,9 @@ afr_ta_process_onwireq(afr_local_t *local, xlator_t *this)              --priv->ta_on_wire_txn_count;              UNLOCK(&priv->lock);              if (entry->ta_failed_subvol == bad_child) { -                afr_changelog_post_op_do(entry->transaction.frame, this); +                afr_post_op_handle_success(entry->transaction.frame, this);              } else { -                afr_changelog_post_op_fail(entry->transaction.frame, this, EIO); +                afr_post_op_handle_failure(entry->transaction.frame, this);              }          }      } @@ -1187,6 +1194,34 @@ afr_ta_post_op_done(int ret, call_frame_t *frame, void *opaque)      return 0;  } +int ** +afr_set_changelog_xattr(afr_private_t *priv, unsigned char *pending, +                        dict_t *xattr, afr_local_t *local) +{ +    int **changelog = NULL; +    int idx = 0; +    int i; + +    if (local->is_new_entry == _gf_true) { +        changelog = afr_mark_pending_changelog(priv, pending, xattr, +                                               local->cont.dir_fop.buf.ia_type); +    } else { +        idx = afr_index_for_transaction_type(local->transaction.type); +        changelog = afr_matrix_create(priv->child_count, AFR_NUM_CHANGE_LOGS); +        if (!changelog) { +            goto out; +        } +        for (i = 0; i < priv->child_count; i++) { +            if (local->transaction.failed_subvols[i]) +                changelog[i][idx] = hton32(1); +        } +        afr_set_pending_dict(priv, xattr, changelog); +    } + +out: +    return changelog; +} +  static int  afr_ta_post_op_do(void *opaque)  { @@ -1195,13 +1230,13 @@ afr_ta_post_op_do(void *opaque)      xlator_t *this = NULL;      call_frame_t *txn_frame = NULL;      dict_t *xattr = NULL; -    int **pending = NULL; +    unsigned char *pending = NULL; +    int **changelog = NULL;      int failed_subvol = -1;      int success_subvol = -1;      loc_t loc = {          0,      }; -    int idx = 0;      int i = 0;      int ret = 0; @@ -1209,7 +1244,6 @@ afr_ta_post_op_do(void *opaque)      txn_frame = local->transaction.frame;      this = txn_frame->this;      priv = this->private; -    idx = afr_index_for_transaction_type(local->transaction.type);      ret = afr_fill_ta_loc(this, &loc);      if (ret) { @@ -1224,22 +1258,20 @@ afr_ta_post_op_do(void *opaque)          goto out;      } -    pending = afr_matrix_create(priv->child_count, AFR_NUM_CHANGE_LOGS); -    if (!pending) { -        ret = -ENOMEM; -        goto out; -    } +    pending = alloca0(priv->child_count); +      for (i = 0; i < priv->child_count; i++) {          if (local->transaction.failed_subvols[i]) { -            pending[i][idx] = hton32(1); +            pending[i] = 1;              failed_subvol = i;          } else {              success_subvol = i;          }      } -    ret = afr_set_pending_dict(priv, xattr, pending); -    if (ret < 0) +    changelog = afr_set_changelog_xattr(priv, pending, xattr, local); + +    if (!changelog)          goto out;      ret = afr_ta_post_op_lock(this, &loc); @@ -1271,16 +1303,16 @@ out:      if (xattr)          dict_unref(xattr); -    if (pending) -        afr_matrix_cleanup(pending, priv->child_count); +    if (changelog) +        afr_matrix_cleanup(changelog, priv->child_count);      loc_wipe(&loc);      if (ret == 0) {          /*Mark pending xattrs on the up data brick.*/ -        afr_changelog_post_op_do(local->transaction.frame, this); +        afr_post_op_handle_success(local->transaction.frame, this);      } else { -        afr_changelog_post_op_fail(local->transaction.frame, this, -ret); +        afr_post_op_handle_failure(local->transaction.frame, this);      }      return ret;  } @@ -1359,6 +1391,28 @@ afr_ta_fill_failed_subvol(afr_private_t *priv, afr_local_t *local)  }  static void +afr_post_op_handle_success(call_frame_t *frame, xlator_t *this) +{ +    afr_local_t *local = NULL; + +    local = frame->local; +    if (local->is_new_entry == _gf_true) { +        afr_mark_new_entry_changelog(frame, this); +    } +    afr_changelog_post_op_do(frame, this); + +    return; +} + +static void +afr_post_op_handle_failure(call_frame_t *frame, xlator_t *this) +{ +    afr_changelog_post_op_fail(frame, this, EIO); + +    return; +} + +static void  afr_ta_decide_post_op_state(call_frame_t *frame, xlator_t *this)  {      afr_private_t *priv = NULL; @@ -1380,10 +1434,12 @@ afr_ta_decide_post_op_state(call_frame_t *frame, xlator_t *this)              /*Post releasing the notify lock, we will act on this queue*/              break;          case TA_INFO_IN_MEMORY_SUCCESS: -            afr_changelog_post_op_do(frame, this); +            afr_post_op_handle_success(frame, this);              break;          case TA_INFO_IN_MEMORY_FAILED: -            afr_changelog_post_op_fail(frame, this, EIO); +            afr_post_op_handle_failure(frame, this); +            break; +        default:              break;      }      return; diff --git a/xlators/cluster/afr/src/afr.h b/xlators/cluster/afr/src/afr.h index 6f8015380f0..6ddb992f448 100644 --- a/xlators/cluster/afr/src/afr.h +++ b/xlators/cluster/afr/src/afr.h @@ -880,6 +880,7 @@ typedef struct _afr_local {      struct list_head ta_onwireq;      afr_ta_fop_state_t fop_state;      int ta_failed_subvol; +    gf_boolean_t is_new_entry;  } afr_local_t;  typedef struct afr_spbc_timeout { @@ -1320,4 +1321,8 @@ afr_ta_has_quorum(afr_private_t *priv, afr_local_t *local);  void  afr_ta_lock_release_synctask(xlator_t *this); + +void +afr_mark_new_entry_changelog(call_frame_t *frame, xlator_t *this); +  #endif /* __AFR_H__ */  | 
