Blob Blame History Raw
From 648be4ccf9e3f077ec0e9849e99c6be98769716f Mon Sep 17 00:00:00 2001
From: vmallika <vmallika@redhat.com>
Date: Mon, 29 Jun 2015 19:12:28 +0530
Subject: [PATCH 210/212] quota/marker: fix mem leak in marker

This is a backport of http://review.gluster.org/#/c/11457/

Problem-1)
Now the marker accounting happens in background,
There is a possibility that before completing
create_xattr_txn another create txn can be initiated
for the same inode.
suppose if few 100 txns are initiated
before completion, this can block all synctask threads
waiting on a lock and this can also consume lot of memory
and can take more time to complete the background accounting
operation.

This patch improves the locking mechanism which
can improve the performance as well reduce memory
consumption

Problem-2)
For every lookup and for all inodes in readdirp
we were initiating a new txn, this can result
in more txn pending in synctask queue and
lead to huge memory consumption. inspect
file/dir should start a txn only if there
is some delta

Problem-3)
When there are multiple write operations on
same inode and all the synctask threads are busy.
As we are checking for updation_status
flag in background, all txn will be move to synctask queue.
This can increase the mem usage.

Only one txn for inode in a queue will be sufficient,
so check and set updation falg before moving txn to
background

> Change-Id: Ic42ce00f0a50ce51c7128ba68a1b6a0699a1cd14
> BUG: 1207735
> Signed-off-by: vmallika <vmallika@redhat.com>

Change-Id: Iee464d51d4ebe70c2ec7cf66540198f8af16f57e
BUG: 1224177
Signed-off-by: vmallika <vmallika@redhat.com>
Reviewed-on: https://code.engineering.redhat.com/gerrit/52303
Reviewed-by: Raghavendra Gowdappa <rgowdapp@redhat.com>
Tested-by: Raghavendra Gowdappa <rgowdapp@redhat.com>
---
 xlators/features/marker/src/marker-quota.c |  389 ++++++++++++++++------------
 xlators/features/marker/src/marker-quota.h |    6 +-
 2 files changed, 224 insertions(+), 171 deletions(-)

diff --git a/xlators/features/marker/src/marker-quota.c b/xlators/features/marker/src/marker-quota.c
index 0b015ef..97946f8 100644
--- a/xlators/features/marker/src/marker-quota.c
+++ b/xlators/features/marker/src/marker-quota.c
@@ -128,6 +128,49 @@ out:
         return ret;
 }
 
+int32_t
+mq_set_ctx_create_status (quota_inode_ctx_t *ctx,
+                          gf_boolean_t status)
+{
+        int32_t   ret = -1;
+
+        if (ctx == NULL)
+                goto out;
+
+        LOCK (&ctx->lock);
+        {
+                ctx->create_status = status;
+        }
+        UNLOCK (&ctx->lock);
+
+        ret = 0;
+out:
+        return ret;
+}
+
+int32_t
+mq_test_and_set_ctx_create_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->create_status;
+                ctx->create_status = temp;
+        }
+        UNLOCK (&ctx->lock);
+
+        ret = 0;
+out:
+        return ret;
+}
+
 void
 mq_assign_lk_owner (xlator_t *this, call_frame_t *frame)
 {
@@ -2184,30 +2227,19 @@ out:
 }
 
 int32_t
