cb8e9e
From b0061ce310b487858b74dbaa8266a61df87dafb6 Mon Sep 17 00:00:00 2001
cb8e9e
From: vmallika <vmallika@redhat.com>
cb8e9e
Date: Thu, 27 Aug 2015 21:11:53 +0530
cb8e9e
Subject: [PATCH 317/320] marker: preserve previous dirty flag during update txn
cb8e9e
cb8e9e
This is a backport of http://review.gluster.org/#/c/12032/
cb8e9e
cb8e9e
In case if dir has become dirty because of crash,
cb8e9e
this dirty flag on disk was getting reset in the
cb8e9e
next update txn.
cb8e9e
cb8e9e
This patch now gets the dirty flag before setting
cb8e9e
in the update txn and it the value is dirty, it keeps
cb8e9e
the flag dirty, so that inspect_directory can fix the
cb8e9e
dirty dir
cb8e9e
cb8e9e
> Change-Id: Iab2c343dbe19bd3b291adbfeebe6d9785b6bb9e3
cb8e9e
> BUG: 1251454
cb8e9e
> Signed-off-by: vmallika <vmallika@redhat.com>
cb8e9e
cb8e9e
Change-Id: I4a34c8a0e13aa1c21cd9ddbb272c7e22a4137004
cb8e9e
BUG: 1251457
cb8e9e
Signed-off-by: vmallika <vmallika@redhat.com>
cb8e9e
Reviewed-on: https://code.engineering.redhat.com/gerrit/56569
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 |  106 ++++++++++++++++++++++++----
cb8e9e
 1 files changed, 91 insertions(+), 15 deletions(-)
cb8e9e
cb8e9e
diff --git a/xlators/features/marker/src/marker-quota.c b/xlators/features/marker/src/marker-quota.c
cb8e9e
index b582158..d9063a8 100644
cb8e9e
--- a/xlators/features/marker/src/marker-quota.c
cb8e9e
+++ b/xlators/features/marker/src/marker-quota.c
cb8e9e
@@ -2386,18 +2386,30 @@ out:
cb8e9e
 }
cb8e9e
 
cb8e9e
 int32_t
cb8e9e
-mq_mark_dirty (xlator_t *this, loc_t *loc, int32_t dirty)
cb8e9e
+mq_get_set_dirty (xlator_t *this, loc_t *loc, int32_t dirty,
cb8e9e
+                  int32_t *prev_dirty)
cb8e9e
 {
cb8e9e
-        int32_t            ret      = -1;
cb8e9e
-        dict_t            *dict     = NULL;
cb8e9e
-        quota_inode_ctx_t *ctx      = NULL;
cb8e9e
+        int32_t              ret              = -1;
cb8e9e
+        int8_t               value            = 0;
cb8e9e
+        quota_inode_ctx_t   *ctx              = NULL;
cb8e9e
+        dict_t              *dict             = NULL;
cb8e9e
+        dict_t              *rsp_dict         = NULL;
cb8e9e
 
cb8e9e
         GF_VALIDATE_OR_GOTO ("marker", loc, out);
cb8e9e
         GF_VALIDATE_OR_GOTO ("marker", loc->inode, out);
cb8e9e
+        GF_VALIDATE_OR_GOTO ("marker", prev_dirty, out);
cb8e9e
+
cb8e9e
+        ret = mq_inode_ctx_get (loc->inode, this, &ctx;;
cb8e9e
+        if (ret < 0) {
cb8e9e
+                gf_log (this->name, GF_LOG_ERROR, "failed to get inode ctx for "
cb8e9e
+                        "%s", loc->path);
cb8e9e
+                goto out;
cb8e9e
+        }
cb8e9e
 
cb8e9e
         dict = dict_new ();
cb8e9e
         if (!dict) {
cb8e9e
                 gf_log (this->name, GF_LOG_ERROR, "dict_new failed");
cb8e9e
+                ret = -1;
cb8e9e
                 goto out;
cb8e9e
         }
cb8e9e
 
cb8e9e
@@ -2407,14 +2419,48 @@ mq_mark_dirty (xlator_t *this, loc_t *loc, int32_t dirty)
cb8e9e
                 goto out;
cb8e9e
         }
cb8e9e
 
cb8e9e
-        ret = syncop_setxattr (FIRST_CHILD(this), loc, dict, 0, NULL, NULL);
cb8e9e
+        ret = syncop_xattrop (FIRST_CHILD(this), loc, GF_XATTROP_GET_AND_SET,
cb8e9e
+                              dict, NULL, &rsp_dict);
cb8e9e
         if (ret < 0) {
cb8e9e
                 gf_log_callingfn (this->name, (-ret == ENOENT || -ret == ESTALE)
cb8e9e
-                        ? GF_LOG_DEBUG:GF_LOG_ERROR, "setxattr dirty = %d "
cb8e9e
-                        "failed for %s: %s", dirty, loc->path, strerror (-ret));
cb8e9e
+                          ? GF_LOG_DEBUG:GF_LOG_ERROR, "xattrop failed "
cb8e9e
+                          "for %s: %s", loc->path, strerror (-ret));
cb8e9e
                 goto out;
cb8e9e
         }
