|
|
d1681e |
From 1c094d1dc70dbc5d08181ef64fb300c95f331aec Mon Sep 17 00:00:00 2001
|
|
|
d1681e |
From: Krutika Dhananjay <kdhananj@redhat.com>
|
|
|
d1681e |
Date: Wed, 6 Dec 2017 16:55:33 +0530
|
|
|
d1681e |
Subject: [PATCH 171/180] features/shard: Upon FSYNC from upper layers, wind
|
|
|
d1681e |
fsync on all changed shards
|
|
|
d1681e |
|
|
|
d1681e |
> Upstream: https://review.gluster.org/19566
|
|
|
d1681e |
> BUG: 1468483
|
|
|
d1681e |
> Change-Id: Ib74354f57a18569762ad45a51f182822a2537421
|
|
|
d1681e |
|
|
|
d1681e |
Change-Id: I93797a60e3449d02413d171babfb8e4292e3f2f6
|
|
|
d1681e |
BUG: 1493085
|
|
|
d1681e |
Signed-off-by: Krutika Dhananjay <kdhananj@redhat.com>
|
|
|
d1681e |
Reviewed-on: https://code.engineering.redhat.com/gerrit/131737
|
|
|
d1681e |
Reviewed-by: Atin Mukherjee <amukherj@redhat.com>
|
|
|
d1681e |
Tested-by: RHGS Build Bot <nigelb@redhat.com>
|
|
|
d1681e |
Reviewed-by: Pranith Kumar Karampuri <pkarampu@redhat.com>
|
|
|
d1681e |
---
|
|
|
d1681e |
tests/bugs/shard/bug-1468483.t | 58 +++
|
|
|
d1681e |
tests/bugs/shard/shard-inode-refcount-test.t | 2 +-
|
|
|
d1681e |
xlators/features/shard/src/shard-messages.h | 9 +-
|
|
|
d1681e |
xlators/features/shard/src/shard.c | 533 +++++++++++++++++++++++++--
|
|
|
d1681e |
xlators/features/shard/src/shard.h | 6 +
|
|
|
d1681e |
5 files changed, 569 insertions(+), 39 deletions(-)
|
|
|
d1681e |
create mode 100644 tests/bugs/shard/bug-1468483.t
|
|
|
d1681e |
|
|
|
d1681e |
diff --git a/tests/bugs/shard/bug-1468483.t b/tests/bugs/shard/bug-1468483.t
|
|
|
d1681e |
new file mode 100644
|
|
|
d1681e |
index 0000000..e462b8d
|
|
|
d1681e |
--- /dev/null
|
|
|
d1681e |
+++ b/tests/bugs/shard/bug-1468483.t
|
|
|
d1681e |
@@ -0,0 +1,58 @@
|
|
|
d1681e |
+#!/bin/bash
|
|
|
d1681e |
+
|
|
|
d1681e |
+. $(dirname $0)/../../include.rc
|
|
|
d1681e |
+. $(dirname $0)/../../volume.rc
|
|
|
d1681e |
+. $(dirname $0)/../../common-utils.rc
|
|
|
d1681e |
+
|
|
|
d1681e |
+cleanup
|
|
|
d1681e |
+
|
|
|
d1681e |
+TEST glusterd
|
|
|
d1681e |
+TEST pidof glusterd
|
|
|
d1681e |
+TEST $CLI volume create $V0 $H0:$B0/${V0}0
|
|
|
d1681e |
+TEST $CLI volume set $V0 performance.write-behind off
|
|
|
d1681e |
+TEST $CLI volume set $V0 features.shard on
|
|
|
d1681e |
+TEST $CLI volume set $V0 features.shard-block-size 16MB
|
|
|
d1681e |
+TEST $CLI volume start $V0
|
|
|
d1681e |
+TEST $CLI volume profile $V0 start
|
|
|
d1681e |
+
|
|
|
d1681e |
+TEST $GFS --volfile-id=$V0 --volfile-server=$H0 $M0
|
|
|
d1681e |
+TEST dd if=/dev/zero conv=fsync of=$M0/foo bs=1M count=100
|
|
|
d1681e |
+
|
|
|
d1681e |
+#This should ensure /.shard is created on the bricks.
|
|
|
d1681e |
+TEST stat $B0/${V0}0/.shard
|
|
|
d1681e |
+
|
|
|
d1681e |
+gfid_foo=$(get_gfid_string $M0/foo)
|
|
|
d1681e |
+
|
|
|
d1681e |
+TEST stat $B0/${V0}0/.shard/$gfid_foo.1
|
|
|
d1681e |
+TEST stat $B0/${V0}0/.shard/$gfid_foo.2
|
|
|
d1681e |
+TEST stat $B0/${V0}0/.shard/$gfid_foo.3
|
|
|
d1681e |
+TEST stat $B0/${V0}0/.shard/$gfid_foo.4
|
|
|
d1681e |
+TEST stat $B0/${V0}0/.shard/$gfid_foo.5
|
|
|
d1681e |
+TEST stat $B0/${V0}0/.shard/$gfid_foo.6
|
|
|
d1681e |
+
|
|
|
d1681e |
+# For a file with 7 shards, there should be 7 fsyncs on the brick. Without this
|
|
|
d1681e |
+# fix, I was seeing only 1 fsync (on the base shard alone).
|
|
|
d1681e |
+
|
|
|
d1681e |
+EXPECT "7" echo `$CLI volume profile $V0 info incremental | grep -w FSYNC | awk '{print $8}'`
|
|
|
d1681e |
+
|
|
|
d1681e |
+useradd -M test_user 2>/dev/null
|
|
|
d1681e |
+
|
|
|
d1681e |
+TEST touch $M0/bar
|
|
|
d1681e |
+
|
|
|
d1681e |
+# Change ownership to non-root on bar.
|
|
|
d1681e |
+TEST chown test_user:test_user $M0/bar
|
|
|
d1681e |
+
|
|
|
d1681e |
+TEST $CLI volume profile $V0 stop
|
|
|
d1681e |
+TEST $CLI volume profile $V0 start
|
|
|
d1681e |
+
|
|
|
d1681e |
+# Write 100M of data on bar as non-root.
|
|
|
d1681e |
+TEST run_cmd_as_user test_user "dd if=/dev/zero conv=fsync of=$M0/bar bs=1M count=100"
|
|
|
d1681e |
+
|
|
|
d1681e |
+EXPECT "7" echo `$CLI volume profile $V0 info incremental | grep -w FSYNC | awk '{print $8}'`
|
|
|
d1681e |
+
|
|
|
d1681e |
+EXPECT_WITHIN $UMOUNT_TIMEOUT "Y" force_umount $M0
|
|
|
d1681e |
+userdel test_user
|
|
|
d1681e |
+TEST $CLI volume stop $V0
|
|
|
d1681e |
+TEST $CLI volume delete $V0
|
|
|
d1681e |
+
|
|
|
d1681e |
+cleanup
|
|
|
d1681e |
diff --git a/tests/bugs/shard/shard-inode-refcount-test.t b/tests/bugs/shard/shard-inode-refcount-test.t
|
|
|
d1681e |
index 6358097..03e0cc9 100644
|
|
|
d1681e |
--- a/tests/bugs/shard/shard-inode-refcount-test.t
|
|
|
d1681e |
+++ b/tests/bugs/shard/shard-inode-refcount-test.t
|
|
|
d1681e |
@@ -14,7 +14,7 @@ TEST $CLI volume start $V0
|
|
|
d1681e |
|
|
|
d1681e |
TEST glusterfs --volfile-id=$V0 --volfile-server=$H0 $M0
|
|
|
d1681e |
|
|
|
d1681e |
-TEST dd if=/dev/zero of=$M0/one-plus-five-shards bs=1M count=23
|
|
|
d1681e |
+TEST dd if=/dev/zero conv=fsync of=$M0/one-plus-five-shards bs=1M count=23
|
|
|
d1681e |
|
|
|
d1681e |
ACTIVE_INODES_BEFORE=$(get_mount_active_size_value $V0)
|
|
|
d1681e |
TEST rm -f $M0/one-plus-five-shards
|
|
|
d1681e |
diff --git a/xlators/features/shard/src/shard-messages.h b/xlators/features/shard/src/shard-messages.h
|
|
|
d1681e |
index 588cb68..8e61630 100644
|
|
|
d1681e |
--- a/xlators/features/shard/src/shard-messages.h
|
|
|
d1681e |
+++ b/xlators/features/shard/src/shard-messages.h
|
|
|
d1681e |
@@ -40,7 +40,7 @@
|
|
|
d1681e |
*/
|
|
|
d1681e |
|
|
|
d1681e |
#define GLFS_COMP_BASE_SHARD GLFS_MSGID_COMP_SHARD
|
|
|
d1681e |
-#define GLFS_NUM_MESSAGES 18
|
|
|
d1681e |
+#define GLFS_NUM_MESSAGES 19
|
|
|
d1681e |
#define GLFS_MSGID_END (GLFS_COMP_BASE_SHARD + GLFS_NUM_MESSAGES + 1)
|
|
|
d1681e |
|
|
|
d1681e |
#define glfs_msg_start_x GLFS_COMP_BASE_SHARD, "Invalid: Start of messages"
|
|
|
d1681e |
@@ -180,5 +180,12 @@
|
|
|
d1681e |
*/
|
|
|
d1681e |
#define SHARD_MSG_INVALID_FOP (GLFS_COMP_BASE_SHARD + 18)
|
|
|
d1681e |
|
|
|
d1681e |
+/*!
|
|
|
d1681e |
+ * @messageid 133019
|
|
|
d1681e |
+ * @diagnosis
|
|
|
d1681e |
+ * @recommendedaction
|
|
|
d1681e |
+*/
|
|
|
d1681e |
+#define SHARD_MSG_MEMALLOC_FAILED (GLFS_COMP_BASE_SHARD + 19)
|
|
|
d1681e |
+
|
|
|
d1681e |
#define glfs_msg_end_x GLFS_MSGID_END, "Invalid: End of messages"
|
|
|
d1681e |
#endif /* !_SHARD_MESSAGES_H_ */
|
|
|
d1681e |
diff --git a/xlators/features/shard/src/shard.c b/xlators/features/shard/src/shard.c
|
|
|
d1681e |
index 49cf04a..a661345 100644
|
|
|
d1681e |
--- a/xlators/features/shard/src/shard.c
|
|
|
d1681e |
+++ b/xlators/features/shard/src/shard.c
|
|
|
d1681e |
@@ -76,6 +76,7 @@ __shard_inode_ctx_get (inode_t *inode, xlator_t *this, shard_inode_ctx_t **ctx)
|
|
|
d1681e |
return ret;
|
|
|
d1681e |
|
|
|
d1681e |
INIT_LIST_HEAD (&ctx_p->ilist);
|
|
|
d1681e |
+ INIT_LIST_HEAD (&ctx_p->to_fsync_list);
|
|
|
d1681e |
|
|
|
d1681e |
ret = __inode_ctx_set (inode, this, (uint64_t *)&ctx_p);
|
|
|
d1681e |
if (ret < 0) {
|
|
|
d1681e |
@@ -205,6 +206,65 @@ shard_inode_ctx_set_refreshed_flag (inode_t *inode, xlator_t *this)
|
|
|
d1681e |
return ret;
|
|
|
d1681e |
}
|
|
|
d1681e |
|
|
|
d1681e |
+int
|
|
|
d1681e |
+__shard_inode_ctx_add_to_fsync_list (inode_t *base_inode, xlator_t *this,
|
|
|
d1681e |
+ inode_t *shard_inode)
|
|
|
d1681e |
+{
|
|
|
d1681e |
+ int ret = -1;
|
|
|
d1681e |
+ shard_inode_ctx_t *base_ictx = NULL;
|
|
|
d1681e |
+ shard_inode_ctx_t *shard_ictx = NULL;
|
|
|
d1681e |
+
|
|
|
d1681e |
+ ret = __shard_inode_ctx_get (base_inode, this, &base_ictx);
|
|
|
d1681e |
+ if (ret)
|
|
|
d1681e |
+ return ret;
|
|
|
d1681e |
+
|
|
|
d1681e |
+ ret = __shard_inode_ctx_get (shard_inode, this, &shard_ictx);
|
|
|
d1681e |
+ if (ret)
|
|
|
d1681e |
+ return ret;
|
|
|
d1681e |
+
|
|
|
d1681e |
+ if (shard_ictx->fsync_needed) {
|
|
|
d1681e |
+ shard_ictx->fsync_needed++;
|
|
|
d1681e |
+ return 1;
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+
|
|
|
d1681e |
+ list_add_tail (&shard_ictx->to_fsync_list, &base_ictx->to_fsync_list);
|
|
|
d1681e |
+ shard_ictx->inode = shard_inode;
|
|
|
d1681e |
+ shard_ictx->fsync_needed++;
|
|
|
d1681e |
+ base_ictx->fsync_count++;
|
|
|
d1681e |
+ shard_ictx->base_inode = base_inode;
|
|
|
d1681e |
+
|
|
|
d1681e |
+ return 0;
|
|
|
d1681e |
+}
|
|
|
d1681e |
+
|
|
|
d1681e |
+int
|
|
|
d1681e |
+shard_inode_ctx_add_to_fsync_list (inode_t *base_inode, xlator_t *this,
|
|
|
d1681e |
+ inode_t *shard_inode)
|
|
|
d1681e |
+{
|
|
|
d1681e |
+ int ret = -1;
|
|
|
d1681e |
+
|
|
|
d1681e |
+ /* This ref acts as a refkeepr on the base inode. We
|
|
|
d1681e |
+ * need to keep this inode alive as it holds the head
|
|
|
d1681e |
+ * of the to_fsync_list.
|
|
|
d1681e |
+ */
|
|
|
d1681e |
+ inode_ref (base_inode);
|
|
|
d1681e |
+
|
|
|
d1681e |
+ LOCK (&base_inode->lock);
|
|
|
d1681e |
+ LOCK (&shard_inode->lock);
|
|
|
d1681e |
+ {
|
|
|
d1681e |
+ ret = __shard_inode_ctx_add_to_fsync_list (base_inode, this,
|
|
|
d1681e |
+ shard_inode);
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ UNLOCK (&shard_inode->lock);
|
|
|
d1681e |
+ UNLOCK (&base_inode->lock);
|
|
|
d1681e |
+
|
|
|
d1681e |
+ /* Unref the base inode corresponding to the ref above, if the shard is
|
|
|
d1681e |
+ * found to be already part of the fsync list.
|
|
|
d1681e |
+ */
|
|
|
d1681e |
+ if (ret != 0)
|
|
|
d1681e |
+ inode_unref (base_inode);
|
|
|
d1681e |
+ return ret;
|
|
|
d1681e |
+}
|
|
|
d1681e |
+
|
|
|
d1681e |
gf_boolean_t
|
|
|
d1681e |
__shard_inode_ctx_needs_lookup (inode_t *inode, xlator_t *this)
|
|
|
d1681e |
{
|
|
|
d1681e |
@@ -301,6 +361,40 @@ shard_inode_ctx_get_block_size (inode_t *inode, xlator_t *this,
|
|
|
d1681e |
}
|
|
|
d1681e |
|
|
|
d1681e |
int
|
|
|
d1681e |
+__shard_inode_ctx_get_fsync_count (inode_t *inode, xlator_t *this,
|
|
|
d1681e |
+ int *fsync_count)
|
|
|
d1681e |
+{
|
|
|
d1681e |
+ int ret = -1;
|
|
|
d1681e |
+ uint64_t ctx_uint = 0;
|
|
|
d1681e |
+ shard_inode_ctx_t *ctx = NULL;
|
|
|
d1681e |
+
|
|
|
d1681e |
+ ret = __inode_ctx_get (inode, this, &ctx_uint);
|
|
|
d1681e |
+ if (ret < 0)
|
|
|
d1681e |
+ return ret;
|
|
|
d1681e |
+
|
|
|
d1681e |
+ ctx = (shard_inode_ctx_t *) ctx_uint;
|
|
|
d1681e |
+
|
|
|
d1681e |
+ *fsync_count = ctx->fsync_needed;
|
|
|
d1681e |
+
|
|
|
d1681e |
+ return 0;
|
|
|
d1681e |
+}
|
|
|
d1681e |
+
|
|
|
d1681e |
+int
|
|
|
d1681e |
+shard_inode_ctx_get_fsync_count (inode_t *inode, xlator_t *this,
|
|
|
d1681e |
+ int *fsync_count)
|
|
|
d1681e |
+{
|
|
|
d1681e |
+ int ret = -1;
|
|
|
d1681e |
+
|
|
|
d1681e |
+ LOCK (&inode->lock);
|
|
|
d1681e |
+ {
|
|
|
d1681e |
+ ret = __shard_inode_ctx_get_fsync_count (inode, this,
|
|
|
d1681e |
+ fsync_count);
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ UNLOCK (&inode->lock);
|
|
|
d1681e |
+
|
|
|
d1681e |
+ return ret;
|
|
|
d1681e |
+}
|
|
|
d1681e |
+int
|
|
|
d1681e |
__shard_inode_ctx_get_all (inode_t *inode, xlator_t *this,
|
|
|
d1681e |
shard_inode_ctx_t *ctx_out)
|
|
|
d1681e |
{
|
|
|
d1681e |
@@ -482,15 +576,19 @@ out:
|
|
|
d1681e |
return ret;
|
|
|
d1681e |
}
|
|
|
d1681e |
|
|
|
d1681e |
-void
|
|
|
d1681e |
+inode_t *
|
|
|
d1681e |
__shard_update_shards_inode_list (inode_t *linked_inode, xlator_t *this,
|
|
|
d1681e |
inode_t *base_inode, int block_num)
|
|
|
d1681e |
{
|
|
|
d1681e |
- char block_bname[256] = {0,};
|
|
|
d1681e |
- inode_t *lru_inode = NULL;
|
|
|
d1681e |
- shard_priv_t *priv = NULL;
|
|
|
d1681e |
- shard_inode_ctx_t *ctx = NULL;
|
|
|
d1681e |
- shard_inode_ctx_t *lru_inode_ctx = NULL;
|
|
|
d1681e |
+ char block_bname[256] = {0,};
|
|
|
d1681e |
+ inode_t *lru_inode = NULL;
|
|
|
d1681e |
+ shard_priv_t *priv = NULL;
|
|
|
d1681e |
+ shard_inode_ctx_t *ctx = NULL;
|
|
|
d1681e |
+ shard_inode_ctx_t *lru_inode_ctx = NULL;
|
|
|
d1681e |
+ shard_inode_ctx_t *lru_base_inode_ctx = NULL;
|
|
|
d1681e |
+ inode_t *fsync_inode = NULL;
|
|
|
d1681e |
+ inode_t *lru_base_inode = NULL;
|
|
|
d1681e |
+ gf_boolean_t do_fsync = _gf_false;
|
|
|
d1681e |
|
|
|
d1681e |
priv = this->private;
|
|
|
d1681e |
|
|
|
d1681e |
@@ -510,6 +608,7 @@ __shard_update_shards_inode_list (inode_t *linked_inode, xlator_t *this,
|
|
|
d1681e |
ctx->block_num = block_num;
|
|
|
d1681e |
list_add_tail (&ctx->ilist, &priv->ilist_head);
|
|
|
d1681e |
priv->inode_count++;
|
|
|
d1681e |
+ ctx->base_inode = base_inode;
|
|
|
d1681e |
} else {
|
|
|
d1681e |
/*If on the other hand there is no available slot for this inode
|
|
|
d1681e |
* in the list, delete the lru inode from the head of the list,
|
|
|
d1681e |
@@ -519,30 +618,56 @@ __shard_update_shards_inode_list (inode_t *linked_inode, xlator_t *this,
|
|
|
d1681e |
shard_inode_ctx_t,
|
|
|
d1681e |
ilist);
|
|
|
d1681e |
GF_ASSERT (lru_inode_ctx->block_num > 0);
|
|
|
d1681e |
+ lru_base_inode = lru_inode_ctx->base_inode;
|
|
|
d1681e |
list_del_init (&lru_inode_ctx->ilist);
|
|
|
d1681e |
lru_inode = inode_find (linked_inode->table,
|
|
|
d1681e |
lru_inode_ctx->stat.ia_gfid);
|
|
|
d1681e |
- shard_make_block_bname (lru_inode_ctx->block_num,
|
|
|
d1681e |
- lru_inode_ctx->base_gfid,
|
|
|
d1681e |
- block_bname,
|
|
|
d1681e |
- sizeof (block_bname));
|
|
|
d1681e |
- inode_unlink (lru_inode, priv->dot_shard_inode,
|
|
|
d1681e |
- block_bname);
|
|
|
d1681e |
- /* The following unref corresponds to the ref held by
|
|
|
d1681e |
- * inode_find() above.
|
|
|
d1681e |
+ /* If the lru inode was part of the pending-fsync list,
|
|
|
d1681e |
+ * the base inode needs to be unref'd, the lru inode
|
|
|
d1681e |
+ * deleted from fsync list and fsync'd in a new frame,
|
|
|
d1681e |
+ * and then unlinked in memory and forgotten.
|
|
|
d1681e |
*/
|
|
|
d1681e |
- inode_unref (lru_inode);
|
|
|
d1681e |
+ LOCK (&lru_base_inode->lock);
|
|
|
d1681e |
+ LOCK (&lru_inode->lock);
|
|
|
d1681e |
+ {
|
|
|
d1681e |
+ if (!list_empty(&lru_inode_ctx->to_fsync_list)) {
|
|
|
d1681e |
+ list_del_init (&lru_inode_ctx->to_fsync_list);
|
|
|
d1681e |
+ lru_inode_ctx->fsync_needed = 0;
|
|
|
d1681e |
+ do_fsync = _gf_true;
|
|
|
d1681e |
+ __shard_inode_ctx_get (lru_base_inode, this, &lru_base_inode_ctx);
|
|
|
d1681e |
+ lru_base_inode_ctx->fsync_count--;
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ UNLOCK (&lru_inode->lock);
|
|
|
d1681e |
+ UNLOCK (&lru_base_inode->lock);
|
|
|
d1681e |
+
|
|
|
d1681e |
+ if (!do_fsync) {
|
|
|
d1681e |
+ shard_make_block_bname (lru_inode_ctx->block_num,
|
|
|
d1681e |
+ lru_inode_ctx->base_gfid,
|
|
|
d1681e |
+ block_bname,
|
|
|
d1681e |
+ sizeof (block_bname));
|
|
|
d1681e |
/* The following unref corresponds to the ref held at
|
|
|
d1681e |
- * the time the shard was created or looked up
|
|
|
d1681e |
+ * the time the shard was added to the lru list.
|
|
|
d1681e |
+ */
|
|
|
d1681e |
+ inode_unref (lru_inode);
|
|
|
d1681e |
+ inode_unlink (lru_inode, priv->dot_shard_inode,
|
|
|
d1681e |
+ block_bname);
|
|
|
d1681e |
+ inode_forget (lru_inode, 0);
|
|
|
d1681e |
+ } else {
|
|
|
d1681e |
+ fsync_inode = lru_inode;
|
|
|
d1681e |
+ inode_unref (lru_base_inode);
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ /* The following unref corresponds to the ref
|
|
|
d1681e |
+ * held by inode_find() above.
|
|
|
d1681e |
*/
|
|
|
d1681e |
inode_unref (lru_inode);
|
|
|
d1681e |
- inode_forget (lru_inode, 0);
|
|
|
d1681e |
/* For as long as an inode is in lru list, we try to
|
|
|
d1681e |
* keep it alive by holding a ref on it.
|
|
|
d1681e |
*/
|
|
|
d1681e |
inode_ref (linked_inode);
|
|
|
d1681e |
gf_uuid_copy (ctx->base_gfid, base_inode->gfid);
|
|
|
d1681e |
ctx->block_num = block_num;
|
|
|
d1681e |
+ ctx->base_inode = base_inode;
|
|
|
d1681e |
list_add_tail (&ctx->ilist, &priv->ilist_head);
|
|
|
d1681e |
}
|
|
|
d1681e |
} else {
|
|
|
d1681e |
@@ -551,6 +676,7 @@ __shard_update_shards_inode_list (inode_t *linked_inode, xlator_t *this,
|
|
|
d1681e |
*/
|
|
|
d1681e |
list_move_tail (&ctx->ilist, &priv->ilist_head);
|
|
|
d1681e |
}
|
|
|
d1681e |
+ return fsync_inode;
|
|
|
d1681e |
}
|
|
|
d1681e |
|
|
|
d1681e |
int
|
|
|
d1681e |
@@ -617,6 +743,85 @@ shard_common_inode_write_success_unwind (glusterfs_fop_t fop,
|
|
|
d1681e |
}
|
|
|
d1681e |
|
|
|
d1681e |
int
|
|
|
d1681e |
+shard_evicted_inode_fsync_cbk (call_frame_t *frame, void *cookie,
|
|
|
d1681e |
+ xlator_t *this, int32_t op_ret, int32_t op_errno,
|
|
|
d1681e |
+ struct iatt *prebuf, struct iatt *postbuf,
|
|
|
d1681e |
+ dict_t *xdata)
|
|
|
d1681e |
+{
|
|
|
d1681e |
+ char block_bname[256] = {0,};
|
|
|
d1681e |
+ fd_t *anon_fd = cookie;
|
|
|
d1681e |
+ inode_t *shard_inode = NULL;
|
|
|
d1681e |
+ shard_inode_ctx_t *ctx = NULL;
|
|
|
d1681e |
+ shard_priv_t *priv = NULL;
|
|
|
d1681e |
+
|
|
|
d1681e |
+ priv = this->private;
|
|
|
d1681e |
+ shard_inode = anon_fd->inode;
|
|
|
d1681e |
+
|
|
|
d1681e |
+ if (op_ret < 0) {
|
|
|
d1681e |
+ gf_msg (this->name, GF_LOG_WARNING, op_errno,
|
|
|
d1681e |
+ SHARD_MSG_MEMALLOC_FAILED, "fsync failed on shard");
|
|
|
d1681e |
+ goto out;
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+
|
|
|
d1681e |
+ LOCK (&priv->lock);
|
|
|
d1681e |
+ LOCK(&shard_inode->lock);
|
|
|
d1681e |
+ {
|
|
|
d1681e |
+ __shard_inode_ctx_get (shard_inode, this, &ctx;;
|
|
|
d1681e |
+ if ((list_empty(&ctx->to_fsync_list)) &&
|
|
|
d1681e |
+ (list_empty(&ctx->ilist))) {
|
|
|
d1681e |
+ shard_make_block_bname (ctx->block_num,
|
|
|
d1681e |
+ shard_inode->gfid, block_bname,
|
|
|
d1681e |
+ sizeof (block_bname));
|
|
|
d1681e |
+ inode_unlink (shard_inode, priv->dot_shard_inode,
|
|
|
d1681e |
+ block_bname);
|
|
|
d1681e |
+ /* The following unref corresponds to the ref held by
|
|
|
d1681e |
+ * inode_link() at the time the shard was created or
|
|
|
d1681e |
+ * looked up
|
|
|
d1681e |
+ */
|
|
|
d1681e |
+ inode_unref (shard_inode);
|
|
|
d1681e |
+ inode_forget (shard_inode, 0);
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ UNLOCK(&shard_inode->lock);
|
|
|
d1681e |
+ UNLOCK(&priv->lock);
|
|
|
d1681e |
+
|
|
|
d1681e |
+out:
|
|
|
d1681e |
+ if (anon_fd)
|
|
|
d1681e |
+ fd_unref (anon_fd);
|
|
|
d1681e |
+ STACK_DESTROY (frame->root);
|
|
|
d1681e |
+ return 0;
|
|
|
d1681e |
+}
|
|
|
d1681e |
+
|
|
|
d1681e |
+int
|
|
|
d1681e |
+shard_initiate_evicted_inode_fsync (xlator_t *this, inode_t *inode)
|
|
|
d1681e |
+{
|
|
|
d1681e |
+ fd_t *anon_fd = NULL;
|
|
|
d1681e |
+ call_frame_t *fsync_frame = NULL;
|
|
|
d1681e |
+
|
|
|
d1681e |
+ fsync_frame = create_frame (this, this->ctx->pool);
|
|
|
d1681e |
+ if (!fsync_frame) {
|
|
|
d1681e |
+ gf_msg (this->name, GF_LOG_WARNING, ENOMEM,
|
|
|
d1681e |
+ SHARD_MSG_MEMALLOC_FAILED, "Failed to create new frame "
|
|
|
d1681e |
+ "to fsync shard");
|
|
|
d1681e |
+ return -1;
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+
|
|
|
d1681e |
+ anon_fd = fd_anonymous (inode);
|
|
|
d1681e |
+ if (!anon_fd) {
|
|
|
d1681e |
+ gf_msg (this->name, GF_LOG_WARNING, ENOMEM,
|
|
|
d1681e |
+ SHARD_MSG_MEMALLOC_FAILED, "Failed to create anon fd to"
|
|
|
d1681e |
+ " fsync shard");
|
|
|
d1681e |
+ STACK_DESTROY (fsync_frame->root);
|
|
|
d1681e |
+ return -1;
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+
|
|
|
d1681e |
+ STACK_WIND_COOKIE (fsync_frame, shard_evicted_inode_fsync_cbk, anon_fd,
|
|
|
d1681e |
+ FIRST_CHILD(this), FIRST_CHILD(this)->fops->fsync,
|
|
|
d1681e |
+ anon_fd, 1, NULL);
|
|
|
d1681e |
+ return 0;
|
|
|
d1681e |
+}
|
|
|
d1681e |
+
|
|
|
d1681e |
+int
|
|
|
d1681e |
shard_common_resolve_shards (call_frame_t *frame, xlator_t *this,
|
|
|
d1681e |
shard_post_resolve_fop_handler_t post_res_handler)
|
|
|
d1681e |
{
|
|
|
d1681e |
@@ -625,6 +830,7 @@ shard_common_resolve_shards (call_frame_t *frame, xlator_t *this,
|
|
|
d1681e |
char path[PATH_MAX] = {0,};
|
|
|
d1681e |
inode_t *inode = NULL;
|
|
|
d1681e |
inode_t *res_inode = NULL;
|
|
|
d1681e |
+ inode_t *fsync_inode = NULL;
|
|
|
d1681e |
shard_priv_t *priv = NULL;
|
|
|
d1681e |
shard_local_t *local = NULL;
|
|
|
d1681e |
|
|
|
d1681e |
@@ -661,20 +867,22 @@ shard_common_resolve_shards (call_frame_t *frame, xlator_t *this,
|
|
|
d1681e |
*/
|
|
|
d1681e |
LOCK(&priv->lock);
|
|
|
d1681e |
{
|
|
|
d1681e |
- __shard_update_shards_inode_list (inode, this,
|
|
|
d1681e |
+ fsync_inode = __shard_update_shards_inode_list (inode,
|
|
|
d1681e |
+ this,
|
|
|
d1681e |
res_inode,
|
|
|
d1681e |
shard_idx_iter);
|
|
|
d1681e |
}
|
|
|
d1681e |
UNLOCK(&priv->lock);
|
|
|
d1681e |
shard_idx_iter++;
|
|
|
d1681e |
-
|
|
|
d1681e |
+ if (fsync_inode)
|
|
|
d1681e |
+ shard_initiate_evicted_inode_fsync (this,
|
|
|
d1681e |
+ fsync_inode);
|
|
|
d1681e |
continue;
|
|
|
d1681e |
} else {
|
|
|
d1681e |
local->call_count++;
|
|
|
d1681e |
shard_idx_iter++;
|
|
|
d1681e |
}
|
|
|
d1681e |
}
|
|
|
d1681e |
-
|
|
|
d1681e |
out:
|
|
|
d1681e |
post_res_handler (frame, this);
|
|
|
d1681e |
return 0;
|
|
|
d1681e |
@@ -1657,6 +1865,7 @@ shard_link_block_inode (shard_local_t *local, int block_num, inode_t *inode,
|
|
|
d1681e |
char block_bname[256] = {0,};
|
|
|
d1681e |
inode_t *linked_inode = NULL;
|
|
|
d1681e |
xlator_t *this = NULL;
|
|
|
d1681e |
+ inode_t *fsync_inode = NULL;
|
|
|
d1681e |
shard_priv_t *priv = NULL;
|
|
|
d1681e |
|
|
|
d1681e |
this = THIS;
|
|
|
d1681e |
@@ -1674,10 +1883,14 @@ shard_link_block_inode (shard_local_t *local, int block_num, inode_t *inode,
|
|
|
d1681e |
|
|
|
d1681e |
LOCK(&priv->lock);
|
|
|
d1681e |
{
|
|
|
d1681e |
- __shard_update_shards_inode_list (linked_inode, this,
|
|
|
d1681e |
- local->loc.inode, block_num);
|
|
|
d1681e |
+ fsync_inode = __shard_update_shards_inode_list (linked_inode,
|
|
|
d1681e |
+ this,
|
|
|
d1681e |
+ local->loc.inode,
|
|
|
d1681e |
+ block_num);
|
|
|
d1681e |
}
|
|
|
d1681e |
UNLOCK(&priv->lock);
|
|
|
d1681e |
+ if (fsync_inode)
|
|
|
d1681e |
+ shard_initiate_evicted_inode_fsync (this, fsync_inode);
|
|
|
d1681e |
}
|
|
|
d1681e |
|
|
|
d1681e |
int
|
|
|
d1681e |
@@ -2120,6 +2333,7 @@ shard_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset,
|
|
|
d1681e |
local->xattr_req = (xdata) ? dict_ref (xdata) : dict_new ();
|
|
|
d1681e |
if (!local->xattr_req)
|
|
|
d1681e |
goto err;
|
|
|
d1681e |
+ local->resolver_base_inode = loc->inode;
|
|
|
d1681e |
|
|
|
d1681e |
shard_lookup_base_file (frame, this, &local->loc,
|
|
|
d1681e |
shard_post_lookup_truncate_handler);
|
|
|
d1681e |
@@ -2172,6 +2386,7 @@ shard_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
|
|
|
d1681e |
|
|
|
d1681e |
local->loc.inode = inode_ref (fd->inode);
|
|
|
d1681e |
gf_uuid_copy (local->loc.gfid, fd->inode->gfid);
|
|
|
d1681e |
+ local->resolver_base_inode = fd->inode;
|
|
|
d1681e |
|
|
|
d1681e |
shard_lookup_base_file (frame, this, &local->loc,
|
|
|
d1681e |
shard_post_lookup_truncate_handler);
|
|
|
d1681e |
@@ -2509,32 +2724,48 @@ shard_unlink_block_inode (shard_local_t *local, int shard_block_num)
|
|
|
d1681e |
{
|
|
|
d1681e |
char block_bname[256] = {0,};
|
|
|
d1681e |
inode_t *inode = NULL;
|
|
|
d1681e |
+ inode_t *base_inode = NULL;
|
|
|
d1681e |
xlator_t *this = NULL;
|
|
|
d1681e |
shard_priv_t *priv = NULL;
|
|
|
d1681e |
shard_inode_ctx_t *ctx = NULL;
|
|
|
d1681e |
+ shard_inode_ctx_t *base_ictx = NULL;
|
|
|
d1681e |
+ gf_boolean_t unlink_unref_forget = _gf_false;
|
|
|
d1681e |
|
|
|
d1681e |
this = THIS;
|
|
|
d1681e |
priv = this->private;
|
|
|
d1681e |
|
|
|
d1681e |
inode = local->inode_list[shard_block_num - local->first_block];
|
|
|
d1681e |
+ base_inode = local->resolver_base_inode;
|
|
|
d1681e |
|
|
|
d1681e |
shard_make_block_bname (shard_block_num, (local->loc.inode)->gfid,
|
|
|
d1681e |
block_bname, sizeof (block_bname));
|
|
|
d1681e |
|
|
|
d1681e |
LOCK(&priv->lock);
|
|
|
d1681e |
+ LOCK(&base_inode->lock);
|
|
|
d1681e |
+ LOCK(&inode->lock);
|
|
|
d1681e |
{
|
|
|
d1681e |
- shard_inode_ctx_get (inode, this, &ctx;;
|
|
|
d1681e |
+ __shard_inode_ctx_get (inode, this, &ctx;;
|
|
|
d1681e |
if (!list_empty (&ctx->ilist)) {
|
|
|
d1681e |
list_del_init (&ctx->ilist);
|
|
|
d1681e |
priv->inode_count--;
|
|
|
d1681e |
GF_ASSERT (priv->inode_count >= 0);
|
|
|
d1681e |
- inode_unlink (inode, priv->dot_shard_inode, block_bname);
|
|
|
d1681e |
- inode_unref (inode);
|
|
|
d1681e |
- inode_forget (inode, 0);
|
|
|
d1681e |
+ unlink_unref_forget = _gf_true;
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ if (ctx->fsync_needed) {
|
|
|
d1681e |
+ inode_unref (base_inode);
|
|
|
d1681e |
+ list_del_init (&ctx->to_fsync_list);
|
|
|
d1681e |
+ __shard_inode_ctx_get (base_inode, this, &base_ictx);
|
|
|
d1681e |
+ base_ictx->fsync_count--;
|
|
|
d1681e |
}
|
|
|
d1681e |
}
|
|
|
d1681e |
+ UNLOCK(&inode->lock);
|
|
|
d1681e |
+ UNLOCK(&base_inode->lock);
|
|
|
d1681e |
+ if (unlink_unref_forget) {
|
|
|
d1681e |
+ inode_unlink (inode, priv->dot_shard_inode, block_bname);
|
|
|
d1681e |
+ inode_unref (inode);
|
|
|
d1681e |
+ inode_forget (inode, 0);
|
|
|
d1681e |
+ }
|
|
|
d1681e |
UNLOCK(&priv->lock);
|
|
|
d1681e |
-
|
|
|
d1681e |
}
|
|
|
d1681e |
|
|
|
d1681e |
int
|
|
|
d1681e |
@@ -2752,6 +2983,7 @@ shard_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc, int xflag,
|
|
|
d1681e |
local->xflag = xflag;
|
|
|
d1681e |
local->xattr_req = (xdata) ? dict_ref (xdata) : dict_new ();
|
|
|
d1681e |
local->block_size = block_size;
|
|
|
d1681e |
+ local->resolver_base_inode = loc->inode;
|
|
|
d1681e |
local->fop = GF_FOP_UNLINK;
|
|
|
d1681e |
if (!this->itable)
|
|
|
d1681e |
this->itable = (local->loc.inode)->table;
|
|
|
d1681e |
@@ -2988,6 +3220,7 @@ shard_rename (call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc,
|
|
|
d1681e |
frame->local = local;
|
|
|
d1681e |
loc_copy (&local->loc, oldloc);
|
|
|
d1681e |
loc_copy (&local->loc2, newloc);
|
|
|
d1681e |
+ local->resolver_base_inode = newloc->inode;
|
|
|
d1681e |
local->fop = GF_FOP_RENAME;
|
|
|
d1681e |
local->xattr_req = (xdata) ? dict_ref (xdata) : dict_new();
|
|
|
d1681e |
if (!local->xattr_req)
|
|
|
d1681e |
@@ -3754,6 +3987,10 @@ shard_common_inode_write_do_cbk (call_frame_t *frame, void *cookie,
|
|
|
d1681e |
local->delta_size += (post->ia_size - pre->ia_size);
|
|
|
d1681e |
shard_inode_ctx_set (local->fd->inode, this, post, 0,
|
|
|
d1681e |
SHARD_MASK_TIMES);
|
|
|
d1681e |
+ if (local->fd->inode != anon_fd->inode)
|
|
|
d1681e |
+ shard_inode_ctx_add_to_fsync_list (local->fd->inode,
|
|
|
d1681e |
+ this,
|
|
|
d1681e |
+ anon_fd->inode);
|
|
|
d1681e |
}
|
|
|
d1681e |
}
|
|
|
d1681e |
UNLOCK (&frame->lock);
|
|
|
d1681e |
@@ -4204,18 +4441,198 @@ shard_flush (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
|
|
|
d1681e |
}
|
|
|
d1681e |
|
|
|
d1681e |
int
|
|
|
d1681e |
-shard_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
|
|
|
d1681e |
- int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
|
|
|
d1681e |
- struct iatt *postbuf, dict_t *xdata)
|
|
|
d1681e |
+__shard_get_timestamps_from_inode_ctx (shard_local_t *local, inode_t *inode,
|
|
|
d1681e |
+ xlator_t *this)
|
|
|
d1681e |
{
|
|
|
d1681e |
- if (op_ret < 0)
|
|
|
d1681e |
+ int ret = -1;
|
|
|
d1681e |
+ uint64_t ctx_uint = 0;
|
|
|
d1681e |
+ shard_inode_ctx_t *ctx = NULL;
|
|
|
d1681e |
+
|
|
|
d1681e |
+ ret = __inode_ctx_get (inode, this, &ctx_uint);
|
|
|
d1681e |
+ if (ret < 0)
|
|
|
d1681e |
+ return ret;
|
|
|
d1681e |
+
|
|
|
d1681e |
+ ctx = (shard_inode_ctx_t *) ctx_uint;
|
|
|
d1681e |
+
|
|
|
d1681e |
+ local->postbuf.ia_ctime = ctx->stat.ia_ctime;
|
|
|
d1681e |
+ local->postbuf.ia_ctime_nsec = ctx->stat.ia_ctime_nsec;
|
|
|
d1681e |
+ local->postbuf.ia_atime = ctx->stat.ia_atime;
|
|
|
d1681e |
+ local->postbuf.ia_atime_nsec = ctx->stat.ia_atime_nsec;
|
|
|
d1681e |
+ local->postbuf.ia_mtime = ctx->stat.ia_mtime;
|
|
|
d1681e |
+ local->postbuf.ia_mtime_nsec = ctx->stat.ia_mtime_nsec;
|
|
|
d1681e |
+
|
|
|
d1681e |
+ return 0;
|
|
|
d1681e |
+}
|
|
|
d1681e |
+
|
|
|
d1681e |
+int
|
|
|
d1681e |
+shard_get_timestamps_from_inode_ctx (shard_local_t *local, inode_t *inode,
|
|
|
d1681e |
+ xlator_t *this)
|
|
|
d1681e |
+{
|
|
|
d1681e |
+ int ret = 0;
|
|
|
d1681e |
+
|
|
|
d1681e |
+ LOCK (&inode->lock);
|
|
|
d1681e |
+ {
|
|
|
d1681e |
+ ret = __shard_get_timestamps_from_inode_ctx (local, inode,
|
|
|
d1681e |
+ this);
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ UNLOCK (&inode->lock);
|
|
|
d1681e |
+
|
|
|
d1681e |
+ return ret;
|
|
|
d1681e |
+}
|
|
|
d1681e |
+
|
|
|
d1681e |
+int
|
|
|
d1681e |
+shard_fsync_shards_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
|
|
|
d1681e |
+ int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
|
|
|
d1681e |
+ struct iatt *postbuf, dict_t *xdata)
|
|
|
d1681e |
+{
|
|
|
d1681e |
+ int call_count = 0;
|
|
|
d1681e |
+ uint64_t fsync_count = 0;
|
|
|
d1681e |
+ fd_t *anon_fd = cookie;
|
|
|
d1681e |
+ shard_local_t *local = NULL;
|
|
|
d1681e |
+ shard_inode_ctx_t *ctx = NULL;
|
|
|
d1681e |
+ shard_inode_ctx_t *base_ictx = NULL;
|
|
|
d1681e |
+ inode_t *base_inode = NULL;
|
|
|
d1681e |
+
|
|
|
d1681e |
+ local = frame->local;
|
|
|
d1681e |
+ base_inode = local->fd->inode;
|
|
|
d1681e |
+
|
|
|
d1681e |
+ if (local->op_ret < 0)
|
|
|
d1681e |
goto out;
|
|
|
d1681e |
|
|
|
d1681e |
- /* To-Do: Wind fsync on all shards of the file */
|
|
|
d1681e |
- postbuf->ia_ctime = 0;
|
|
|
d1681e |
+ LOCK (&frame->lock);
|
|
|
d1681e |
+ {
|
|
|
d1681e |
+ if (op_ret < 0) {
|
|
|
d1681e |
+ local->op_ret = op_ret;
|
|
|
d1681e |
+ local->op_errno = op_errno;
|
|
|
d1681e |
+ goto out;
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ shard_inode_ctx_set (local->fd->inode, this, postbuf, 0,
|
|
|
d1681e |
+ SHARD_MASK_TIMES);
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ UNLOCK (&frame->lock);
|
|
|
d1681e |
+ fd_ctx_get (anon_fd, this, &fsync_count);
|
|
|
d1681e |
out:
|
|
|
d1681e |
- SHARD_STACK_UNWIND (fsync, frame, op_ret, op_errno, prebuf, postbuf,
|
|
|
d1681e |
- xdata);
|
|
|
d1681e |
+ if (base_inode != anon_fd->inode) {
|
|
|
d1681e |
+ LOCK (&base_inode->lock);
|
|
|
d1681e |
+ LOCK (&anon_fd->inode->lock);
|
|
|
d1681e |
+ {
|
|
|
d1681e |
+ __shard_inode_ctx_get (anon_fd->inode, this, &ctx;;
|
|
|
d1681e |
+ __shard_inode_ctx_get (base_inode, this, &base_ictx);
|
|
|
d1681e |
+ if (op_ret == 0)
|
|
|
d1681e |
+ ctx->fsync_needed -= fsync_count;
|
|
|
d1681e |
+ GF_ASSERT (ctx->fsync_needed >= 0);
|
|
|
d1681e |
+ list_del_init (&ctx->to_fsync_list);
|
|
|
d1681e |
+ if (ctx->fsync_needed != 0) {
|
|
|
d1681e |
+ list_add_tail (&ctx->to_fsync_list,
|
|
|
d1681e |
+ &base_ictx->to_fsync_list);
|
|
|
d1681e |
+ base_ictx->fsync_count++;
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ UNLOCK (&anon_fd->inode->lock);
|
|
|
d1681e |
+ UNLOCK (&base_inode->lock);
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ if (anon_fd)
|
|
|
d1681e |
+ fd_unref (anon_fd);
|
|
|
d1681e |
+
|
|
|
d1681e |
+ call_count = shard_call_count_return (frame);
|
|
|
d1681e |
+ if (call_count != 0)
|
|
|
d1681e |
+ return 0;
|
|
|
d1681e |
+
|
|
|
d1681e |
+ if (local->op_ret < 0) {
|
|
|
d1681e |
+ SHARD_STACK_UNWIND (fsync, frame, local->op_ret,
|
|
|
d1681e |
+ local->op_errno, NULL, NULL, NULL);
|
|
|
d1681e |
+ } else {
|
|
|
d1681e |
+ shard_get_timestamps_from_inode_ctx (local, base_inode, this);
|
|
|
d1681e |
+ SHARD_STACK_UNWIND (fsync, frame, local->op_ret,
|
|
|
d1681e |
+ local->op_errno, &local->prebuf,
|
|
|
d1681e |
+ &local->postbuf, local->xattr_rsp);
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ return 0;
|
|
|
d1681e |
+}
|
|
|
d1681e |
+
|
|
|
d1681e |
+int
|
|
|
d1681e |
+shard_post_lookup_fsync_handler (call_frame_t *frame, xlator_t *this)
|
|
|
d1681e |
+{
|
|
|
d1681e |
+ int ret = 0;
|
|
|
d1681e |
+ int call_count = 0;
|
|
|
d1681e |
+ int fsync_count = 0;
|
|
|
d1681e |
+ fd_t *anon_fd = NULL;
|
|
|
d1681e |
+ inode_t *base_inode = NULL;
|
|
|
d1681e |
+ shard_local_t *local = NULL;
|
|
|
d1681e |
+ shard_inode_ctx_t *ctx = NULL;
|
|
|
d1681e |
+ shard_inode_ctx_t *iter = NULL;
|
|
|
d1681e |
+ struct list_head copy = {0,};
|
|
|
d1681e |
+ shard_inode_ctx_t *tmp = NULL;
|
|
|
d1681e |
+
|
|
|
d1681e |
+ local = frame->local;
|
|
|
d1681e |
+ base_inode = local->fd->inode;
|
|
|
d1681e |
+ local->postbuf = local->prebuf;
|
|
|
d1681e |
+ INIT_LIST_HEAD (©);
|
|
|
d1681e |
+
|
|
|
d1681e |
+ if (local->op_ret < 0) {
|
|
|
d1681e |
+ SHARD_STACK_UNWIND (fsync, frame, local->op_ret,
|
|
|
d1681e |
+ local->op_errno, NULL, NULL, NULL);
|
|
|
d1681e |
+ return 0;
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+
|
|
|
d1681e |
+ LOCK (&base_inode->lock);
|
|
|
d1681e |
+ {
|
|
|
d1681e |
+ __shard_inode_ctx_get (base_inode, this, &ctx;;
|
|
|
d1681e |
+ list_splice_init (&ctx->to_fsync_list, ©);
|
|
|
d1681e |
+ call_count = ctx->fsync_count;
|
|
|
d1681e |
+ ctx->fsync_count = 0;
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ UNLOCK (&base_inode->lock);
|
|
|
d1681e |
+
|
|
|
d1681e |
+ local->call_count = ++call_count;
|
|
|
d1681e |
+
|
|
|
d1681e |
+ /* Send fsync() on the base shard first */
|
|
|
d1681e |
+ anon_fd = fd_ref (local->fd);
|
|
|
d1681e |
+ STACK_WIND_COOKIE (frame, shard_fsync_shards_cbk, anon_fd,
|
|
|
d1681e |
+ FIRST_CHILD(this),
|
|
|
d1681e |
+ FIRST_CHILD(this)->fops->fsync, anon_fd,
|
|
|
d1681e |
+ local->datasync, local->xattr_req);
|
|
|
d1681e |
+ call_count--;
|
|
|
d1681e |
+ anon_fd = NULL;
|
|
|
d1681e |
+
|
|
|
d1681e |
+ list_for_each_entry_safe (iter, tmp, ©, to_fsync_list) {
|
|
|
d1681e |
+ fsync_count = 0;
|
|
|
d1681e |
+ shard_inode_ctx_get_fsync_count (iter->inode, this,
|
|
|
d1681e |
+ &fsync_count);
|
|
|
d1681e |
+ GF_ASSERT (fsync_count > 0);
|
|
|
d1681e |
+ anon_fd = fd_anonymous (iter->inode);
|
|
|
d1681e |
+ if (!anon_fd) {
|
|
|
d1681e |
+ local->op_ret = -1;
|
|
|
d1681e |
+ local->op_errno = ENOMEM;
|
|
|
d1681e |
+ gf_msg (this->name, GF_LOG_WARNING, ENOMEM,
|
|
|
d1681e |
+ SHARD_MSG_MEMALLOC_FAILED, "Failed to create "
|
|
|
d1681e |
+ "anon fd to fsync shard");
|
|
|
d1681e |
+ shard_fsync_shards_cbk (frame, (void *) (long) anon_fd,
|
|
|
d1681e |
+ this, -1, ENOMEM, NULL, NULL,
|
|
|
d1681e |
+ NULL);
|
|
|
d1681e |
+ continue;
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+
|
|
|
d1681e |
+ ret = fd_ctx_set (anon_fd, this, fsync_count);
|
|
|
d1681e |
+ if (ret) {
|
|
|
d1681e |
+ gf_msg (this->name, GF_LOG_ERROR, 0,
|
|
|
d1681e |
+ SHARD_MSG_FD_CTX_SET_FAILED, "Failed to set fd "
|
|
|
d1681e |
+ "ctx for shard inode gfid=%s",
|
|
|
d1681e |
+ uuid_utoa (iter->inode->gfid));
|
|
|
d1681e |
+ local->op_ret = -1;
|
|
|
d1681e |
+ local->op_errno = ENOMEM;
|
|
|
d1681e |
+ shard_fsync_shards_cbk (frame, (void *) (long) anon_fd,
|
|
|
d1681e |
+ this, -1, ENOMEM, NULL, NULL,
|
|
|
d1681e |
+ NULL);
|
|
|
d1681e |
+ continue;
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ STACK_WIND_COOKIE (frame, shard_fsync_shards_cbk, anon_fd,
|
|
|
d1681e |
+ FIRST_CHILD(this),
|
|
|
d1681e |
+ FIRST_CHILD(this)->fops->fsync, anon_fd,
|
|
|
d1681e |
+ local->datasync, local->xattr_req);
|
|
|
d1681e |
+ call_count--;
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+
|
|
|
d1681e |
return 0;
|
|
|
d1681e |
}
|
|
|
d1681e |
|
|
|
d1681e |
@@ -4223,8 +4640,50 @@ int
|
|
|
d1681e |
shard_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t datasync,
|
|
|
d1681e |
dict_t *xdata)
|
|
|
d1681e |
{
|
|
|
d1681e |
- STACK_WIND (frame, shard_fsync_cbk, FIRST_CHILD(this),
|
|
|
d1681e |
- FIRST_CHILD(this)->fops->fsync, fd, datasync, xdata);
|
|
|
d1681e |
+ int ret = 0;
|
|
|
d1681e |
+ uint64_t block_size = 0;
|
|
|
d1681e |
+ shard_local_t *local = NULL;
|
|
|
d1681e |
+
|
|
|
d1681e |
+ ret = shard_inode_ctx_get_block_size (fd->inode, this, &block_size);
|
|
|
d1681e |
+ if (ret) {
|
|
|
d1681e |
+ gf_msg (this->name, GF_LOG_ERROR, 0,
|
|
|
d1681e |
+ SHARD_MSG_INODE_CTX_GET_FAILED, "Failed to get block "
|
|
|
d1681e |
+ "size for %s from its inode ctx",
|
|
|
d1681e |
+ uuid_utoa (fd->inode->gfid));
|
|
|
d1681e |
+ goto err;
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+
|
|
|
d1681e |
+ if (!block_size || frame->root->pid == GF_CLIENT_PID_GSYNCD) {
|
|
|
d1681e |
+ STACK_WIND (frame, default_fsync_cbk, FIRST_CHILD(this),
|
|
|
d1681e |
+ FIRST_CHILD(this)->fops->fsync, fd, datasync,
|
|
|
d1681e |
+ xdata);
|
|
|
d1681e |
+ return 0;
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+
|
|
|
d1681e |
+ if (!this->itable)
|
|
|
d1681e |
+ this->itable = fd->inode->table;
|
|
|
d1681e |
+
|
|
|
d1681e |
+ local = mem_get0 (this->local_pool);
|
|
|
d1681e |
+ if (!local)
|
|
|
d1681e |
+ goto err;
|
|
|
d1681e |
+
|
|
|
d1681e |
+ frame->local = local;
|
|
|
d1681e |
+
|
|
|
d1681e |
+ local->fd = fd_ref (fd);
|
|
|
d1681e |
+ local->fop = GF_FOP_FSYNC;
|
|
|
d1681e |
+ local->datasync = datasync;
|
|
|
d1681e |
+ local->xattr_req = (xdata) ? dict_ref (xdata) : dict_new ();
|
|
|
d1681e |
+ if (!local->xattr_req)
|
|
|
d1681e |
+ goto err;
|
|
|
d1681e |
+
|
|
|
d1681e |
+ local->loc.inode = inode_ref (fd->inode);
|
|
|
d1681e |
+ gf_uuid_copy (local->loc.gfid, fd->inode->gfid);
|
|
|
d1681e |
+
|
|
|
d1681e |
+ shard_lookup_base_file (frame, this, &local->loc,
|
|
|
d1681e |
+ shard_post_lookup_fsync_handler);
|
|
|
d1681e |
+ return 0;
|
|
|
d1681e |
+err:
|
|
|
d1681e |
+ SHARD_STACK_UNWIND (fsync, frame, -1, ENOMEM, NULL, NULL, NULL);
|
|
|
d1681e |
return 0;
|
|
|
d1681e |
}
|
|
|
d1681e |
|
|
|
d1681e |
diff --git a/xlators/features/shard/src/shard.h b/xlators/features/shard/src/shard.h
|
|
|
d1681e |
index 7319598..75d39a1 100644
|
|
|
d1681e |
--- a/xlators/features/shard/src/shard.h
|
|
|
d1681e |
+++ b/xlators/features/shard/src/shard.h
|
|
|
d1681e |
@@ -215,6 +215,7 @@ typedef struct shard_local {
|
|
|
d1681e |
uint32_t gid;
|
|
|
d1681e |
uint64_t block_size;
|
|
|
d1681e |
uint64_t dst_block_size;
|
|
|
d1681e |
+ int32_t datasync;
|
|
|
d1681e |
off_t offset;
|
|
|
d1681e |
size_t total_size;
|
|
|
d1681e |
size_t written_size;
|
|
|
d1681e |
@@ -270,6 +271,11 @@ typedef struct shard_inode_ctx {
|
|
|
d1681e |
uuid_t base_gfid;
|
|
|
d1681e |
int block_num;
|
|
|
d1681e |
gf_boolean_t refreshed;
|
|
|
d1681e |
+ struct list_head to_fsync_list;
|
|
|
d1681e |
+ int fsync_needed;
|
|
|
d1681e |
+ inode_t *inode;
|
|
|
d1681e |
+ int fsync_count;
|
|
|
d1681e |
+ inode_t *base_inode;
|
|
|
d1681e |
} shard_inode_ctx_t;
|
|
|
d1681e |
|
|
|
d1681e |
#endif /* __SHARD_H__ */
|
|
|
d1681e |
--
|
|
|
d1681e |
1.8.3.1
|
|
|
d1681e |
|