summaryrefslogtreecommitdiffstats
path: root/xlators/features/marker/src
diff options
context:
space:
mode:
Diffstat (limited to 'xlators/features/marker/src')
-rw-r--r--xlators/features/marker/src/marker-quota.c24
-rw-r--r--xlators/features/marker/src/marker-quota.h4
-rw-r--r--xlators/features/marker/src/marker.c48
-rw-r--r--xlators/features/marker/src/marker.h2
4 files changed, 63 insertions, 15 deletions
diff --git a/xlators/features/marker/src/marker-quota.c b/xlators/features/marker/src/marker-quota.c
index 39f199bb849..e12cfab2527 100644
--- a/xlators/features/marker/src/marker-quota.c
+++ b/xlators/features/marker/src/marker-quota.c
@@ -755,11 +755,18 @@ out:
int32_t
mq_remove_contri (xlator_t *this, loc_t *loc, quota_inode_ctx_t *ctx,
- inode_contribution_t *contri, quota_meta_t *delta)
+ inode_contribution_t *contri, quota_meta_t *delta,
+ uint32_t nlink)
{
int32_t ret = -1;
char contri_key[QUOTA_KEY_MAX] = {0, };
+ if (nlink == 1) {
+ /*File was a last link and has been deleted */
+ ret = 0;
+ goto done;
+ }
+
GET_CONTRI_KEY (this, contri_key, contri->gfid, ret);
if (ret < 0) {
gf_log (this->name, GF_LOG_ERROR, "get contri_key "
@@ -786,6 +793,7 @@ mq_remove_contri (xlator_t *this, loc_t *loc, quota_inode_ctx_t *ctx,
}
}
+done:
LOCK (&contri->lock);
{
contri->contribution += delta->size;
@@ -943,7 +951,7 @@ mq_synctask_cleanup (int ret, call_frame_t *frame, void *opaque)
int
mq_synctask1 (xlator_t *this, synctask_fn_t task, gf_boolean_t spawn,
- loc_t *loc, quota_meta_t *contri)
+ loc_t *loc, quota_meta_t *contri, uint32_t nlink)
{
int32_t ret = -1;
quota_synctask_t *args = NULL;
@@ -959,6 +967,7 @@ mq_synctask1 (xlator_t *this, synctask_fn_t task, gf_boolean_t spawn,
args->this = this;
loc_copy (&args->loc, loc);
+ args->ia_nlink = nlink;
if (contri) {
args->contri = *contri;
@@ -988,7 +997,7 @@ out:
int
mq_synctask (xlator_t *this, synctask_fn_t task, gf_boolean_t spawn, loc_t *loc)
{
- return mq_synctask1 (this, task, spawn, loc, NULL);
+ return mq_synctask1 (this, task, spawn, loc, NULL, -1);
}
int32_t
@@ -1196,12 +1205,14 @@ mq_reduce_parent_size_task (void *opaque)
xlator_t *this = NULL;
loc_t *loc = NULL;
gf_boolean_t remove_xattr = _gf_true;
+ uint32_t nlink = 0;
GF_ASSERT (opaque);
args = (quota_synctask_t *) opaque;
loc = &args->loc;
contri = args->contri;
+ nlink = args->ia_nlink;
this = args->this;
THIS = this;
@@ -1261,7 +1272,8 @@ mq_reduce_parent_size_task (void *opaque)
mq_sub_meta (&delta, NULL);
if (remove_xattr) {
- ret = mq_remove_contri (this, loc, ctx, contribution, &delta);
+ ret = mq_remove_contri (this, loc, ctx, contribution, &delta,
+ nlink);
if (ret < 0)
goto out;
}
@@ -1307,7 +1319,7 @@ out:
int32_t
mq_reduce_parent_size_txn (xlator_t *this, loc_t *origin_loc,
- quota_meta_t *contri)
+ quota_meta_t *contri, uint32_t nlink)
{
int32_t ret = -1;
loc_t loc = {0, };
@@ -1325,7 +1337,7 @@ mq_reduce_parent_size_txn (xlator_t *this, loc_t *origin_loc,
}
ret = mq_synctask1 (this, mq_reduce_parent_size_task, _gf_true, &loc,
- contri);
+ contri, nlink);
out:
loc_wipe (&loc);
return ret;
diff --git a/xlators/features/marker/src/marker-quota.h b/xlators/features/marker/src/marker-quota.h
index 304c0ffa2a0..dc953704d11 100644
--- a/xlators/features/marker/src/marker-quota.h
+++ b/xlators/features/marker/src/marker-quota.h
@@ -115,6 +115,7 @@ struct quota_synctask {
loc_t loc;
quota_meta_t contri;
gf_boolean_t is_static;
+ uint32_t ia_nlink;
};
typedef struct quota_synctask quota_synctask_t;
@@ -145,7 +146,8 @@ int
mq_create_xattrs_txn (xlator_t *this, loc_t *loc, struct iatt *buf);
int32_t
-mq_reduce_parent_size_txn (xlator_t *, loc_t *, quota_meta_t *);
+mq_reduce_parent_size_txn (xlator_t *, loc_t *, quota_meta_t *,
+ uint32_t nlink);
int32_t
mq_forget (xlator_t *, quota_inode_ctx_t *);
diff --git a/xlators/features/marker/src/marker.c b/xlators/features/marker/src/marker.c
index 34e0fe73fec..8007933101d 100644
--- a/xlators/features/marker/src/marker.c
+++ b/xlators/features/marker/src/marker.c
@@ -941,7 +941,7 @@ marker_rmdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
priv = this->private;
if (priv->feature_enabled & GF_QUOTA)
- mq_reduce_parent_size_txn (this, &local->loc, NULL);
+ mq_reduce_parent_size_txn (this, &local->loc, NULL, 1);
if (priv->feature_enabled & GF_XTIME)
marker_xtime_update_marks (this, local);
@@ -990,6 +990,8 @@ marker_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
{
marker_conf_t *priv = NULL;
marker_local_t *local = NULL;
+ uint32_t nlink = -1;
+ int32_t ret = 0;
if (op_ret == -1) {
gf_log (this->name, GF_LOG_TRACE,
@@ -1009,8 +1011,14 @@ marker_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
priv = this->private;
if (priv->feature_enabled & GF_QUOTA) {
- if (!local->skip_txn)
- mq_reduce_parent_size_txn (this, &local->loc, NULL);
+ if (!local->skip_txn) {
+ if (xdata)
+ ret = dict_get_uint32 (xdata,
+ GF_RESPONSE_LINK_COUNT_XDATA, &nlink);
+
+ mq_reduce_parent_size_txn (this, &local->loc, NULL,
+ nlink);
+ }
}
if (priv->feature_enabled & GF_XTIME)
@@ -1029,6 +1037,7 @@ marker_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc, int xflag,
int32_t ret = 0;
marker_local_t *local = NULL;
marker_conf_t *priv = NULL;
+ gf_boolean_t dict_free = _gf_false;
priv = this->private;
@@ -1051,12 +1060,26 @@ marker_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc, int xflag,
goto unlink_wind;
}
+ if (xdata == NULL) {
+ xdata = dict_new ();
+ dict_free = _gf_true;
+ }
+
+ ret = dict_set_int32 (xdata, GF_REQUEST_LINK_COUNT_XDATA, 1);
+ if (ret < 0)
+ goto err;
+
unlink_wind:
STACK_WIND (frame, marker_unlink_cbk, FIRST_CHILD(this),
FIRST_CHILD(this)->fops->unlink, loc, xflag, xdata);
- return 0;
+ goto out;
+
err:
MARKER_STACK_UNWIND (unlink, frame, -1, ENOMEM, NULL, NULL, NULL);
+
+out:
+ if (dict_free)
+ dict_unref (xdata);
return 0;
}
@@ -1163,13 +1186,15 @@ marker_rename_done (call_frame_t *frame, void *cookie, xlator_t *this,
if (local->err != 0)
goto err;
- mq_reduce_parent_size_txn (this, &oplocal->loc, &oplocal->contribution);
+ mq_reduce_parent_size_txn (this, &oplocal->loc, &oplocal->contribution,
+ -1);
if (local->loc.inode != NULL) {
/* If destination file exits before rename, it would have
* been unlinked while renaming a file
*/
- mq_reduce_parent_size_txn (this, &local->loc, NULL);
+ mq_reduce_parent_size_txn (this, &local->loc, NULL,
+ local->ia_nlink);
}
newloc.inode = inode_ref (oplocal->loc.inode);
@@ -1327,6 +1352,12 @@ marker_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
goto quota_err;
}
+ local->ia_nlink = 0;
+ if (xdata)
+ ret = dict_get_uint32 (xdata,
+ GF_RESPONSE_LINK_COUNT_XDATA,
+ &local->ia_nlink);
+
local->buf = *buf;
stub = fop_rename_cbk_stub (frame, default_rename_cbk, op_ret,
op_errno, buf, preoldparent,
@@ -1636,7 +1667,10 @@ marker_rename (call_frame_t *frame, xlator_t *this, loc_t *oldloc,
lock.l_type = F_WRLCK;
lock.l_whence = SEEK_SET;
- local->xdata = dict_ref (xdata);
+ local->xdata = xdata ? dict_ref (xdata) : dict_new ();
+ ret = dict_set_int32 (local->xdata, GF_REQUEST_LINK_COUNT_XDATA, 1);
+ if (ret < 0)
+ goto err;
local->frame = frame;
local->lk_frame = create_frame (this, this->ctx->pool);
diff --git a/xlators/features/marker/src/marker.h b/xlators/features/marker/src/marker.h
index 6921ebd45e5..4726880b82f 100644
--- a/xlators/features/marker/src/marker.h
+++ b/xlators/features/marker/src/marker.h
@@ -95,7 +95,7 @@ struct marker_local{
uid_t uid;
gid_t gid;
int32_t ref;
- int32_t ia_nlink;
+ uint32_t ia_nlink;
struct iatt buf;
gf_lock_t lock;
mode_t mode;