-mq_create_xattrs (xlator_t *this, loc_t *loc, gf_boolean_t objects)
+mq_create_xattrs (xlator_t *this, quota_inode_ctx_t *ctx, loc_t *loc,
+                  gf_boolean_t objects)
 {
         quota_meta_t           size                 = {0, };
         quota_meta_t           contri               = {0, };
         int32_t                ret                  = -1;
         char                   key[CONTRI_KEY_MAX]  = {0, };
         dict_t                *dict                 = NULL;
-        quota_inode_ctx_t     *ctx                  = NULL;
         inode_contribution_t  *contribution         = NULL;
 
         GF_VALIDATE_OR_GOTO ("marker", loc, out);
         GF_VALIDATE_OR_GOTO ("marker", loc->inode, out);
 
-        ret = mq_inode_ctx_get (loc->inode, this, &ctx);
-        if (ret < 0) {
-                ctx = mq_inode_ctx_new (loc->inode, this);
-                if (ctx == NULL) {
-                        gf_log (this->name, GF_LOG_WARNING,
-                                "mq_inode_ctx_new failed");
-                        ret = -1;
-                        goto out;
-                }
-        }
-
         dict = dict_new ();
         if (!dict) {
                 gf_log (this->name, GF_LOG_ERROR, "dict_new failed");
@@ -2765,8 +2797,6 @@ mq_synctask_cleanup (int ret, call_frame_t *frame, void *opaque)
 
         args = (quota_synctask_t *) opaque;
         loc_wipe (&args->loc);
-        if (args->dict)
-                dict_unref (args->dict);
 
         if (!args->is_static)
                 GF_FREE (args);
@@ -2776,7 +2806,7 @@ mq_synctask_cleanup (int ret, call_frame_t *frame, void *opaque)
 
 int
 mq_synctask (xlator_t *this, synctask_fn_t task, gf_boolean_t spawn, loc_t *loc,
-             dict_t *dict, struct iatt *buf, int64_t contri)
+             int64_t contri)
 {
         int32_t              ret         = -1;
         quota_synctask_t    *args        = NULL;
@@ -2793,11 +2823,6 @@ mq_synctask (xlator_t *this, synctask_fn_t task, gf_boolean_t spawn, loc_t *loc,
         args->this = this;
         loc_copy (&args->loc, loc);
         args->contri = contri;
-        if (dict)
-                args->dict = dict_ref (dict);
-        if (buf)
-                args->buf = *buf;
-
 
         if (spawn) {
                 ret = synctask_new (this->ctx->env, task, mq_synctask_cleanup,
@@ -2825,7 +2850,7 @@ mq_start_quota_txn_v2 (xlator_t *this, loc_t *loc, quota_inode_ctx_t *ctx,
         loc_t              parent_loc = {0,};
         gf_boolean_t       locked     = _gf_false;
         gf_boolean_t       dirty      = _gf_false;
-        gf_boolean_t       status     = _gf_true;
+        gf_boolean_t       status     = _gf_false;
         quota_meta_t       delta      = {0, };
 
         GF_VALIDATE_OR_GOTO ("marker", contri, out);
@@ -2855,9 +2880,16 @@ mq_start_quota_txn_v2 (xlator_t *this, loc_t *loc, quota_inode_ctx_t *ctx,
                 /* To improve performance, abort current transaction
                  * if one is already in progress for same inode
                  */
-                ret = mq_test_and_set_ctx_updation_status (ctx, &status);
-                if (ret < 0 || status == _gf_true)
-                        goto out;
+                if (status == _gf_true) {
+                        /* status will alreday set before txn start,
+                         * so it should not be set in first
+                         * loop iteration
+                         */
+                        ret = mq_test_and_set_ctx_updation_status (ctx,
+                                                                   &status);
+                        if (ret < 0 || status == _gf_true)
+                                goto out;
+                }
 
                 ret = mq_inode_loc_fill (NULL, child_loc.parent, &parent_loc);
                 if (ret < 0) {
@@ -2941,7 +2973,7 @@ out:
         if (locked)
                 ret = mq_lock (this, &parent_loc, F_UNLCK);
 
-        if (status == _gf_false)
+        if (ctx && status == _gf_false)
                 mq_set_ctx_updation_status (ctx, _gf_false);
 
         loc_wipe (&child_loc);
@@ -2949,7 +2981,7 @@ out:
         if (contri)
                 GF_REF_PUT (contri);
 
-        return ret;
+        return 0;
 }
 
 int
@@ -2961,8 +2993,10 @@ mq_create_xattrs_task (void *opaque)
         gf_boolean_t             objects    = _gf_false;
         gf_boolean_t             need_txn   = _gf_false;
         quota_synctask_t        *args       = NULL;
+        quota_inode_ctx_t       *ctx        = NULL;
         xlator_t                *this       = NULL;
         loc_t                   *loc        = NULL;
+        gf_boolean_t             status     = _gf_false;
 
         GF_ASSERT (opaque);
 
@@ -2981,16 +3015,29 @@ mq_create_xattrs_task (void *opaque)
                 goto out;
         }
 
-        ret = mq_lock (this, loc, F_WRLCK);
-        if (ret < 0)
+        ret = mq_inode_ctx_get (loc->inode, this, &ctx);
+        if (ret < 0) {
+                gf_log (this->name, GF_LOG_WARNING, "Failed to"
+                        "get inode ctx, aborting quota create txn");
                 goto out;
-        locked = _gf_true;
+        }
+
+        if (loc->inode->ia_type == IA_IFDIR) {
+                /* lock not required for files */
+                ret = mq_lock (this, loc, F_WRLCK);
+                if (ret < 0)
+                        goto out;
+                locked = _gf_true;
+        }
 
         ret = mq_are_xattrs_set (this, loc, &xattrs_set, &objects);
         if (ret < 0 || xattrs_set)
                 goto out;
 
-        ret = mq_create_xattrs (this, loc, objects);
+        mq_set_ctx_create_status (ctx, _gf_false);
+        status = _gf_true;
+
+        ret = mq_create_xattrs (this, ctx, loc, objects);
         if (ret < 0)
                 goto out;
 
@@ -2999,12 +3046,44 @@ out:
         if (locked)
                 ret = mq_lock (this, loc, F_UNLCK);
 
+        if (status == _gf_false)
+                mq_set_ctx_create_status (ctx, _gf_false);
+
         if (need_txn)
                 ret = mq_initiate_quota_blocking_txn (this, loc);
 
         return ret;
 }
 
+static int
+_mq_create_xattrs_txn (xlator_t *this, loc_t *loc, gf_boolean_t spawn)
+{
+        int32_t                  ret        = -1;
+        quota_inode_ctx_t       *ctx        = NULL;
+        gf_boolean_t             status     = _gf_true;
+
+        ret = mq_inode_ctx_get (loc->inode, this, &ctx);
+        if (ret < 0) {
+                ctx = mq_inode_ctx_new (loc->inode, this);
+                if (ctx == NULL) {
+                        gf_log (this->name, GF_LOG_WARNING,
+                                "mq_inode_ctx_new failed");
+                        ret = -1;
+                        goto out;
+                }
+        }
+
+        ret = mq_test_and_set_ctx_create_status (ctx, &status);
+        if (ret < 0 || status == _gf_true)
+                goto out;
+
+        ret = mq_synctask (this, mq_create_xattrs_task, spawn, loc, 0);
+out:
+        if (ret < 0 && status == _gf_false)
+                mq_set_ctx_create_status (ctx, _gf_false);
+
+        return ret;
+}
 int
 mq_create_xattrs_txn (xlator_t *this, loc_t *loc)
 {
@@ -3013,8 +3092,7 @@ mq_create_xattrs_txn (xlator_t *this, loc_t *loc)
         GF_VALIDATE_OR_GOTO ("marker", loc, out);
         GF_VALIDATE_OR_GOTO ("marker", loc->inode, out);
 
-        ret = mq_synctask (this, mq_create_xattrs_task, _gf_true, loc, NULL,
-                           NULL, 0);
+        ret = _mq_create_xattrs_txn (this, loc, _gf_true);
 out:
         return ret;
 }
@@ -3027,8 +3105,7 @@ mq_create_xattrs_blocking_txn (xlator_t *this, loc_t *loc)
         GF_VALIDATE_OR_GOTO ("marker", loc, out);
         GF_VALIDATE_OR_GOTO ("marker", loc->inode, out);
 
-        ret = mq_synctask (this, mq_create_xattrs_task, _gf_false, loc, NULL,
-                           NULL, 0);
+        ret = _mq_create_xattrs_txn (this, loc, _gf_false);
 out:
         return ret;
 }
@@ -3169,7 +3246,7 @@ mq_reduce_parent_size_txn (xlator_t *this, loc_t *loc, int64_t contri)
         GF_VALIDATE_OR_GOTO ("marker", loc->inode, out);
 
         ret = mq_synctask (this, mq_reduce_parent_size_task, _gf_true, loc,
-                           NULL, NULL, contri);
+                           contri);
 out:
         return ret;
 }
@@ -3195,7 +3272,6 @@ mq_initiate_quota_task (void *opaque)
         if (ret == -1) {
                 gf_log (this->name, GF_LOG_WARNING,
                         "inode ctx get failed, aborting quota txn");
-                ret = -1;
                 goto out;
         }
 
@@ -3230,6 +3306,7 @@ mq_initiate_quota_task (void *opaque)
                                                   loc->parent ?
                                                  uuid_utoa (loc->parent->gfid) :
                                                   NULL);
+                        ret = -1;
                         goto out;
                 }
         }
