7f4c2a
From 648be4ccf9e3f077ec0e9849e99c6be98769716f Mon Sep 17 00:00:00 2001
7f4c2a
From: vmallika <vmallika@redhat.com>
7f4c2a
Date: Mon, 29 Jun 2015 19:12:28 +0530
7f4c2a
Subject: [PATCH 210/212] quota/marker: fix mem leak in marker
7f4c2a
7f4c2a
This is a backport of http://review.gluster.org/#/c/11457/
7f4c2a
7f4c2a
Problem-1)
7f4c2a
Now the marker accounting happens in background,
7f4c2a
There is a possibility that before completing
7f4c2a
create_xattr_txn another create txn can be initiated
7f4c2a
for the same inode.
7f4c2a
suppose if few 100 txns are initiated
7f4c2a
before completion, this can block all synctask threads
7f4c2a
waiting on a lock and this can also consume lot of memory
7f4c2a
and can take more time to complete the background accounting
7f4c2a
operation.
7f4c2a
7f4c2a
This patch improves the locking mechanism which
7f4c2a
can improve the performance as well reduce memory
7f4c2a
consumption
7f4c2a
7f4c2a
Problem-2)
7f4c2a
For every lookup and for all inodes in readdirp
7f4c2a
we were initiating a new txn, this can result
7f4c2a
in more txn pending in synctask queue and
7f4c2a
lead to huge memory consumption. inspect
7f4c2a
file/dir should start a txn only if there
7f4c2a
is some delta
7f4c2a
7f4c2a
Problem-3)
7f4c2a
When there are multiple write operations on
7f4c2a
same inode and all the synctask threads are busy.
7f4c2a
As we are checking for updation_status
7f4c2a
flag in background, all txn will be move to synctask queue.
7f4c2a
This can increase the mem usage.
7f4c2a
7f4c2a
Only one txn for inode in a queue will be sufficient,
7f4c2a
so check and set updation falg before moving txn to
7f4c2a
background
7f4c2a
7f4c2a
> Change-Id: Ic42ce00f0a50ce51c7128ba68a1b6a0699a1cd14
7f4c2a
> BUG: 1207735
7f4c2a
> Signed-off-by: vmallika <vmallika@redhat.com>
7f4c2a
7f4c2a
Change-Id: Iee464d51d4ebe70c2ec7cf66540198f8af16f57e
7f4c2a
BUG: 1224177
7f4c2a
Signed-off-by: vmallika <vmallika@redhat.com>
7f4c2a
Reviewed-on: https://code.engineering.redhat.com/gerrit/52303
7f4c2a
Reviewed-by: Raghavendra Gowdappa <rgowdapp@redhat.com>
7f4c2a
Tested-by: Raghavendra Gowdappa <rgowdapp@redhat.com>
7f4c2a
---
7f4c2a
 xlators/features/marker/src/marker-quota.c |  389 ++++++++++++++++------------
7f4c2a
 xlators/features/marker/src/marker-quota.h |    6 +-
7f4c2a
 2 files changed, 224 insertions(+), 171 deletions(-)
7f4c2a
7f4c2a
diff --git a/xlators/features/marker/src/marker-quota.c b/xlators/features/marker/src/marker-quota.c
7f4c2a
index 0b015ef..97946f8 100644
7f4c2a
--- a/xlators/features/marker/src/marker-quota.c
7f4c2a
+++ b/xlators/features/marker/src/marker-quota.c
7f4c2a
@@ -128,6 +128,49 @@ out:
7f4c2a
         return ret;
7f4c2a
 }
7f4c2a
 
7f4c2a
+int32_t
7f4c2a
+mq_set_ctx_create_status (quota_inode_ctx_t *ctx,
7f4c2a
+                          gf_boolean_t status)
7f4c2a
+{
7f4c2a
+        int32_t   ret = -1;
7f4c2a
+
7f4c2a
+        if (ctx == NULL)
7f4c2a
+                goto out;
7f4c2a
+
7f4c2a
+        LOCK (&ctx->lock);
7f4c2a
+        {
7f4c2a
+                ctx->create_status = status;
7f4c2a
+        }
7f4c2a
+        UNLOCK (&ctx->lock);
7f4c2a
+
7f4c2a
+        ret = 0;
7f4c2a
+out:
7f4c2a
+        return ret;
7f4c2a
+}
7f4c2a
+
7f4c2a
+int32_t
7f4c2a
+mq_test_and_set_ctx_create_status (quota_inode_ctx_t *ctx,
7f4c2a
+                                   gf_boolean_t *status)
7f4c2a
+{
7f4c2a
+        int32_t         ret     = -1;
7f4c2a
+        gf_boolean_t    temp    = _gf_false;
7f4c2a
+
7f4c2a
+        GF_VALIDATE_OR_GOTO ("marker", ctx, out);
7f4c2a
+        GF_VALIDATE_OR_GOTO ("marker", status, out);
7f4c2a
+
7f4c2a
+        LOCK (&ctx->lock);
7f4c2a
+        {
7f4c2a
+                temp = *status;
7f4c2a
+                *status = ctx->create_status;
7f4c2a
+                ctx->create_status = temp;
7f4c2a
+        }
7f4c2a
+        UNLOCK (&ctx->lock);
7f4c2a
+
7f4c2a
+        ret = 0;
7f4c2a
+out:
7f4c2a
+        return ret;
7f4c2a
+}
7f4c2a
+
7f4c2a
 void
