summaryrefslogtreecommitdiffstats
path: root/xlators/features
diff options
context:
space:
mode:
Diffstat (limited to 'xlators/features')
-rw-r--r--xlators/features/marker/src/marker-quota-helper.c1
-rw-r--r--xlators/features/marker/src/marker-quota.c132
-rw-r--r--xlators/features/marker/src/marker-quota.h1
3 files changed, 122 insertions, 12 deletions
diff --git a/xlators/features/marker/src/marker-quota-helper.c b/xlators/features/marker/src/marker-quota-helper.c
index a559da808..e1c803626 100644
--- a/xlators/features/marker/src/marker-quota-helper.c
+++ b/xlators/features/marker/src/marker-quota-helper.c
@@ -119,6 +119,7 @@ quota_alloc_inode_ctx ()
ctx->size = 0;
ctx->dirty = 0;
+ ctx->updation_status = _gf_false;
LOCK_INIT (&ctx->lock);
INIT_LIST_HEAD (&ctx->contribution_head);
out:
diff --git a/xlators/features/marker/src/marker-quota.c b/xlators/features/marker/src/marker-quota.c
index 4978cd776..e1d77ae64 100644
--- a/xlators/features/marker/src/marker-quota.c
+++ b/xlators/features/marker/src/marker-quota.c
@@ -30,6 +30,70 @@
#include "marker-quota.h"
#include "marker-quota-helper.h"
+int32_t
+mq_get_ctx_updation_status (quota_inode_ctx_t *ctx,
+ gf_boolean_t *status)
+{
+ int32_t ret = -1;
+
+ GF_VALIDATE_OR_GOTO ("marker", ctx, out);
+ GF_VALIDATE_OR_GOTO ("marker", status, out);
+
+ LOCK (&ctx->lock);
+ {
+ *status = ctx->updation_status;
+ }
+ UNLOCK (&ctx->lock);
+
+ ret = 0;
+out:
+ return ret;
+}
+
+
+int32_t
+mq_set_ctx_updation_status (quota_inode_ctx_t *ctx,
+ gf_boolean_t status)
+{
+ int32_t ret = -1;
+
+ if (ctx == NULL)
+ goto out;
+
+ LOCK (&ctx->lock);
+ {
+ ctx->updation_status = status;
+ }
+ UNLOCK (&ctx->lock);
+
+ ret = 0;
+out:
+ return ret;
+}
+
+int32_t
+mq_test_and_set_ctx_updation_status (quota_inode_ctx_t *ctx,
+ gf_boolean_t *status)
+{
+ int32_t ret = -1;
+ gf_boolean_t temp = _gf_false;
+
+ GF_VALIDATE_OR_GOTO ("marker", ctx, out);
+ GF_VALIDATE_OR_GOTO ("marker", status, out);
+
+ LOCK (&ctx->lock);
+ {
+ temp = *status;
+ *status = ctx->updation_status;
+ ctx->updation_status = temp;
+ }
+ UNLOCK (&ctx->lock);
+
+ ret = 0;
+out:
+ return ret;
+}
+
void
mq_assign_lk_owner (xlator_t *this, call_frame_t *frame)
{
@@ -669,6 +733,9 @@ err:
return 0;
}
+/* return 1 when dirty updation started
+ * 0 other wise
+ */
int32_t
update_dirty_inode (xlator_t *this,
loc_t *loc,
@@ -677,9 +744,16 @@ update_dirty_inode (xlator_t *this,
{
int32_t ret = -1;
quota_local_t *local = NULL;
+ gf_boolean_t status = _gf_false;
struct gf_flock lock = {0, };
call_frame_t *frame = NULL;
+ ret = mq_get_ctx_updation_status (ctx, &status);
+ if (ret == -1 || status == _gf_true) {
+ ret = 0;
+ goto out;
+ }
+
frame = create_frame (this, this->ctx->pool);
if (frame == NULL) {
ret = -1;
@@ -712,7 +786,7 @@ update_dirty_inode (xlator_t *this,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->inodelk,
this->name, &local->loc, F_SETLKW, &lock);
- return 0;
+ return 1;
fr_destroy:
QUOTA_STACK_DESTROY (frame, this);
@@ -1079,8 +1153,9 @@ int32_t
quota_inodelk_cbk (call_frame_t *frame, void *cookie,
xlator_t *this, int32_t op_ret, int32_t op_errno)
{
- int32_t ret = 0;
- quota_local_t *local = NULL;
+ int32_t ret = 0;
+ gf_boolean_t status = _gf_false;
+ quota_local_t *local = NULL;
local = frame->local;
@@ -1090,7 +1165,6 @@ quota_inodelk_cbk (call_frame_t *frame, void *cookie,
"unlocking failed on path (%s)(%s)",
local->parent_loc.path, strerror (op_errno));
}
-
xattr_updation_done (frame, NULL, this, 0, 0, NULL);
return 0;
@@ -1108,8 +1182,14 @@ quota_inodelk_cbk (call_frame_t *frame, void *cookie,
xattr_updation_done (frame, NULL, this, 0, 0, NULL);
goto out;
}
+ status = _gf_true;
- get_lock_on_parent (frame, this);
+ ret = mq_test_and_set_ctx_updation_status (local->ctx, &status);
+ if (ret == 0 && status == _gf_false) {
+ get_lock_on_parent (frame, this);
+ } else {
+ xattr_updation_done (frame, NULL, this, 0, 0, NULL);
+ }
}
out:
return 0;
@@ -1521,6 +1601,8 @@ quota_fetch_child_size_and_contri (call_frame_t *frame, void *cookie,
ret = dict_set_int64 (newdict, contri_key, 0);
+ mq_set_ctx_updation_status (local->ctx, _gf_false);
+
STACK_WIND (frame, quota_update_inode_contribution, FIRST_CHILD(this),
FIRST_CHILD(this)->fops->lookup, &local->loc, newdict);
@@ -1530,6 +1612,8 @@ err:
if ((op_ret == -1) || (ret == -1)) {
local->err = op_errno;
+ mq_set_ctx_updation_status (local->ctx, _gf_false);
+
quota_release_parent_lock (frame, NULL, this, 0, 0);
}
@@ -1557,6 +1641,8 @@ quota_markdirty (call_frame_t *frame, void *cookie,
local->err = op_errno;
+ mq_set_ctx_updation_status (local->ctx, _gf_false);
+
quota_inodelk_cbk (frame, NULL, this, 0, 0);
return 0;
@@ -1587,6 +1673,8 @@ err:
if (ret == -1) {
local->err = 1;
+ mq_set_ctx_updation_status (local->ctx, _gf_false);
+
quota_release_parent_lock (frame, NULL, this, 0, 0);
}
@@ -1625,7 +1713,7 @@ get_lock_on_parent (call_frame_t *frame, xlator_t *this)
fr_destroy:
QUOTA_STACK_DESTROY (frame, this);
- return 0;
+ return -1;
}
@@ -1662,14 +1750,17 @@ start_quota_txn (xlator_t *this, loc_t *loc,
local->ctx = ctx;
local->contri = contri;
- get_lock_on_parent (frame, this);
+ ret = get_lock_on_parent (frame, this);
+ if (ret == -1)
+ goto err;
return 0;
fr_destroy:
QUOTA_STACK_DESTROY (frame, this);
-
err:
+ mq_set_ctx_updation_status (ctx, _gf_false);
+
return -1;
}
@@ -1678,6 +1769,7 @@ int
initiate_quota_txn (xlator_t *this, loc_t *loc)
{
int32_t ret = -1;
+ gf_boolean_t status = _gf_false;
quota_inode_ctx_t *ctx = NULL;
inode_contribution_t *contribution = NULL;
@@ -1695,9 +1787,22 @@ initiate_quota_txn (xlator_t *this, loc_t *loc)
if (contribution == NULL)
goto out;
- start_quota_txn (this, loc, ctx, contribution);
+ /* To improve performance, donot start another transaction
+ * if one is already in progress for same inode
+ */
+ status = _gf_true;
+
+ ret = mq_test_and_set_ctx_updation_status (ctx, &status);
+ if (ret < 0)
+ goto out;
+
+ if (status == _gf_false) {
+ start_quota_txn (this, loc, ctx, contribution);
+ }
+
+ ret = 0;
out:
- return 0;
+ return ret;
}
@@ -1788,8 +1893,11 @@ inspect_directory_xattr (xlator_t *this,
" contri=%"PRId64, size_int, contri_int);
if (dirty) {
- update_dirty_inode (this, loc, ctx, contribution);
- } else if ((not_root == _gf_true) && (size_int != contri_int)) {
+ ret = update_dirty_inode (this, loc, ctx, contribution);
+ }
+
+ if ((!dirty || ret == 0) && (not_root == _gf_true) &&
+ (size_int != contri_int)) {
initiate_quota_txn (this, loc);
}
diff --git a/xlators/features/marker/src/marker-quota.h b/xlators/features/marker/src/marker-quota.h
index 384a96ccc..c5eee41f9 100644
--- a/xlators/features/marker/src/marker-quota.h
+++ b/xlators/features/marker/src/marker-quota.h
@@ -91,6 +91,7 @@
struct quota_inode_ctx {
int64_t size;
int8_t dirty;
+ gf_boolean_t updation_status;
gf_lock_t lock;
struct list_head contribution_head;
};