@@ -3241,6 +3318,36 @@ out:
         if (contribution)
                 GF_REF_PUT (contribution);
 
+        if (ctx && ret < 0)
+                mq_set_ctx_updation_status (ctx, _gf_false);
+
+        return ret;
+}
+
+int
+_mq_initiate_quota_txn (xlator_t *this, loc_t *loc, gf_boolean_t spawn)
+{
+        int32_t                 ret          = -1;
+        quota_inode_ctx_t      *ctx          = NULL;
+        gf_boolean_t            status       = _gf_true;
+
+        ret = mq_inode_ctx_get (loc->inode, this, &ctx);
+        if (ret == -1) {
+                gf_log (this->name, GF_LOG_WARNING,
+                        "inode ctx get failed, aborting quota txn");
+                goto out;
+        }
+
+        ret = mq_test_and_set_ctx_updation_status (ctx, &status);
+        if (ret < 0 || status == _gf_true)
+                goto out;
+
+        ret = mq_synctask (this, mq_initiate_quota_task, spawn, loc, 0);
+
+out:
+        if (ret < 0 && status == _gf_false)
+                mq_set_ctx_updation_status (ctx, _gf_false);
+
         return ret;
 }
 
@@ -3253,8 +3360,7 @@ mq_initiate_quota_txn (xlator_t *this, loc_t *loc)
         GF_VALIDATE_OR_GOTO ("marker", loc, out);
         GF_VALIDATE_OR_GOTO ("marker", loc->inode, out);
 