cb8e9e
 
cb8e9e
+        *prev_dirty = 0;
cb8e9e
+        if (rsp_dict) {
cb8e9e
+                ret = dict_get_int8 (rsp_dict, QUOTA_DIRTY_KEY, &value);
cb8e9e
+                if (ret == 0)
cb8e9e
+                        *prev_dirty = value;
cb8e9e
+        }
cb8e9e
+
cb8e9e
+        LOCK (&ctx->lock);
cb8e9e
+        {
cb8e9e
+                ctx->dirty = dirty;
cb8e9e
+        }
cb8e9e
+        UNLOCK (&ctx->lock);
cb8e9e
+        ret = 0;
cb8e9e
+out:
cb8e9e
+        if (dict)
cb8e9e
+                dict_unref (dict);
cb8e9e
+
cb8e9e
+        if (rsp_dict)
cb8e9e
+                dict_unref (rsp_dict);
cb8e9e
+
cb8e9e
+        return ret;
cb8e9e
+}
cb8e9e
+
cb8e9e
+int32_t
cb8e9e
+mq_mark_dirty (xlator_t *this, loc_t *loc, int32_t dirty)
cb8e9e
+{
cb8e9e
+        int32_t            ret      = -1;
cb8e9e
+        dict_t            *dict     = NULL;
cb8e9e
+        quota_inode_ctx_t *ctx      = 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
                 gf_log (this->name, GF_LOG_ERROR, "failed to get inode ctx for "
cb8e9e
@@ -2423,6 +2469,27 @@ mq_mark_dirty (xlator_t *this, loc_t *loc, int32_t dirty)
cb8e9e
                 goto out;
cb8e9e
         }
cb8e9e
 
cb8e9e
+        dict = dict_new ();
cb8e9e
+        if (!dict) {
cb8e9e
+                ret = -1;
cb8e9e
+                gf_log (this->name, GF_LOG_ERROR, "dict_new failed");
cb8e9e
+                goto out;
cb8e9e
+        }
cb8e9e
+
cb8e9e
+        ret = dict_set_int8 (dict, QUOTA_DIRTY_KEY, dirty);
cb8e9e
+        if (ret < 0) {
cb8e9e
+                gf_log (this->name, GF_LOG_ERROR, "dict_set failed");
cb8e9e
+                goto out;
cb8e9e
+        }
cb8e9e
+
cb8e9e
+        ret = syncop_setxattr (FIRST_CHILD(this), loc, dict, 0, NULL, NULL);
cb8e9e
+        if (ret < 0) {
cb8e9e
+                gf_log_callingfn (this->name, (-ret == ENOENT || -ret == ESTALE)
cb8e9e
+                        ? GF_LOG_DEBUG:GF_LOG_ERROR, "setxattr dirty = %d "
cb8e9e
+                        "failed for %s: %s", dirty, loc->path, strerror (-ret));
cb8e9e
+                goto out;
cb8e9e
+        }
cb8e9e
+
cb8e9e
         LOCK (&ctx->lock);
cb8e9e
         {
cb8e9e
                 ctx->dirty = dirty;
cb8e9e
@@ -3010,6 +3077,7 @@ int32_t
cb8e9e
 mq_reduce_parent_size_task (void *opaque)
cb8e9e
 {
cb8e9e
         int32_t                  ret           = -1;
cb8e9e
+        int32_t                  prev_dirty    = 0;
cb8e9e
         quota_inode_ctx_t       *ctx           = NULL;
cb8e9e
         quota_inode_ctx_t       *parent_ctx    = NULL;
cb8e9e
         inode_contribution_t    *contribution  = NULL;
cb8e9e
@@ -3079,7 +3147,7 @@ mq_reduce_parent_size_task (void *opaque)
cb8e9e
                 UNLOCK (&contribution->lock);
cb8e9e
         }
cb8e9e
 
cb8e9e
-        ret = mq_mark_dirty (this, &parent_loc, 1);
cb8e9e
+        ret = mq_get_set_dirty (this, &parent_loc, 1, &prev_dirty);
cb8e9e
         if (ret < 0)
cb8e9e
                 goto out;
cb8e9e
         dirty = _gf_true;
cb8e9e
@@ -3101,11 +3169,13 @@ mq_reduce_parent_size_task (void *opaque)
cb8e9e
 
cb8e9e
 out:
cb8e9e
         if (dirty) {
cb8e9e
-                if (ret < 0) {
cb8e9e
+                if (ret < 0 || prev_dirty) {
cb8e9e
                         /* On failure clear dirty status flag.
cb8e9e
                          * In the next lookup inspect_directory_xattr
cb8e9e
                          * can set the status flag and fix the
cb8e9e
-                         * dirty directory
cb8e9e
+                         * dirty directory.
cb8e9e
+                         * Do the same if dir was dirty before
cb8e9e
+                         * the txn
cb8e9e
                          */
cb8e9e
                         ret = mq_inode_ctx_get (parent_loc.inode, this,
cb8e9e
                                                 &parent_ctx);
cb8e9e
@@ -3159,6 +3229,7 @@ int
cb8e9e
 mq_initiate_quota_task (void *opaque)
cb8e9e
 {
cb8e9e
         int32_t                ret        = -1;
cb8e9e
+        int32_t                prev_dirty = 0;
cb8e9e
         loc_t                  child_loc  = {0,};
cb8e9e
         loc_t                  parent_loc = {0,};
cb8e9e
         gf_boolean_t           locked     = _gf_false;
cb8e9e
@@ -3299,7 +3370,8 @@ mq_initiate_quota_task (void *opaque)
cb8e9e
                 if (quota_meta_is_null (&delta))
cb8e9e
                         goto out;
cb8e9e
 
cb8e9e
-                ret = mq_mark_dirty (this, &parent_loc, 1);
cb8e9e
+                prev_dirty = 0;
cb8e9e
+                ret = mq_get_set_dirty (this, &parent_loc, 1, &prev_dirty);
cb8e9e
                 if (ret < 0)
cb8e9e
                         goto out;
cb8e9e
                 dirty = _gf_true;
cb8e9e
@@ -3317,8 +3389,10 @@ mq_initiate_quota_task (void *opaque)
cb8e9e
                         goto out;
cb8e9e
                 }
cb8e9e
 
cb8e9e
-                ret = mq_mark_dirty (this, &parent_loc, 0);
cb8e9e
-                dirty = _gf_false;
cb8e9e
+                if (prev_dirty == 0) {
cb8e9e
+                        ret = mq_mark_dirty (this, &parent_loc, 0);
cb8e9e
+                        dirty = _gf_false;
cb8e9e
+                }
cb8e9e
 
cb8e9e
                 ret = mq_lock (this, &parent_loc, F_UNLCK);
cb8e9e
                 locked = _gf_false;
cb8e9e
@@ -3339,11 +3413,13 @@ mq_initiate_quota_task (void *opaque)
cb8e9e
 
cb8e9e
 out:
cb8e9e
         if (dirty) {
cb8e9e
-                if (ret < 0) {
cb8e9e
+                if (ret < 0 || prev_dirty) {
cb8e9e
                         /* On failure clear dirty status flag.
cb8e9e
                          * In the next lookup inspect_directory_xattr
cb8e9e
                          * can set the status flag and fix the
cb8e9e
-                         * dirty directory
cb8e9e
+                         * dirty directory.
cb8e9e
+                         * Do the same if the dir was dirty before
cb8e9e
+                         * txn
cb8e9e
                          */
cb8e9e
                         ret = mq_inode_ctx_get (parent_loc.inode, this,
cb8e9e
                                                 &parent_ctx);
cb8e9e
-- 
cb8e9e
1.7.1
cb8e9e