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; |