-        ret = mq_synctask (this, mq_initiate_quota_task, _gf_true, loc, NULL,
-                           NULL, 0);
+        ret = _mq_initiate_quota_txn (this, loc, _gf_true);
 out:
         return ret;
 }
@@ -3268,43 +3374,38 @@ mq_initiate_quota_blocking_txn (xlator_t *this, loc_t *loc)
         GF_VALIDATE_OR_GOTO ("marker", loc, out);
         GF_VALIDATE_OR_GOTO ("marker", loc->inode, out);
 
-        ret = mq_synctask (this, mq_initiate_quota_task, _gf_false, loc, NULL,
-                           NULL, 0);
+        ret = _mq_initiate_quota_txn (this, loc, _gf_false);
 out:
         return ret;
 }
 
-/* return 1 when dirty updation is performed
- * return 0 other wise
- */
-int32_t
-mq_update_dirty_inode_v2 (xlator_t *this, loc_t *loc, quota_inode_ctx_t *ctx,
-                          inode_contribution_t *contribution)
+int
+mq_update_dirty_inode_task (void *opaque)
 {
-        int32_t          ret            = -1;
-        fd_t            *fd             = NULL;
-        off_t            offset         = 0;
-        loc_t            child_loc      = {0, };
-        gf_dirent_t      entries;
-        gf_dirent_t     *entry          = NULL;
-        gf_boolean_t     status         = _gf_true;
-        gf_boolean_t     locked         = _gf_false;
-        gf_boolean_t     free_entries   = _gf_false;
-        gf_boolean_t     updated        = _gf_false;
-        int32_t          dirty          = 0;
-        quota_meta_t     contri         = {0, };
-        quota_meta_t     size           = {0, };
-        quota_meta_t     contri_sum     = {0, };
-        quota_meta_t     delta          = {0, };
+        int32_t               ret            = -1;
+        fd_t                 *fd             = NULL;
+        off_t                 offset         = 0;
+        loc_t                 child_loc      = {0, };
+        gf_dirent_t           entries;
+        gf_dirent_t          *entry          = NULL;
+        gf_boolean_t          locked         = _gf_false;
+        gf_boolean_t          free_entries   = _gf_false;
+        gf_boolean_t          updated        = _gf_false;
+        int32_t               dirty          = 0;
+        quota_meta_t          contri         = {0, };
+        quota_meta_t          size           = {0, };
+        quota_meta_t          contri_sum     = {0, };
+        quota_meta_t          delta          = {0, };
+        quota_synctask_t     *args           = NULL;
+        xlator_t             *this           = NULL;
+        loc_t                *loc            = NULL;
 
-        GF_VALIDATE_OR_GOTO ("marker", loc, out);
-        GF_VALIDATE_OR_GOTO ("marker", loc->inode, out);
+        GF_ASSERT (opaque);
 
-        ret = mq_get_ctx_updation_status (ctx, &status);
-        if (ret == -1 || status == _gf_true) {
-                ret = 0;
-                goto out;
-        }
+        args = (quota_synctask_t *) opaque;
+        loc = &args->loc;
+        this = args->this;
+        THIS = this;
 
         if (gf_uuid_is_null (loc->gfid))
                 gf_uuid_copy (loc->gfid, loc->inode->gfid);
@@ -3431,19 +3532,31 @@ out:
         if (locked)
                 mq_lock (this, loc, F_UNLCK);
 
-        if (status == _gf_false)
-                mq_set_ctx_updation_status (ctx, _gf_false);
-
         loc_wipe(&child_loc);
 
         if (updated)
-                return 1;
-        else
-                return 0;
+                mq_initiate_quota_blocking_txn (this, loc);
+
+        return ret;
 }
 
 int32_t