7f4c2a
 mq_assign_lk_owner (xlator_t *this, call_frame_t *frame)
7f4c2a
 {
7f4c2a
@@ -2184,30 +2227,19 @@ out:
7f4c2a
 }
7f4c2a
 
7f4c2a
 int32_t
7f4c2a
-mq_create_xattrs (xlator_t *this, loc_t *loc, gf_boolean_t objects)
7f4c2a
+mq_create_xattrs (xlator_t *this, quota_inode_ctx_t *ctx, loc_t *loc,
7f4c2a
+                  gf_boolean_t objects)
7f4c2a
 {
7f4c2a
         quota_meta_t           size                 = {0, };
7f4c2a
         quota_meta_t           contri               = {0, };
7f4c2a
         int32_t                ret                  = -1;
7f4c2a
         char                   key[CONTRI_KEY_MAX]  = {0, };
7f4c2a
         dict_t                *dict                 = NULL;
7f4c2a
-        quota_inode_ctx_t     *ctx                  = NULL;
7f4c2a
         inode_contribution_t  *contribution         = NULL;
7f4c2a
 
7f4c2a
         GF_VALIDATE_OR_GOTO ("marker", loc, out);
7f4c2a
         GF_VALIDATE_OR_GOTO ("marker", loc->inode, out);
7f4c2a
 
7f4c2a
-        ret = mq_inode_ctx_get (loc->inode, this, &ctx;;
7f4c2a
-        if (ret < 0) {
7f4c2a
-                ctx = mq_inode_ctx_new (loc->inode, this);
7f4c2a
-                if (ctx == NULL) {
7f4c2a
-                        gf_log (this->name, GF_LOG_WARNING,
7f4c2a
-                                "mq_inode_ctx_new failed");
7f4c2a
-                        ret = -1;
7f4c2a
-                        goto out;
7f4c2a
-                }
7f4c2a
-        }
7f4c2a
-
7f4c2a
         dict = dict_new ();
7f4c2a
         if (!dict) {
7f4c2a
                 gf_log (this->name, GF_LOG_ERROR, "dict_new failed");
7f4c2a
@@ -2765,8 +2797,6 @@ mq_synctask_cleanup (int ret, call_frame_t *frame, void *opaque)
7f4c2a
 
7f4c2a
         args = (quota_synctask_t *) opaque;
7f4c2a
         loc_wipe (&args->loc);
7f4c2a
-        if (args->dict)
7f4c2a
-                dict_unref (args->dict);
7f4c2a
 
7f4c2a
         if (!args->is_static)
7f4c2a
                 GF_FREE (args);
7f4c2a
@@ -2776,7 +2806,7 @@ mq_synctask_cleanup (int ret, call_frame_t *frame, void *opaque)
7f4c2a
 
7f4c2a
 int
7f4c2a
 mq_synctask (xlator_t *this, synctask_fn_t task, gf_boolean_t spawn, loc_t *loc,
7f4c2a
-             dict_t *dict, struct iatt *buf, int64_t contri)
7f4c2a
+             int64_t contri)
7f4c2a
 {
7f4c2a
         int32_t              ret         = -1;
7f4c2a
         quota_synctask_t    *args        = NULL;
7f4c2a
@@ -2793,11 +2823,6 @@ mq_synctask (xlator_t *this, synctask_fn_t task, gf_boolean_t spawn, loc_t *loc,
7f4c2a
         args->this = this;
7f4c2a
         loc_copy (&args->loc, loc);
7f4c2a
         args->contri = contri;
7f4c2a
-        if (dict)
7f4c2a
-                args->dict = dict_ref (dict);
7f4c2a
-        if (buf)
7f4c2a
-                args->buf = *buf;
7f4c2a
-
7f4c2a
 
7f4c2a
         if (spawn) {
7f4c2a
                 ret = synctask_new (this->ctx->env, task, mq_synctask_cleanup,
7f4c2a
@@ -2825,7 +2850,7 @@ mq_start_quota_txn_v2 (xlator_t *this, loc_t *loc, quota_inode_ctx_t *ctx,
7f4c2a
         loc_t              parent_loc = {0,};
7f4c2a
         gf_boolean_t       locked     = _gf_false;
7f4c2a
         gf_boolean_t       dirty      = _gf_false;
7f4c2a
-        gf_boolean_t       status     = _gf_true;
7f4c2a
+        gf_boolean_t       status     = _gf_false;
7f4c2a
         quota_meta_t       delta      = {0, };
7f4c2a
 
7f4c2a
         GF_VALIDATE_OR_GOTO ("marker", contri, out);
7f4c2a
@@ -2855,9 +2880,16 @@ mq_start_quota_txn_v2 (xlator_t *this, loc_t *loc, quota_inode_ctx_t *ctx,
7f4c2a
                 /* To improve performance, abort current transaction
7f4c2a
                  * if one is already in progress for same inode
7f4c2a
                  */
7f4c2a
-                ret = mq_test_and_set_ctx_updation_status (ctx, &status);
7f4c2a
-                if (ret < 0 || status == _gf_true)
7f4c2a
-                        goto out;
7f4c2a
+                if (status == _gf_true) {
7f4c2a
+                        /* status will alreday set before txn start,
7f4c2a
+                         * so it should not be set in first
7f4c2a
+                         * loop iteration
7f4c2a
+                         */
7f4c2a
+                        ret = mq_test_and_set_ctx_updation_status (ctx,
7f4c2a
+                                                                   &status);
7f4c2a
+                        if (ret < 0 || status == _gf_true)
7f4c2a
+                                goto out;
7f4c2a
+                }
7f4c2a
 
7f4c2a
                 ret = mq_inode_loc_fill (NULL, child_loc.parent, &parent_loc);
7f4c2a
                 if (ret < 0) {
7f4c2a
@@ -2941,7 +2973,7 @@ out:
7f4c2a
         if (locked)
7f4c2a
                 ret = mq_lock (this, &parent_loc, F_UNLCK);
7f4c2a
 
7f4c2a
-        if (status == _gf_false)
7f4c2a
+        if (ctx && status == _gf_false)
7f4c2a
                 mq_set_ctx_updation_status (ctx, _gf_false);
7f4c2a
 
7f4c2a
         loc_wipe (&child_loc);
7f4c2a
@@ -2949,7 +2981,7 @@ out:
7f4c2a
         if (contri)
7f4c2a
                 GF_REF_PUT (contri);
7f4c2a
 
7f4c2a
-        return ret;
7f4c2a
+        return 0;
7f4c2a
 }
7f4c2a
 
7f4c2a
 int
7f4c2a
@@ -2961,8 +2993,10 @@ mq_create_xattrs_task (void *opaque)
7f4c2a
         gf_boolean_t             objects    = _gf_false;
7f4c2a
         gf_boolean_t             need_txn   = _gf_false;
7f4c2a
         quota_synctask_t        *args       = NULL;
7f4c2a
+        quota_inode_ctx_t       *ctx        = NULL;
7f4c2a
         xlator_t                *this       = NULL;
7f4c2a
         loc_t                   *loc        = NULL;
7f4c2a
+        gf_boolean_t             status     = _gf_false;
7f4c2a
 
7f4c2a
         GF_ASSERT (opaque);
7f4c2a
 
7f4c2a
@@ -2981,16 +3015,29 @@ mq_create_xattrs_task (void *opaque)
7f4c2a
                 goto out;
7f4c2a
         }
7f4c2a
 
7f4c2a
-        ret = mq_lock (this, loc, F_WRLCK);
7f4c2a
-        if (ret < 0)
7f4c2a
+        ret = mq_inode_ctx_get (loc->inode, this, &ctx;;
7f4c2a
+        if (ret < 0) {
7f4c2a
+                gf_log (this->name, GF_LOG_WARNING, "Failed to"
7f4c2a
+                        "get inode ctx, aborting quota create txn");
7f4c2a
                 goto out;
7f4c2a
-        locked = _gf_true;
7f4c2a
+        }
7f4c2a
+
7f4c2a
+        if (loc->inode->ia_type == IA_IFDIR) {
7f4c2a
+                /* lock not required for files */
7f4c2a
+                ret = mq_lock (this, loc, F_WRLCK);
7f4c2a
+                if (ret < 0)
7f4c2a
+                        goto out;
7f4c2a
+                locked = _gf_true;
7f4c2a
+        }
7f4c2a
 
7f4c2a
         ret = mq_are_xattrs_set (this, loc, &xattrs_set, &objects);
7f4c2a
         if (ret < 0 || xattrs_set)
7f4c2a
                 goto out;
7f4c2a
 
7f4c2a
-        ret = mq_create_xattrs (this, loc, objects);
7f4c2a
+        mq_set_ctx_create_status (ctx, _gf_false);
7f4c2a
+        status = _gf_true;
7f4c2a
+
7f4c2a
+        ret = mq_create_xattrs (this, ctx, loc, objects);
7f4c2a
         if (ret < 0)
7f4c2a
                 goto out;
7f4c2a
 
7f4c2a
@@ -2999,12 +3046,44 @@ out:
7f4c2a
         if (locked)
7f4c2a
                 ret = mq_lock (this, loc, F_UNLCK);
7f4c2a
 
7f4c2a
+        if (status == _gf_false)
7f4c2a
+                mq_set_ctx_create_status (ctx, _gf_false);
7f4c2a
+
7f4c2a
         if (need_txn)
7f4c2a
                 ret = mq_initiate_quota_blocking_txn (this, loc);
7f4c2a
 
7f4c2a
         return ret;
7f4c2a
 }
7f4c2a
 
7f4c2a
+static int
7f4c2a
+_mq_create_xattrs_txn (xlator_t *this, loc_t *loc, gf_boolean_t spawn)
7f4c2a
+{
7f4c2a
+        int32_t                  ret        = -1;
7f4c2a
+        quota_inode_ctx_t       *ctx        = NULL;
7f4c2a
+        gf_boolean_t             status     = _gf_true;
7f4c2a
+
7f4c2a
+        ret = mq_inode_ctx_get (loc->inode, this, &ctx;;
7f4c2a
+        if (ret < 0) {
7f4c2a
+                ctx = mq_inode_ctx_new (loc->inode, this);
7f4c2a
+                if (ctx == NULL) {
7f4c2a
+                        gf_log (this->name, GF_LOG_WARNING,
7f4c2a
+                                "mq_inode_ctx_new failed");
7f4c2a
+                        ret = -1;
7f4c2a
+                        goto out;
7f4c2a
+                }
7f4c2a
+        }
7f4c2a
+
7f4c2a
+        ret = mq_test_and_set_ctx_create_status (ctx, &status);
7f4c2a
+        if (ret < 0 || status == _gf_true)
7f4c2a
+                goto out;
7f4c2a
+
7f4c2a
+        ret = mq_synctask (this, mq_create_xattrs_task, spawn, loc, 0);
7f4c2a
+out:
7f4c2a
+        if (ret < 0 && status == _gf_false)
7f4c2a
+                mq_set_ctx_create_status (ctx, _gf_false);
7f4c2a
+
7f4c2a
+        return ret;
7f4c2a
+}
7f4c2a
 int
7f4c2a
 mq_create_xattrs_txn (xlator_t *this, loc_t *loc)
7f4c2a
 {
7f4c2a
@@ -3013,8 +3092,7 @@ mq_create_xattrs_txn (xlator_t *this, loc_t *loc)
7f4c2a
         GF_VALIDATE_OR_GOTO ("marker", loc, out);
7f4c2a
         GF_VALIDATE_OR_GOTO ("marker", loc->inode, out);
7f4c2a
 
7f4c2a
-        ret = mq_synctask (this, mq_create_xattrs_task, _gf_true, loc, NULL,
7f4c2a
-                           NULL, 0);
7f4c2a
+        ret = _mq_create_xattrs_txn (this, loc, _gf_true);
7f4c2a
 out:
7f4c2a
         return ret;
7f4c2a
 }
7f4c2a
@@ -3027,8 +3105,7 @@ mq_create_xattrs_blocking_txn (xlator_t *this, loc_t *loc)
7f4c2a
         GF_VALIDATE_OR_GOTO ("marker", loc, out);
7f4c2a
         GF_VALIDATE_OR_GOTO ("marker", loc->inode, out);
7f4c2a
 
7f4c2a
-        ret = mq_synctask (this, mq_create_xattrs_task, _gf_false, loc, NULL,
7f4c2a
-                           NULL, 0);
7f4c2a
+        ret = _mq_create_xattrs_txn (this, loc, _gf_false);
7f4c2a
 out:
7f4c2a
         return ret;
7f4c2a
 }
7f4c2a
@@ -3169,7 +3246,7 @@ mq_reduce_parent_size_txn (xlator_t *this, loc_t *loc, int64_t contri)
7f4c2a
         GF_VALIDATE_OR_GOTO ("marker", loc->inode, out);
7f4c2a
 
7f4c2a
         ret = mq_synctask (this, mq_reduce_parent_size_task, _gf_true, loc,
7f4c2a
-                           NULL, NULL, contri);
7f4c2a
+                           contri);
7f4c2a
 out:
7f4c2a
         return ret;
7f4c2a
 }
7f4c2a
@@ -3195,7 +3272,6 @@ mq_initiate_quota_task (void *opaque)
7f4c2a
         if (ret == -1) {
7f4c2a
                 gf_log (this->name, GF_LOG_WARNING,
7f4c2a
                         "inode ctx get failed, aborting quota txn");
7f4c2a
-                ret = -1;
7f4c2a
                 goto out;
7f4c2a
         }
7f4c2a
 
7f4c2a
@@ -3230,6 +3306,7 @@ mq_initiate_quota_task (void *opaque)
7f4c2a
                                                   loc->parent ?
7f4c2a
                                                  uuid_utoa (loc->parent->gfid) :
7f4c2a
                                                   NULL);
7f4c2a
+                        ret = -1;
7f4c2a
                         goto out;
7f4c2a
                 }
7f4c2a
         }
7f4c2a
@@ -3241,6 +3318,36 @@ out:
7f4c2a
         if (contribution)
7f4c2a
                 GF_REF_PUT (contribution);
7f4c2a
 
7f4c2a
+        if (ctx && ret < 0)
7f4c2a
+                mq_set_ctx_updation_status (ctx, _gf_false);
7f4c2a
+
7f4c2a
+        return ret;
7f4c2a
+}
7f4c2a
+
7f4c2a
+int
7f4c2a
+_mq_initiate_quota_txn (xlator_t *this, loc_t *loc, gf_boolean_t spawn)
7f4c2a
+{
7f4c2a
+        int32_t                 ret          = -1;
7f4c2a
+        quota_inode_ctx_t      *ctx          = NULL;
7f4c2a
+        gf_boolean_t            status       = _gf_true;
7f4c2a
+
7f4c2a
+        ret = mq_inode_ctx_get (loc->inode, this, &ctx;;
7f4c2a
+        if (ret == -1) {
7f4c2a
+                gf_log (this->name, GF_LOG_WARNING,
7f4c2a
+                        "inode ctx get failed, aborting quota txn");
7f4c2a
+                goto out;
7f4c2a
+        }
7f4c2a
+
7f4c2a
+        ret = mq_test_and_set_ctx_updation_status (ctx, &status);
7f4c2a
+        if (ret < 0 || status == _gf_true)
7f4c2a
+                goto out;
7f4c2a
+
7f4c2a
+        ret = mq_synctask (this, mq_initiate_quota_task, spawn, loc, 0);
7f4c2a
+
7f4c2a
+out:
7f4c2a
+        if (ret < 0 && status == _gf_false)
7f4c2a
+                mq_set_ctx_updation_status (ctx, _gf_false);
7f4c2a
+
7f4c2a
         return ret;
7f4c2a
 }
7f4c2a
 
7f4c2a
@@ -3253,8 +3360,7 @@ mq_initiate_quota_txn (xlator_t *this, loc_t *loc)
7f4c2a
         GF_VALIDATE_OR_GOTO ("marker", loc, out);
7f4c2a
         GF_VALIDATE_OR_GOTO ("marker", loc->inode, out);
7f4c2a
 
7f4c2a
-        ret = mq_synctask (this, mq_initiate_quota_task, _gf_true, loc, NULL,
7f4c2a
-                           NULL, 0);
7f4c2a
+        ret = _mq_initiate_quota_txn (this, loc, _gf_true);
7f4c2a
 out:
7f4c2a
         return ret;
7f4c2a
 }
7f4c2a
@@ -3268,43 +3374,38 @@ mq_initiate_quota_blocking_txn (xlator_t *this, loc_t *loc)
7f4c2a
         GF_VALIDATE_OR_GOTO ("marker", loc, out);
7f4c2a
         GF_VALIDATE_OR_GOTO ("marker", loc->inode, out);
7f4c2a
 
7f4c2a
-        ret = mq_synctask (this, mq_initiate_quota_task, _gf_false, loc, NULL,
7f4c2a
-                           NULL, 0);
7f4c2a
+        ret = _mq_initiate_quota_txn (this, loc, _gf_false);
7f4c2a
 out:
7f4c2a
         return ret;
7f4c2a
 }
