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