-mq_inspect_directory_xattr_task (void *opaque)
+mq_update_dirty_inode_txn (xlator_t *this, loc_t *loc)
+{
+        int32_t          ret            = -1;
+
+        GF_VALIDATE_OR_GOTO ("marker", loc, out);
+        GF_VALIDATE_OR_GOTO ("marker", loc->inode, out);
+
+        ret = mq_synctask (this, mq_update_dirty_inode_task, _gf_true,
+                           loc, 0);
+out:
+        return ret;
+}
+
+int32_t
+mq_inspect_directory_xattr (xlator_t *this, loc_t *loc, quota_inode_ctx_t *ctx,
+                            dict_t *dict, struct iatt buf)
 {
         int32_t               ret                          = 0;
         int8_t                dirty                        = -1;
@@ -3451,31 +3564,7 @@ mq_inspect_directory_xattr_task (void *opaque)
         quota_meta_t          contri                       = {0, };
         quota_meta_t          delta                        = {0, };
         char                  contri_key[CONTRI_KEY_MAX]   = {0, };
-        quota_inode_ctx_t    *ctx                          = NULL;
         inode_contribution_t *contribution                 = NULL;
-        quota_synctask_t     *args                         = NULL;
-        xlator_t             *this                         = NULL;
-        loc_t                *loc                          = NULL;
-        dict_t               *dict                         = NULL;
-
-        GF_ASSERT (opaque);
-
-        args = (quota_synctask_t *) opaque;
-        loc = &args->loc;
-        dict = args->dict;
-        this = args->this;
-        THIS = this;
-
-        ret = mq_inode_ctx_get (loc->inode, this, &ctx);
-        if (ret < 0) {
-                ctx = mq_inode_ctx_new (loc->inode, this);
-                if (ctx == NULL) {
-                        gf_log (this->name, GF_LOG_WARNING,
-                                "mq_inode_ctx_new failed");
-                        ret = -1;
-                        goto err;
-                }
-        }
 
         if (!loc_is_root(loc)) {
                 contribution = mq_add_new_contribution_node (this, ctx, loc);
@@ -3485,7 +3574,7 @@ mq_inspect_directory_xattr_task (void *opaque)
                                         "cannot add a new contribution node "
                                         "(%s)", uuid_utoa (loc->inode->gfid));
                         ret = -1;
-                        goto err;
+                        goto out;
                 }
         }
 