7f4c2a
 
7f4c2a
-/* return 1 when dirty updation is performed
7f4c2a
- * return 0 other wise
7f4c2a
- */
7f4c2a
-int32_t
7f4c2a
-mq_update_dirty_inode_v2 (xlator_t *this, loc_t *loc, quota_inode_ctx_t *ctx,
7f4c2a
-                          inode_contribution_t *contribution)
7f4c2a
+int
7f4c2a
+mq_update_dirty_inode_task (void *opaque)
7f4c2a
 {
7f4c2a
-        int32_t          ret            = -1;
7f4c2a
-        fd_t            *fd             = NULL;
7f4c2a
-        off_t            offset         = 0;
7f4c2a
-        loc_t            child_loc      = {0, };
7f4c2a
-        gf_dirent_t      entries;
7f4c2a
-        gf_dirent_t     *entry          = NULL;
7f4c2a
-        gf_boolean_t     status         = _gf_true;
7f4c2a
-        gf_boolean_t     locked         = _gf_false;
7f4c2a
-        gf_boolean_t     free_entries   = _gf_false;
7f4c2a
-        gf_boolean_t     updated        = _gf_false;
7f4c2a
-        int32_t          dirty          = 0;
7f4c2a
-        quota_meta_t     contri         = {0, };
7f4c2a
-        quota_meta_t     size           = {0, };
7f4c2a
-        quota_meta_t     contri_sum     = {0, };
7f4c2a
-        quota_meta_t     delta          = {0, };
7f4c2a
+        int32_t               ret            = -1;
7f4c2a
+        fd_t                 *fd             = NULL;
7f4c2a
+        off_t                 offset         = 0;
7f4c2a
+        loc_t                 child_loc      = {0, };
7f4c2a
+        gf_dirent_t           entries;
7f4c2a
+        gf_dirent_t          *entry          = NULL;
7f4c2a
+        gf_boolean_t          locked         = _gf_false;
7f4c2a
+        gf_boolean_t          free_entries   = _gf_false;
7f4c2a
+        gf_boolean_t          updated        = _gf_false;
7f4c2a
+        int32_t               dirty          = 0;
7f4c2a
+        quota_meta_t          contri         = {0, };
7f4c2a
+        quota_meta_t          size           = {0, };
7f4c2a
+        quota_meta_t          contri_sum     = {0, };
7f4c2a
+        quota_meta_t          delta          = {0, };
7f4c2a
+        quota_synctask_t     *args           = NULL;
7f4c2a
+        xlator_t             *this           = NULL;
7f4c2a
+        loc_t                *loc            = NULL;
7f4c2a
 
7f4c2a
-        GF_VALIDATE_OR_GOTO ("marker", loc, out);
7f4c2a
-        GF_VALIDATE_OR_GOTO ("marker", loc->inode, out);
7f4c2a
+        GF_ASSERT (opaque);
7f4c2a
 
7f4c2a
-        ret = mq_get_ctx_updation_status (ctx, &status);
7f4c2a
-        if (ret == -1 || status == _gf_true) {
7f4c2a
-                ret = 0;
7f4c2a
-                goto out;
7f4c2a
-        }
7f4c2a
+        args = (quota_synctask_t *) opaque;
7f4c2a
+        loc = &args->loc;
7f4c2a
+        this = args->this;
7f4c2a
+        THIS = this;
7f4c2a
 
7f4c2a
         if (gf_uuid_is_null (loc->gfid))
7f4c2a
                 gf_uuid_copy (loc->gfid, loc->inode->gfid);
7f4c2a
@@ -3431,19 +3532,31 @@ out:
7f4c2a
         if (locked)
7f4c2a
                 mq_lock (this, loc, F_UNLCK);
7f4c2a
 
7f4c2a
-        if (status == _gf_false)
7f4c2a
-                mq_set_ctx_updation_status (ctx, _gf_false);
7f4c2a
-
7f4c2a
         loc_wipe(&child_loc);
7f4c2a
 
7f4c2a
         if (updated)
7f4c2a
-                return 1;
7f4c2a
-        else
7f4c2a
-                return 0;
7f4c2a
+                mq_initiate_quota_blocking_txn (this, loc);
7f4c2a
+
7f4c2a
+        return ret;
7f4c2a
 }
