summaryrefslogtreecommitdiffstats
path: root/xlators/cluster/afr
diff options
context:
space:
mode:
Diffstat (limited to 'xlators/cluster/afr')
-rw-r--r--xlators/cluster/afr/src/afr-inode-write.c22
-rw-r--r--xlators/cluster/afr/src/afr-transaction.c23
-rw-r--r--xlators/cluster/afr/src/afr.h8
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;