@@ -3506,7 +3595,7 @@ mq_inspect_directory_xattr_task (void *opaque)
         if (!loc_is_root(loc)) {
                 GET_CONTRI_KEY (contri_key, contribution->gfid, ret);
                 if (ret < 0)
-                        goto err;
+                        goto out;
 
                 ret = _quota_dict_get_meta (this, dict, contri_key, &contri,
                                             IA_IFDIR, _gf_false);
@@ -3527,27 +3616,29 @@ mq_inspect_directory_xattr_task (void *opaque)
                 ctx->size = size.size;
                 ctx->file_count = size.file_count;
                 ctx->dir_count = size.dir_count;
-                ctx->dirty = dirty;
         }
         UNLOCK (&ctx->lock);
 
         mq_compute_delta (&delta, &size, &contri);
 
-        if (dirty)
-                ret = mq_update_dirty_inode_v2 (this, loc, ctx, contribution);
+        if (dirty) {
+                if (ctx->dirty == 0)
+                        ret = mq_update_dirty_inode_txn (this, loc);
 
-        if ((!dirty || ret == 1) &&
-            !loc_is_root(loc) &&
+                goto out;
+        }
+
+        if (!loc_is_root(loc) &&
             !quota_meta_is_null (&delta))
-                mq_initiate_quota_blocking_txn (this, loc);
+                mq_initiate_quota_txn (this, loc);
 
         ret = 0;
 
 create_xattr:
         if (ret < 0)
-                ret = mq_create_xattrs_blocking_txn (this, loc);
+                ret = mq_create_xattrs_txn (this, loc);
 
-err:
+out:
         if (contribution)
                 GF_REF_PUT (contribution);
 
@@ -3555,52 +3646,15 @@ err:
 }
 
 int32_t
