|
|
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 |
|