7f4c2a
 
7f4c2a
 int32_t
7f4c2a
-mq_inspect_directory_xattr_task (void *opaque)
7f4c2a
+mq_update_dirty_inode_txn (xlator_t *this, loc_t *loc)
7f4c2a
+{
7f4c2a
+        int32_t          ret            = -1;
7f4c2a
+
7f4c2a
+        GF_VALIDATE_OR_GOTO ("marker", loc, out);
7f4c2a
+        GF_VALIDATE_OR_GOTO ("marker", loc->inode, out);
7f4c2a
+
7f4c2a
+        ret = mq_synctask (this, mq_update_dirty_inode_task, _gf_true,
7f4c2a
+                           loc, 0);
7f4c2a
+out:
7f4c2a
+        return ret;
7f4c2a
+}
7f4c2a
+
7f4c2a
+int32_t
7f4c2a
+mq_inspect_directory_xattr (xlator_t *this, loc_t *loc, quota_inode_ctx_t *ctx,
7f4c2a
+                            dict_t *dict, struct iatt buf)
7f4c2a
 {
7f4c2a
         int32_t               ret                          = 0;
7f4c2a
         int8_t                dirty                        = -1;
7f4c2a
@@ -3451,31 +3564,7 @@ mq_inspect_directory_xattr_task (void *opaque)
7f4c2a
         quota_meta_t          contri                       = {0, };
7f4c2a
         quota_meta_t          delta                        = {0, };
7f4c2a
         char                  contri_key[CONTRI_KEY_MAX]   = {0, };
7f4c2a
-        quota_inode_ctx_t    *ctx                          = NULL;
7f4c2a
         inode_contribution_t *contribution                 = NULL;
7f4c2a
-        quota_synctask_t     *args                         = NULL;
7f4c2a
-        xlator_t             *this                         = NULL;
7f4c2a
-        loc_t                *loc                          = NULL;
7f4c2a
-        dict_t               *dict                         = NULL;
7f4c2a
-
7f4c2a
-        GF_ASSERT (opaque);
7f4c2a
-
7f4c2a
-        args = (quota_synctask_t *) opaque;
7f4c2a
-        loc = &args->loc;
7f4c2a
-        dict = args->dict;
7f4c2a
-        this = args->this;
7f4c2a
-        THIS = this;
7f4c2a
-
7f4c2a
-        ret = mq_inode_ctx_get (loc->inode, this, &ctx;;
7f4c2a
-        if (ret < 0) {
7f4c2a
-                ctx = mq_inode_ctx_new (loc->inode, this);
7f4c2a
-                if (ctx == NULL) {
7f4c2a
-                        gf_log (this->name, GF_LOG_WARNING,
7f4c2a
-                                "mq_inode_ctx_new failed");
7f4c2a
-                        ret = -1;
7f4c2a
-                        goto err;
7f4c2a
-                }
7f4c2a
-        }
7f4c2a
 
7f4c2a
         if (!loc_is_root(loc)) {
7f4c2a
                 contribution = mq_add_new_contribution_node (this, ctx, loc);
7f4c2a
@@ -3485,7 +3574,7 @@ mq_inspect_directory_xattr_task (void *opaque)
7f4c2a
                                         "cannot add a new contribution node "
7f4c2a
                                         "(%s)", uuid_utoa (loc->inode->gfid));
7f4c2a
                         ret = -1;
7f4c2a
-                        goto err;
7f4c2a
+                        goto out;
7f4c2a
                 }
7f4c2a
         }