-mq_inspect_directory_xattr_txn (xlator_t *this, loc_t *loc, dict_t *dict,
-                                struct iatt buf)
-{
-        int32_t   ret = -1;
-
-        ret = mq_synctask (this, mq_inspect_directory_xattr_task, _gf_true,
-                           loc, dict, &buf, 0);
-
-        return ret;
-}
-
-int32_t
-mq_inspect_file_xattr_task (void *opaque)
+mq_inspect_file_xattr (xlator_t *this, quota_inode_ctx_t *ctx, loc_t *loc,
+                       dict_t *dict, struct iatt buf)
 {
         int32_t               ret                          = -1;
         quota_meta_t          size                         = {0, };
         quota_meta_t          contri                       = {0, };
         quota_meta_t          delta                        = {0, };
         char                  contri_key[CONTRI_KEY_MAX]   = {0, };
-        quota_inode_ctx_t    *ctx                          = NULL;
         inode_contribution_t *contribution                 = NULL;
-        quota_synctask_t     *args                         = NULL;
-        xlator_t             *this                         = NULL;
-        loc_t                *loc                          = NULL;
-        dict_t               *dict                         = NULL;
-        struct iatt           buf                          = {0,};
-
-        GF_ASSERT (opaque);
-
-        args = (quota_synctask_t *) opaque;
-        loc = &args->loc;
-        dict = args->dict;
-        buf = args->buf;
-        this = args->this;
-        THIS = this;
-
-        ret = mq_inode_ctx_get (loc->inode, this, &ctx);
-        if (ret < 0) {
-                ctx = mq_inode_ctx_new (loc->inode, this);
-                if (ctx == NULL) {
-                        gf_log (this->name, GF_LOG_WARNING,
-                                "mq_inode_ctx_new failed");
-                        ret = -1;
-                        goto out;
-                }
-        }
 
         contribution = mq_add_new_contribution_node (this, ctx, loc);
         if (contribution == NULL) {
@@ -3629,7 +3683,7 @@ mq_inspect_file_xattr_task (void *opaque)
         ret = _quota_dict_get_meta (this, dict, contri_key, &contri,
                                     IA_IFREG, _gf_true);
         if (ret < 0) {
-                ret = mq_create_xattrs_blocking_txn (this, loc);
+                ret = mq_create_xattrs_txn (this, loc);
         } else {
                 LOCK (&contribution->lock);
                 {
@@ -3641,7 +3695,7 @@ mq_inspect_file_xattr_task (void *opaque)
 
                 mq_compute_delta (&delta, &size, &contri);
                 if (!quota_meta_is_null (&delta))
-                        mq_initiate_quota_blocking_txn (this, loc);
+                        mq_initiate_quota_txn (this, loc);
         }
         /* TODO: revist this code when fixing hardlinks */
 
@@ -3653,27 +3707,30 @@ out:
 }
 
 int32_t
-mq_inspect_file_xattr_txn (xlator_t *this, loc_t *loc, dict_t *dict,
-                           struct iatt buf)
+mq_xattr_state (xlator_t *this, loc_t *loc, dict_t *dict, struct iatt buf)
 {
-        int32_t   ret = -1;
+        int32_t               ret     = -1;
+        quota_inode_ctx_t    *ctx     = NULL;
 
-        ret = mq_synctask (this, mq_inspect_file_xattr_task, _gf_true,
-                           loc, dict, &buf, 0);
-
-        return ret;
-}
+        ret = mq_inode_ctx_get (loc->inode, this, &ctx);
+        if (ret < 0) {
+                ctx = mq_inode_ctx_new (loc->inode, this);
+                if (ctx == NULL) {
+                        gf_log (this->name, GF_LOG_WARNING,
+                                "mq_inode_ctx_new failed");
+                        ret = -1;
+                        goto out;
+                }
+        }
 
-int32_t
-mq_xattr_state (xlator_t *this, loc_t *loc, dict_t *dict, struct iatt buf)
-{
         if (((buf.ia_type == IA_IFREG) && !dht_is_linkfile (&buf, dict))
             || (buf.ia_type == IA_IFLNK))  {
-                mq_inspect_file_xattr_txn (this, loc, dict, buf);
+                mq_inspect_file_xattr (this, ctx, loc, dict, buf);
         } else if (buf.ia_type == IA_IFDIR)
-                mq_inspect_directory_xattr_txn (this, loc, dict, buf);
+                mq_inspect_directory_xattr (this, loc, ctx, dict, buf);
 
-        return 0;
+out:
+        return ret;
 }
 
 int32_t
diff --git a/xlators/features/marker/src/marker-quota.h b/xlators/features/marker/src/marker-quota.h
index 2d03dfd..89ac559 100644
--- a/xlators/features/marker/src/marker-quota.h
+++ b/xlators/features/marker/src/marker-quota.h
@@ -88,6 +88,7 @@ struct quota_inode_ctx {
         int64_t                file_count;
         int64_t                dir_count;
         int8_t                 dirty;
+        gf_boolean_t           create_status;
         gf_boolean_t           updation_status;
         gf_lock_t              lock;
         struct list_head       contribution_head;
@@ -97,8 +98,6 @@ typedef struct quota_inode_ctx quota_inode_ctx_t;
 struct quota_synctask {
         xlator_t      *this;
         loc_t          loc;
-        dict_t        *dict;
-        struct iatt    buf;
         int64_t        contri;
         gf_boolean_t   is_static;
 };
@@ -153,8 +152,5 @@ int32_t
 mq_rename_update_newpath (xlator_t *, loc_t *);
 
 int32_t
-mq_inspect_file_xattr (xlator_t *this, loc_t *loc, dict_t *dict, struct iatt buf);
-
-int32_t
 mq_forget (xlator_t *, quota_inode_ctx_t *);
 #endif
-- 
1.7.1