diff options
| -rw-r--r-- | xlators/cluster/afr/src/afr-inode-write.c | 22 | ||||
| -rw-r--r-- | xlators/cluster/afr/src/afr-transaction.c | 23 | ||||
| -rw-r--r-- | xlators/cluster/afr/src/afr.h | 8 | 
3 files changed, 47 insertions, 6 deletions
diff --git a/xlators/cluster/afr/src/afr-inode-write.c b/xlators/cluster/afr/src/afr-inode-write.c index f9e2b302f8d..df807342b99 100644 --- a/xlators/cluster/afr/src/afr-inode-write.c +++ b/xlators/cluster/afr/src/afr-inode-write.c @@ -284,6 +284,7 @@ afr_inode_write_fill(call_frame_t *frame, xlator_t *this, int child_index,      afr_local_t *local = frame->local;      uint32_t open_fd_count = 0;      uint32_t write_is_append = 0; +    int32_t num_inodelks = 0;      LOCK(&frame->lock);      { @@ -305,6 +306,15 @@ afr_inode_write_fill(call_frame_t *frame, xlator_t *this, int child_index,              local->open_fd_count = open_fd_count;              local->update_open_fd_count = _gf_true;          } + +        ret = dict_get_int32n(xdata, GLUSTERFS_INODELK_COUNT, +                              SLEN(GLUSTERFS_INODELK_COUNT), &num_inodelks); +        if (ret < 0) +            goto unlock; +        if (num_inodelks > local->num_inodelks) { +            local->num_inodelks = num_inodelks; +            local->update_num_inodelks = _gf_true; +        }      }  unlock:      UNLOCK(&frame->lock); @@ -314,6 +324,7 @@ void  afr_process_post_writev(call_frame_t *frame, xlator_t *this)  {      afr_local_t *local = NULL; +    afr_lock_t *lock = NULL;      local = frame->local; @@ -332,6 +343,11 @@ afr_process_post_writev(call_frame_t *frame, xlator_t *this)      if (local->update_open_fd_count)          local->inode_ctx->open_fd_count = local->open_fd_count; +    if (local->update_num_inodelks && +        local->transaction.type == AFR_DATA_TRANSACTION) { +        lock = &local->inode_ctx->lock[local->transaction.type]; +        lock->num_inodelks = local->num_inodelks; +    }  }  int @@ -512,6 +528,12 @@ afr_writev(call_frame_t *frame, xlator_t *this, fd_t *fd, struct iovec *vector,          goto out;      } +    if (dict_set_strn(local->xdata_req, GLUSTERFS_INODELK_DOM_COUNT, +                      SLEN(GLUSTERFS_INODELK_DOM_COUNT), this->name)) { +        op_errno = ENOMEM; +        goto out; +    } +      if (dict_set_uint32(local->xdata_req, GLUSTERFS_WRITE_IS_APPEND, 4)) {          op_errno = ENOMEM;          goto out; diff --git a/xlators/cluster/afr/src/afr-transaction.c b/xlators/cluster/afr/src/afr-transaction.c index dae4c8234e9..cf153dea9cc 100644 --- a/xlators/cluster/afr/src/afr-transaction.c +++ b/xlators/cluster/afr/src/afr-transaction.c @@ -1916,17 +1916,28 @@ afr_internal_lock_finish(call_frame_t *frame, xlator_t *this)  }  gf_boolean_t -afr_are_multiple_fds_opened(afr_local_t *local, xlator_t *this) +afr_are_conflicting_ops_waiting(afr_local_t *local, xlator_t *this)  { +    afr_lock_t *lock = NULL; +    lock = &local->inode_ctx->lock[local->transaction.type]; +      /* Lets say mount1 has eager-lock(full-lock) and after the eager-lock       * is taken mount2 opened the same file, it won't be able to -     * perform any data operations until mount1 releases eager-lock. +     * perform any {meta,}data operations until mount1 releases eager-lock.       * To avoid such scenario do not enable eager-lock for this transaction -     * if open-fd-count is > 1 +     * if open-fd-count is > 1 for metadata transactions and if num-inodelks > 1 +     * for data transactions       */ -    if (local->inode_ctx->open_fd_count > 1) -        return _gf_true; +    if (local->transaction.type == AFR_METADATA_TRANSACTION) { +        if (local->inode_ctx->open_fd_count > 1) { +            return _gf_true; +        } +    } else if (local->transaction.type == AFR_DATA_TRANSACTION) { +        if (lock->num_inodelks > 1) { +            return _gf_true; +        } +    }      return _gf_false;  } @@ -1947,7 +1958,7 @@ afr_is_delayed_changelog_post_op_needed(call_frame_t *frame, xlator_t *this,          goto out;      } -    if (afr_are_multiple_fds_opened(local, this)) { +    if (afr_are_conflicting_ops_waiting(local, this)) {          lock->release = _gf_true;          goto out;      } diff --git a/xlators/cluster/afr/src/afr.h b/xlators/cluster/afr/src/afr.h index 3395507ab90..6252f91736a 100644 --- a/xlators/cluster/afr/src/afr.h +++ b/xlators/cluster/afr/src/afr.h @@ -342,6 +342,12 @@ typedef enum {  } afr_fop_lock_state_t;  typedef struct _afr_inode_lock_t { +    /* @num_inodelks: +       Number of inodelks queried from the server, as queried through +       xdata in FOPs. Currently, used to decide if eager-locking must be +       temporarily disabled. +    */ +    int32_t num_inodelks;      unsigned int event_generation;      gf_boolean_t release;      gf_boolean_t acquired; @@ -393,6 +399,8 @@ typedef struct _afr_local {      uint32_t open_fd_count;      gf_boolean_t update_open_fd_count; +    int32_t num_inodelks; +    gf_boolean_t update_num_inodelks;      gf_lkowner_t saved_lk_owner;  | 