7f4c2a
 
7f4c2a
@@ -3506,7 +3595,7 @@ mq_inspect_directory_xattr_task (void *opaque)
7f4c2a
         if (!loc_is_root(loc)) {
7f4c2a
                 GET_CONTRI_KEY (contri_key, contribution->gfid, ret);
7f4c2a
                 if (ret < 0)
7f4c2a
-                        goto err;
7f4c2a
+                        goto out;
7f4c2a
 
7f4c2a
                 ret = _quota_dict_get_meta (this, dict, contri_key, &contri,
7f4c2a
                                             IA_IFDIR, _gf_false);
7f4c2a
@@ -3527,27 +3616,29 @@ mq_inspect_directory_xattr_task (void *opaque)
7f4c2a
                 ctx->size = size.size;
7f4c2a
                 ctx->file_count = size.file_count;
7f4c2a
                 ctx->dir_count = size.dir_count;
7f4c2a
-                ctx->dirty = dirty;
7f4c2a
         }
7f4c2a
         UNLOCK (&ctx->lock);
7f4c2a
 
7f4c2a
         mq_compute_delta (&delta, &size, &contri);
7f4c2a
 
7f4c2a
-        if (dirty)
7f4c2a
-                ret = mq_update_dirty_inode_v2 (this, loc, ctx, contribution);
7f4c2a
+        if (dirty) {
7f4c2a
+                if (ctx->dirty == 0)
7f4c2a
+                        ret = mq_update_dirty_inode_txn (this, loc);
7f4c2a
 
7f4c2a
-        if ((!dirty || ret == 1) &&
7f4c2a
-            !loc_is_root(loc) &&
7f4c2a
+                goto out;
7f4c2a
+        }
7f4c2a
+
7f4c2a
+        if (!loc_is_root(loc) &&
7f4c2a
             !quota_meta_is_null (&delta))
7f4c2a
-                mq_initiate_quota_blocking_txn (this, loc);
7f4c2a
+                mq_initiate_quota_txn (this, loc);
7f4c2a
 
7f4c2a
         ret = 0;
7f4c2a
 
7f4c2a
 create_xattr:
7f4c2a
         if (ret < 0)
7f4c2a
-                ret = mq_create_xattrs_blocking_txn (this, loc);
7f4c2a
+                ret = mq_create_xattrs_txn (this, loc);
7f4c2a
 
7f4c2a
-err:
7f4c2a
+out:
7f4c2a
         if (contribution)
7f4c2a
                 GF_REF_PUT (contribution);
7f4c2a
 
7f4c2a
@@ -3555,52 +3646,15 @@ err:
7f4c2a
 }
