summaryrefslogtreecommitdiffstats
path: root/xlators/features/shard/src
diff options
context:
space:
mode:
Diffstat (limited to 'xlators/features/shard/src')
-rw-r--r--xlators/features/shard/src/shard.c48
1 files changed, 34 insertions, 14 deletions
diff --git a/xlators/features/shard/src/shard.c b/xlators/features/shard/src/shard.c
index 182678c9a64..d5f55efa0bc 100644
--- a/xlators/features/shard/src/shard.c
+++ b/xlators/features/shard/src/shard.c
@@ -650,7 +650,8 @@ out:
inode_t *
__shard_update_shards_inode_list(inode_t *linked_inode, xlator_t *this,
- inode_t *base_inode, int block_num)
+ inode_t *base_inode, int block_num,
+ uuid_t gfid)
{
char block_bname[256] = {
0,
@@ -680,10 +681,13 @@ __shard_update_shards_inode_list(inode_t *linked_inode, xlator_t *this,
inode_ref(linked_inode);
if (base_inode)
gf_uuid_copy(ctx->base_gfid, base_inode->gfid);
+ else
+ gf_uuid_copy(ctx->base_gfid, gfid);
ctx->block_num = block_num;
list_add_tail(&ctx->ilist, &priv->ilist_head);
priv->inode_count++;
- ctx->base_inode = base_inode;
+ if (base_inode)
+ ctx->base_inode = inode_ref(base_inode);
} else {
/*If on the other hand there is no available slot for this inode
* in the list, delete the lru inode from the head of the list,
@@ -701,6 +705,8 @@ __shard_update_shards_inode_list(inode_t *linked_inode, xlator_t *this,
* deleted from fsync list and fsync'd in a new frame,
* and then unlinked in memory and forgotten.
*/
+ if (!lru_base_inode)
+ goto after_fsync_check;
LOCK(&lru_base_inode->lock);
LOCK(&lru_inode->lock);
{
@@ -716,6 +722,7 @@ __shard_update_shards_inode_list(inode_t *linked_inode, xlator_t *this,
UNLOCK(&lru_inode->lock);
UNLOCK(&lru_base_inode->lock);
+ after_fsync_check:
if (!do_fsync) {
shard_make_block_bname(lru_inode_ctx->block_num,
lru_inode_ctx->base_gfid, block_bname,
@@ -728,20 +735,31 @@ __shard_update_shards_inode_list(inode_t *linked_inode, xlator_t *this,
inode_forget(lru_inode, 0);
} else {
fsync_inode = lru_inode;
- inode_unref(lru_base_inode);
+ if (lru_base_inode)
+ inode_unref(lru_base_inode);
}
/* The following unref corresponds to the ref
* held by inode_find() above.
*/
inode_unref(lru_inode);
+
+ /* The following unref corresponds to the ref held on the base shard
+ * at the time of adding shard inode to lru list
+ */
+ if (lru_base_inode)
+ inode_unref(lru_base_inode);
+
/* For as long as an inode is in lru list, we try to
* keep it alive by holding a ref on it.
*/
inode_ref(linked_inode);
if (base_inode)
gf_uuid_copy(ctx->base_gfid, base_inode->gfid);
+ else
+ gf_uuid_copy(ctx->base_gfid, gfid);
ctx->block_num = block_num;
- ctx->base_inode = base_inode;
+ if (base_inode)
+ ctx->base_inode = inode_ref(base_inode);
list_add_tail(&ctx->ilist, &priv->ilist_head);
}
} else {
@@ -1025,7 +1043,7 @@ shard_common_resolve_shards(call_frame_t *frame, xlator_t *this,
LOCK(&priv->lock);
{
fsync_inode = __shard_update_shards_inode_list(
- inode, this, res_inode, shard_idx_iter);
+ inode, this, res_inode, shard_idx_iter, gfid);
}
UNLOCK(&priv->lock);
shard_idx_iter++;
@@ -2167,7 +2185,7 @@ shard_link_block_inode(shard_local_t *local, int block_num, inode_t *inode,
LOCK(&priv->lock);
{
fsync_inode = __shard_update_shards_inode_list(
- linked_inode, this, local->loc.inode, block_num);
+ linked_inode, this, local->loc.inode, block_num, gfid);
}
UNLOCK(&priv->lock);
if (fsync_inode)
@@ -2875,17 +2893,18 @@ shard_unlink_block_inode(shard_local_t *local, int shard_block_num)
shard_inode_ctx_t *ctx = NULL;
shard_inode_ctx_t *base_ictx = NULL;
gf_boolean_t unlink_unref_forget = _gf_false;
+ int unref_base_inode = 0;
this = THIS;
priv = this->private;
inode = local->inode_list[shard_block_num - local->first_block];
- base_inode = local->resolver_base_inode;
+ shard_inode_ctx_get(inode, this, &ctx);
+ base_inode = ctx->base_inode;
if (base_inode)
gf_uuid_copy(gfid, base_inode->gfid);
else
- gf_uuid_copy(gfid, local->base_gfid);
-
+ gf_uuid_copy(gfid, ctx->base_gfid);
shard_make_block_bname(shard_block_num, gfid, block_bname,
sizeof(block_bname));
@@ -2898,17 +2917,16 @@ shard_unlink_block_inode(shard_local_t *local, int shard_block_num)
if (!list_empty(&ctx->ilist)) {
list_del_init(&ctx->ilist);
priv->inode_count--;
+ unref_base_inode++;
GF_ASSERT(priv->inode_count >= 0);
unlink_unref_forget = _gf_true;
}
if (ctx->fsync_needed) {
- if (base_inode)
- inode_unref(base_inode);
+ unref_base_inode++;
list_del_init(&ctx->to_fsync_list);
- if (base_inode) {
+ if (base_inode)
__shard_inode_ctx_get(base_inode, this, &base_ictx);
- base_ictx->fsync_count--;
- }
+ base_ictx->fsync_count--;
}
}
UNLOCK(&inode->lock);
@@ -2919,6 +2937,8 @@ shard_unlink_block_inode(shard_local_t *local, int shard_block_num)
inode_unref(inode);
inode_forget(inode, 0);
}
+ if (base_inode && unref_base_inode)
+ inode_ref_reduce_by_n(base_inode, unref_base_inode);
UNLOCK(&priv->lock);
}