summaryrefslogtreecommitdiffstats
path: root/xlators/features
diff options
context:
space:
mode:
Diffstat (limited to 'xlators/features')
-rw-r--r--xlators/features/marker/src/marker-quota.c256
-rw-r--r--xlators/features/marker/src/marker-quota.h1
2 files changed, 168 insertions, 89 deletions
diff --git a/xlators/features/marker/src/marker-quota.c b/xlators/features/marker/src/marker-quota.c
index 2aa62a78150..c3d838f7549 100644
--- a/xlators/features/marker/src/marker-quota.c
+++ b/xlators/features/marker/src/marker-quota.c
@@ -59,111 +59,129 @@ out:
return ret;
}
-int32_t
-mq_get_ctx_updation_status (quota_inode_ctx_t *ctx,
+static void
+mq_set_ctx_status (quota_inode_ctx_t *ctx, gf_boolean_t *flag,
+ gf_boolean_t status)
+{
+ LOCK (&ctx->lock);
+ {
+ *flag = status;
+ }
+ UNLOCK (&ctx->lock);
+}
+
+static void
+mq_test_and_set_ctx_status (quota_inode_ctx_t *ctx, gf_boolean_t *flag,
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 = *flag;
+ *flag = temp;
+ }
+ UNLOCK (&ctx->lock);
+}
+static void
+mq_get_ctx_status (quota_inode_ctx_t *ctx, gf_boolean_t *flag,
+ gf_boolean_t *status)
+{
LOCK (&ctx->lock);
{
- *status = ctx->updation_status;
+ *status = *flag;
}
UNLOCK (&ctx->lock);
+}
- ret = 0;
+int32_t
+mq_get_ctx_updation_status (quota_inode_ctx_t *ctx,
+ gf_boolean_t *status)
+{
+ GF_VALIDATE_OR_GOTO ("marker", ctx, out);
+ GF_VALIDATE_OR_GOTO ("marker", status, out);
+
+ mq_get_ctx_status (ctx, &ctx->updation_status, status);
+ return 0;
out:
- return ret;
+ return -1;
}
-
int32_t
mq_set_ctx_updation_status (quota_inode_ctx_t *ctx,
gf_boolean_t status)
{
- int32_t ret = -1;
-
- if (ctx == NULL)
- goto out;
-
- LOCK (&ctx->lock);
- {
- ctx->updation_status = status;
- }
- UNLOCK (&ctx->lock);
+ GF_VALIDATE_OR_GOTO ("marker", ctx, out);
- ret = 0;
+ mq_set_ctx_status (ctx, &ctx->updation_status, status);
+ return 0;
out:
- return ret;
+ return -1;
}
int32_t
mq_test_and_set_ctx_updation_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->updation_status;
- ctx->updation_status = temp;
- }
- UNLOCK (&ctx->lock);
-
- ret = 0;
+ mq_test_and_set_ctx_status (ctx, &ctx->updation_status, status);
+ return 0;
out:
- return ret;
+ return -1;
}
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);
+ GF_VALIDATE_OR_GOTO ("marker", ctx, out);
- ret = 0;
+ mq_set_ctx_status (ctx, &ctx->create_status, status);
+ return 0;
out:
- return ret;
+ return -1;
}
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);
+ mq_test_and_set_ctx_status (ctx, &ctx->create_status, status);
+ return 0;
+out:
+ return -1;
+}
- ret = 0;
+int32_t
+mq_set_ctx_dirty_status (quota_inode_ctx_t *ctx,
+ gf_boolean_t status)
+{
+ GF_VALIDATE_OR_GOTO ("marker", ctx, out);
+
+ mq_set_ctx_status (ctx, &ctx->dirty_status, status);
+ return 0;
out:
- return ret;
+ return -1;
+}
+
+int32_t
+mq_test_and_set_ctx_dirty_status (quota_inode_ctx_t *ctx,
+ gf_boolean_t *status)
+{
+ GF_VALIDATE_OR_GOTO ("marker", ctx, out);
+ GF_VALIDATE_OR_GOTO ("marker", status, out);
+
+ mq_test_and_set_ctx_status (ctx, &ctx->dirty_status, status);
+ return 0;
+out:
+ return -1;
}
void
@@ -2400,6 +2418,7 @@ mq_mark_dirty (xlator_t *this, loc_t *loc, int32_t dirty)
if (ret < 0) {
gf_log (this->name, GF_LOG_ERROR, "failed to get inode ctx for "
"%s", loc->path);
+ ret = 0;
goto out;
}
@@ -2832,8 +2851,7 @@ mq_prevalidate_txn (xlator_t *this, loc_t *origin_loc, loc_t *loc,
quota_inode_ctx_t *ctxtmp = NULL;
if (origin_loc == NULL || origin_loc->inode == NULL ||
- (gf_uuid_is_null(origin_loc->gfid) &&
- gf_uuid_is_null(origin_loc->inode->gfid)))
+ gf_uuid_is_null(origin_loc->inode->gfid))
goto out;
loc_copy (loc, origin_loc);
@@ -2841,6 +2859,14 @@ mq_prevalidate_txn (xlator_t *this, loc_t *origin_loc, loc_t *loc,
if (gf_uuid_is_null (loc->gfid))
gf_uuid_copy (loc->gfid, loc->inode->gfid);
+ if (!loc_is_root(loc) && loc->parent == NULL) {
+ loc->parent = inode_parent (loc->inode, 0, NULL);
+ if (loc->parent == NULL) {
+ ret = -1;
+ goto out;
+ }
+ }
+
if (ctx)
ret = mq_inode_ctx_get (loc->inode, this, ctx);
else
@@ -2984,6 +3010,7 @@ mq_reduce_parent_size_task (void *opaque)
{
int32_t ret = -1;
quota_inode_ctx_t *ctx = NULL;
+ quota_inode_ctx_t *parent_ctx = NULL;
inode_contribution_t *contribution = NULL;
quota_meta_t delta = {0, };
quota_meta_t contri = {0, };
@@ -3003,13 +3030,6 @@ mq_reduce_parent_size_task (void *opaque)
this = args->this;
THIS = this;
- ret = mq_inode_ctx_get (loc->inode, this, &ctx);
- if (ret < 0) {
- gf_log_callingfn (this->name, GF_LOG_WARNING, "ctx for"
- " the node %s is NULL", loc->path);
- goto out;
- }
-
ret = mq_inode_loc_fill (NULL, loc->parent, &parent_loc);
if (ret < 0) {
gf_log (this->name, GF_LOG_ERROR, "loc fill failed");
@@ -3032,6 +3052,14 @@ mq_reduce_parent_size_task (void *opaque)
delta.dir_count = contri.dir_count;
} else {
remove_xattr = _gf_true;
+
+ ret = mq_inode_ctx_get (loc->inode, this, &ctx);
+ if (ret < 0) {
+ gf_log_callingfn (this->name, GF_LOG_WARNING, "ctx for"
+ " the node %s is NULL", loc->path);
+ goto out;
+ }
+
contribution = mq_get_contribution_node (loc->parent, ctx);
if (contribution == NULL) {
ret = -1;
@@ -3071,8 +3099,20 @@ mq_reduce_parent_size_task (void *opaque)
goto out;
out:
- if (dirty && ret >= 0)
- ret = mq_mark_dirty (this, &parent_loc, 0);
+ if (dirty) {
+ if (ret < 0) {
+ /* On failure clear dirty status flag.
+ * In the next lookup inspect_directory_xattr
+ * can set the status flag and fix the
+ * dirty directory
+ */
+ ret = mq_inode_ctx_get (parent_loc.inode, this,
+ &parent_ctx);
+ mq_set_ctx_dirty_status (parent_ctx, _gf_false);
+ } else {
+ ret = mq_mark_dirty (this, &parent_loc, 0);
+ }
+ }
if (locked)
ret = mq_lock (this, &parent_loc, F_UNLCK);
@@ -3107,12 +3147,6 @@ mq_reduce_parent_size_txn (xlator_t *this, loc_t *origin_loc,
goto out;
}
- if (loc.parent == NULL) {
- gf_log (this->name, GF_LOG_WARNING, "parent is NULL for %s, "
- "aborting reduce parent size txn", loc.path);
- goto out;
- }
-
ret = mq_synctask1 (this, mq_reduce_parent_size_task, _gf_true, &loc,
contri);
out:
@@ -3135,6 +3169,7 @@ mq_initiate_quota_task (void *opaque)
loc_t *loc = NULL;
inode_contribution_t *contri = NULL;
quota_inode_ctx_t *ctx = NULL;
+ quota_inode_ctx_t *parent_ctx = NULL;
inode_t *tmp_parent = NULL;
GF_VALIDATE_OR_GOTO ("marker", opaque, out);
@@ -3302,8 +3337,20 @@ mq_initiate_quota_task (void *opaque)
}
out:
- if (ret >= 0 && dirty)
- ret = mq_mark_dirty (this, &parent_loc, 0);
+ if (dirty) {
+ if (ret < 0) {
+ /* On failure clear dirty status flag.
+ * In the next lookup inspect_directory_xattr
+ * can set the status flag and fix the
+ * dirty directory
+ */
+ ret = mq_inode_ctx_get (parent_loc.inode, this,
+ &parent_ctx);
+ mq_set_ctx_dirty_status (parent_ctx, _gf_false);
+ } else {
+ ret = mq_mark_dirty (this, &parent_loc, 0);
+ }
+ }
if (locked)
ret = mq_lock (this, &parent_loc, F_UNLCK);
@@ -3340,12 +3387,6 @@ _mq_initiate_quota_txn (xlator_t *this, loc_t *origin_loc, gf_boolean_t spawn)
goto out;
}
- if (loc.parent == NULL) {
- gf_log (this->name, GF_LOG_WARNING, "parent is NULL for %s, "
- "aborting updation txn", loc.path);
- goto out;
- }
-
ret = mq_test_and_set_ctx_updation_status (ctx, &status);
if (ret < 0 || status == _gf_true)
goto out;
@@ -3408,6 +3449,7 @@ mq_update_dirty_inode_task (void *opaque)
quota_synctask_t *args = NULL;
xlator_t *this = NULL;
loc_t *loc = NULL;
+ quota_inode_ctx_t *ctx = NULL;
GF_ASSERT (opaque);
@@ -3416,6 +3458,10 @@ mq_update_dirty_inode_task (void *opaque)
this = args->this;
THIS = this;
+ ret = mq_inode_ctx_get (loc->inode, this, &ctx);
+ if (ret < 0)
+ goto out;
+
ret = mq_lock (this, loc, F_WRLCK);
if (ret < 0)
goto out;
@@ -3525,8 +3571,16 @@ out:
if (fd)
fd_unref (fd);
- if (ret >= 0 && dirty)
+ if (ret < 0) {
+ /* On failure clear dirty status flag.
+ * In the next lookup inspect_directory_xattr
+ * can set the status flag and fix the
+ * dirty directory
+ */
+ mq_set_ctx_dirty_status (ctx, _gf_false);
+ } else if (dirty) {
mq_mark_dirty (this, loc, 0);
+ }
if (locked)
mq_lock (this, loc, F_UNLCK);
@@ -3540,15 +3594,23 @@ out:
}
int32_t
-mq_update_dirty_inode_txn (xlator_t *this, loc_t *loc)
+mq_update_dirty_inode_txn (xlator_t *this, loc_t *loc, quota_inode_ctx_t *ctx)
{
- int32_t ret = -1;
+ int32_t ret = -1;
+ gf_boolean_t status = _gf_true;
GF_VALIDATE_OR_GOTO ("marker", loc, out);
GF_VALIDATE_OR_GOTO ("marker", loc->inode, out);
+ ret = mq_test_and_set_ctx_dirty_status (ctx, &status);
+ if (ret < 0 || status == _gf_true)
+ goto out;
+
ret = mq_synctask (this, mq_update_dirty_inode_task, _gf_true, loc);
out:
+ if (ret < 0 && status == _gf_false)
+ mq_set_ctx_dirty_status (ctx, _gf_false);
+
return ret;
}
@@ -3563,6 +3625,7 @@ mq_inspect_directory_xattr (xlator_t *this, quota_inode_ctx_t *ctx,
quota_meta_t contri = {0, };
quota_meta_t delta = {0, };
char contri_key[CONTRI_KEY_MAX] = {0, };
+ gf_boolean_t status = _gf_false;
ret = dict_get_int8 (dict, QUOTA_DIRTY_KEY, &dirty);
if (ret < 0) {
@@ -3602,15 +3665,21 @@ mq_inspect_directory_xattr (xlator_t *this, quota_inode_ctx_t *ctx,
ctx->size = size.size;
ctx->file_count = size.file_count;
ctx->dir_count = size.dir_count;
+ ctx->dirty = dirty;
}
UNLOCK (&ctx->lock);
+ ret = mq_get_ctx_updation_status (ctx, &status);
+ if (ret < 0 || status == _gf_true) {
+ /* If the update txn is in progress abort inspection */
+ ret = 0;
+ goto out;
+ }
+
mq_compute_delta (&delta, &size, &contri);
if (dirty) {
- if (ctx->dirty == 0)
- ret = mq_update_dirty_inode_txn (this, loc);
-
+ ret = mq_update_dirty_inode_txn (this, loc, ctx);
goto out;
}
@@ -3619,6 +3688,7 @@ mq_inspect_directory_xattr (xlator_t *this, quota_inode_ctx_t *ctx,
mq_initiate_quota_txn (this, loc);
ret = 0;
+ goto out;
create_xattr:
if (ret < 0)
@@ -3638,6 +3708,7 @@ mq_inspect_file_xattr (xlator_t *this, quota_inode_ctx_t *ctx,
quota_meta_t contri = {0, };
quota_meta_t delta = {0, };
char contri_key[CONTRI_KEY_MAX] = {0, };
+ gf_boolean_t status = _gf_false;
LOCK (&ctx->lock);
{
@@ -3668,6 +3739,13 @@ mq_inspect_file_xattr (xlator_t *this, quota_inode_ctx_t *ctx,
}
UNLOCK (&contribution->lock);
+ ret = mq_get_ctx_updation_status (ctx, &status);
+ if (ret < 0 || status == _gf_true) {
+ /* If the update txn is in progress abort inspection */
+ ret = 0;
+ goto out;
+ }
+
mq_compute_delta (&delta, &size, &contri);
if (!quota_meta_is_null (&delta))
mq_initiate_quota_txn (this, loc);
diff --git a/xlators/features/marker/src/marker-quota.h b/xlators/features/marker/src/marker-quota.h
index 6bae110f014..9491d5e12bd 100644
--- a/xlators/features/marker/src/marker-quota.h
+++ b/xlators/features/marker/src/marker-quota.h
@@ -86,6 +86,7 @@ struct quota_inode_ctx {
int8_t dirty;
gf_boolean_t create_status;
gf_boolean_t updation_status;
+ gf_boolean_t dirty_status;
gf_lock_t lock;
struct list_head contribution_head;
};