7f4c2a
 
7f4c2a
 int32_t
7f4c2a
-mq_inspect_directory_xattr_txn (xlator_t *this, loc_t *loc, dict_t *dict,
7f4c2a
-                                struct iatt buf)
7f4c2a
-{
7f4c2a
-        int32_t   ret = -1;
7f4c2a
-
7f4c2a
-        ret = mq_synctask (this, mq_inspect_directory_xattr_task, _gf_true,
7f4c2a
-                           loc, dict, &buf, 0);
7f4c2a
-
7f4c2a
-        return ret;
7f4c2a
-}
7f4c2a
-
7f4c2a
-int32_t
7f4c2a
-mq_inspect_file_xattr_task (void *opaque)
7f4c2a
+mq_inspect_file_xattr (xlator_t *this, quota_inode_ctx_t *ctx, loc_t *loc,
7f4c2a
+                       dict_t *dict, struct iatt buf)
7f4c2a
 {
7f4c2a
         int32_t               ret                          = -1;
7f4c2a
         quota_meta_t          size                         = {0, };
7f4c2a
         quota_meta_t          contri                       = {0, };
7f4c2a
         quota_meta_t          delta                        = {0, };
7f4c2a
         char                  contri_key[CONTRI_KEY_MAX]   = {0, };
7f4c2a
-        quota_inode_ctx_t    *ctx                          = NULL;
7f4c2a
         inode_contribution_t *contribution                 = NULL;
7f4c2a
-        quota_synctask_t     *args                         = NULL;
7f4c2a
-        xlator_t             *this                         = NULL;
7f4c2a
-        loc_t                *loc                          = NULL;
7f4c2a
-        dict_t               *dict                         = NULL;
7f4c2a
-        struct iatt           buf                          = {0,};
7f4c2a
-
7f4c2a
-        GF_ASSERT (opaque);
7f4c2a
-
7f4c2a
-        args = (quota_synctask_t *) opaque;
7f4c2a
-        loc = &args->loc;
7f4c2a
-        dict = args->dict;
7f4c2a
-        buf = args->buf;
7f4c2a
-        this = args->this;
7f4c2a
-        THIS = this;
7f4c2a
-
7f4c2a
-        ret = mq_inode_ctx_get (loc->inode, this, &ctx;;
7f4c2a
-        if (ret < 0) {
7f4c2a
-                ctx = mq_inode_ctx_new (loc->inode, this);
7f4c2a
-                if (ctx == NULL) {
7f4c2a
-                        gf_log (this->name, GF_LOG_WARNING,
7f4c2a
-                                "mq_inode_ctx_new failed");
7f4c2a
-                        ret = -1;
7f4c2a
-                        goto out;
7f4c2a
-                }
7f4c2a
-        }
7f4c2a
 
7f4c2a
         contribution = mq_add_new_contribution_node (this, ctx, loc);
7f4c2a
         if (contribution == NULL) {
7f4c2a
@@ -3629,7 +3683,7 @@ mq_inspect_file_xattr_task (void *opaque)
7f4c2a
         ret = _quota_dict_get_meta (this, dict, contri_key, &contri,
7f4c2a
                                     IA_IFREG, _gf_true);
7f4c2a
         if (ret < 0) {
7f4c2a
-                ret = mq_create_xattrs_blocking_txn (this, loc);
7f4c2a
+                ret = mq_create_xattrs_txn (this, loc);
7f4c2a
         } else {
7f4c2a
                 LOCK (&contribution->lock);
7f4c2a
                 {
7f4c2a
@@ -3641,7 +3695,7 @@ mq_inspect_file_xattr_task (void *opaque)
7f4c2a
 
7f4c2a
                 mq_compute_delta (&delta, &size, &contri);
7f4c2a
                 if (!quota_meta_is_null (&delta))
7f4c2a
-                        mq_initiate_quota_blocking_txn (this, loc);
7f4c2a
+                        mq_initiate_quota_txn (this, loc);
7f4c2a
         }
7f4c2a
         /* TODO: revist this code when fixing hardlinks */
7f4c2a
 
7f4c2a
@@ -3653,27 +3707,30 @@ out:
7f4c2a
 }
7f4c2a
 
7f4c2a
 int32_t
7f4c2a
-mq_inspect_file_xattr_txn (xlator_t *this, loc_t *loc, dict_t *dict,
7f4c2a
-                           struct iatt buf)
7f4c2a
+mq_xattr_state (xlator_t *this, loc_t *loc, dict_t *dict, struct iatt buf)
7f4c2a
 {
7f4c2a
-        int32_t   ret = -1;
7f4c2a
+        int32_t               ret     = -1;
7f4c2a
+        quota_inode_ctx_t    *ctx     = NULL;
7f4c2a
 
7f4c2a
-        ret = mq_synctask (this, mq_inspect_file_xattr_task, _gf_true,
7f4c2a
-                           loc, dict, &buf, 0);
7f4c2a
-
7f4c2a
-        return ret;
7f4c2a
-}
7f4c2a
+        ret = mq_inode_ctx_get (loc->inode, this, &ctx;;
7f4c2a
+        if (ret < 0) {
7f4c2a
+                ctx = mq_inode_ctx_new (loc->inode, this);
7f4c2a
+                if (ctx == NULL) {
7f4c2a
+                        gf_log (this->name, GF_LOG_WARNING,
7f4c2a
+                                "mq_inode_ctx_new failed");
7f4c2a
+                        ret = -1;
7f4c2a
+                        goto out;
7f4c2a
+                }
7f4c2a
+        }
7f4c2a
 
7f4c2a
-int32_t
7f4c2a
-mq_xattr_state (xlator_t *this, loc_t *loc, dict_t *dict, struct iatt buf)
7f4c2a
-{
7f4c2a
         if (((buf.ia_type == IA_IFREG) && !dht_is_linkfile (&buf, dict))
7f4c2a
             || (buf.ia_type == IA_IFLNK))  {
7f4c2a
-                mq_inspect_file_xattr_txn (this, loc, dict, buf);
7f4c2a
+                mq_inspect_file_xattr (this, ctx, loc, dict, buf);
7f4c2a
         } else if (buf.ia_type == IA_IFDIR)
7f4c2a
-                mq_inspect_directory_xattr_txn (this, loc, dict, buf);
7f4c2a
+                mq_inspect_directory_xattr (this, loc, ctx, dict, buf);
7f4c2a
 
7f4c2a
-        return 0;
7f4c2a
+out:
7f4c2a
+        return ret;
7f4c2a
 }
7f4c2a
 
7f4c2a
 int32_t
7f4c2a
diff --git a/xlators/features/marker/src/marker-quota.h b/xlators/features/marker/src/marker-quota.h
7f4c2a
index 2d03dfd..89ac559 100644
7f4c2a
--- a/xlators/features/marker/src/marker-quota.h
7f4c2a
+++ b/xlators/features/marker/src/marker-quota.h
7f4c2a
@@ -88,6 +88,7 @@ struct quota_inode_ctx {
7f4c2a
         int64_t                file_count;
7f4c2a
         int64_t                dir_count;
7f4c2a
         int8_t                 dirty;
7f4c2a
+        gf_boolean_t           create_status;
7f4c2a
         gf_boolean_t           updation_status;
7f4c2a
         gf_lock_t              lock;
7f4c2a
         struct list_head       contribution_head;
7f4c2a
@@ -97,8 +98,6 @@ typedef struct quota_inode_ctx quota_inode_ctx_t;
7f4c2a
 struct quota_synctask {
7f4c2a
         xlator_t      *this;
7f4c2a
         loc_t          loc;
7f4c2a
-        dict_t        *dict;
7f4c2a
-        struct iatt    buf;
7f4c2a
         int64_t        contri;
7f4c2a
         gf_boolean_t   is_static;
7f4c2a
 };
7f4c2a
@@ -153,8 +152,5 @@ int32_t
7f4c2a
 mq_rename_update_newpath (xlator_t *, loc_t *);
7f4c2a
 
7f4c2a
 int32_t
7f4c2a
-mq_inspect_file_xattr (xlator_t *this, loc_t *loc, dict_t *dict, struct iatt buf);
7f4c2a
-
7f4c2a
-int32_t
7f4c2a
 mq_forget (xlator_t *, quota_inode_ctx_t *);
7f4c2a
 #endif
7f4c2a
-- 
7f4c2a
1.7.1
7f4c2a