From d97863562bb0d2f685df3d2e3aa4bef1299c8307 Mon Sep 17 00:00:00 2001 From: Xavier Hernandez Date: Mon, 14 Jul 2014 17:34:04 +0200 Subject: ec: Optimize read/write performance This patch significantly improves performance of read/write operations on a dispersed volume by reusing previous inodelk/ entrylk operations on the same inode/entry. This reduces the latency of each individual operation considerably. Inode version and size are also updated when needed instead of on each request. This gives an additional boost. Change-Id: I4b98d5508c86b53032e16e295f72a3f83fd8fcac BUG: 1122586 Signed-off-by: Xavier Hernandez Reviewed-on: http://review.gluster.org/8369 Tested-by: Gluster Build System Reviewed-by: Jeff Darcy Reviewed-by: Dan Lambright --- xlators/cluster/ec/src/ec-dir-write.c | 96 ++++++++++++++++++++++++++--------- 1 file changed, 71 insertions(+), 25 deletions(-) (limited to 'xlators/cluster/ec/src/ec-dir-write.c') diff --git a/xlators/cluster/ec/src/ec-dir-write.c b/xlators/cluster/ec/src/ec-dir-write.c index dc1d94e37e8..a28b7ad1937 100644 --- a/xlators/cluster/ec/src/ec-dir-write.c +++ b/xlators/cluster/ec/src/ec-dir-write.c @@ -181,7 +181,8 @@ int32_t ec_manager_create(ec_fop_data_t * fop, int32_t state) /* Fall through */ case EC_STATE_LOCK: - ec_lock_entry(fop, &fop->loc[0]); + ec_lock_prepare_entry(fop, &fop->loc[0]); + ec_lock(fop); return EC_STATE_DISPATCH; @@ -245,11 +246,7 @@ int32_t ec_manager_create(ec_fop_data_t * fop, int32_t state) cbk->xdata); } - if (cbk->op_ret >= 0) - { - return EC_STATE_UPDATE_SIZE_AND_VERSION; - } - return EC_STATE_UNLOCK; + return EC_STATE_LOCK_REUSE; case -EC_STATE_LOCK: case -EC_STATE_DISPATCH: @@ -263,14 +260,14 @@ int32_t ec_manager_create(ec_fop_data_t * fop, int32_t state) NULL, NULL, NULL, NULL, NULL, NULL); } - return EC_STATE_UNLOCK; + return EC_STATE_LOCK_REUSE; - case EC_STATE_UPDATE_SIZE_AND_VERSION: - ec_update_size_version(fop); + case -EC_STATE_LOCK_REUSE: + case EC_STATE_LOCK_REUSE: + ec_lock_reuse(fop, 1); return EC_STATE_UNLOCK; - case -EC_STATE_UPDATE_SIZE_AND_VERSION: case -EC_STATE_UNLOCK: case EC_STATE_UNLOCK: ec_unlock(fop); @@ -468,7 +465,8 @@ int32_t ec_manager_link(ec_fop_data_t * fop, int32_t state) // Parent entry of fop->loc[0] should be locked, but I don't // receive enough information to do it (fop->loc[0].parent is // NULL). - ec_lock_entry(fop, &fop->loc[1]); + ec_lock_prepare_entry(fop, &fop->loc[1]); + ec_lock(fop); return EC_STATE_GET_SIZE_AND_VERSION; @@ -531,7 +529,7 @@ int32_t ec_manager_link(ec_fop_data_t * fop, int32_t state) &cbk->iatt[1], &cbk->iatt[2], cbk->xdata); } - return EC_STATE_UNLOCK; + return EC_STATE_LOCK_REUSE; case -EC_STATE_LOCK: case -EC_STATE_GET_SIZE_AND_VERSION: @@ -546,6 +544,12 @@ int32_t ec_manager_link(ec_fop_data_t * fop, int32_t state) NULL, NULL, NULL, NULL, NULL); } + return EC_STATE_LOCK_REUSE; + + case -EC_STATE_LOCK_REUSE: + case EC_STATE_LOCK_REUSE: + ec_lock_reuse(fop, 0); + return EC_STATE_UNLOCK; case -EC_STATE_UNLOCK: @@ -732,7 +736,8 @@ int32_t ec_manager_mkdir(ec_fop_data_t * fop, int32_t state) { case EC_STATE_INIT: case EC_STATE_LOCK: - ec_lock_entry(fop, &fop->loc[0]); + ec_lock_prepare_entry(fop, &fop->loc[0]); + ec_lock(fop); return EC_STATE_DISPATCH; @@ -785,7 +790,7 @@ int32_t ec_manager_mkdir(ec_fop_data_t * fop, int32_t state) &cbk->iatt[1], &cbk->iatt[2], cbk->xdata); } - return EC_STATE_UNLOCK; + return EC_STATE_LOCK_REUSE; case -EC_STATE_LOCK: case -EC_STATE_DISPATCH: @@ -799,6 +804,12 @@ int32_t ec_manager_mkdir(ec_fop_data_t * fop, int32_t state) NULL, NULL, NULL, NULL, NULL); } + return EC_STATE_LOCK_REUSE; + + case -EC_STATE_LOCK_REUSE: + case EC_STATE_LOCK_REUSE: + ec_lock_reuse(fop, 0); + return EC_STATE_UNLOCK; case -EC_STATE_UNLOCK: @@ -982,7 +993,8 @@ int32_t ec_manager_mknod(ec_fop_data_t * fop, int32_t state) { case EC_STATE_INIT: case EC_STATE_LOCK: - ec_lock_entry(fop, &fop->loc[0]); + ec_lock_prepare_entry(fop, &fop->loc[0]); + ec_lock(fop); return EC_STATE_DISPATCH; @@ -1035,7 +1047,7 @@ int32_t ec_manager_mknod(ec_fop_data_t * fop, int32_t state) &cbk->iatt[1], &cbk->iatt[2], cbk->xdata); } - return EC_STATE_UNLOCK; + return EC_STATE_LOCK_REUSE; case -EC_STATE_LOCK: case -EC_STATE_DISPATCH: @@ -1049,6 +1061,12 @@ int32_t ec_manager_mknod(ec_fop_data_t * fop, int32_t state) NULL, NULL, NULL, NULL, NULL); } + return EC_STATE_LOCK_REUSE; + + case -EC_STATE_LOCK_REUSE: + case EC_STATE_LOCK_REUSE: + ec_lock_reuse(fop, 0); + return EC_STATE_UNLOCK; case -EC_STATE_UNLOCK: @@ -1230,8 +1248,9 @@ int32_t ec_manager_rename(ec_fop_data_t * fop, int32_t state) { case EC_STATE_INIT: case EC_STATE_LOCK: - ec_lock_entry(fop, &fop->loc[0]); - ec_lock_entry(fop, &fop->loc[1]); + ec_lock_prepare_entry(fop, &fop->loc[0]); + ec_lock_prepare_entry(fop, &fop->loc[1]); + ec_lock(fop); return EC_STATE_GET_SIZE_AND_VERSION; @@ -1292,7 +1311,7 @@ int32_t ec_manager_rename(ec_fop_data_t * fop, int32_t state) cbk->xdata); } - return EC_STATE_UNLOCK; + return EC_STATE_LOCK_REUSE; case -EC_STATE_LOCK: case -EC_STATE_GET_SIZE_AND_VERSION: @@ -1307,6 +1326,12 @@ int32_t ec_manager_rename(ec_fop_data_t * fop, int32_t state) NULL, NULL, NULL, NULL, NULL, NULL); } + return EC_STATE_LOCK_REUSE; + + case -EC_STATE_LOCK_REUSE: + case EC_STATE_LOCK_REUSE: + ec_lock_reuse(fop, 0); + return EC_STATE_UNLOCK; case -EC_STATE_UNLOCK: @@ -1479,7 +1504,8 @@ int32_t ec_manager_rmdir(ec_fop_data_t * fop, int32_t state) { case EC_STATE_INIT: case EC_STATE_LOCK: - ec_lock_entry(fop, &fop->loc[0]); + ec_lock_prepare_entry(fop, &fop->loc[0]); + ec_lock(fop); return EC_STATE_DISPATCH; @@ -1524,7 +1550,7 @@ int32_t ec_manager_rmdir(ec_fop_data_t * fop, int32_t state) cbk->xdata); } - return EC_STATE_UNLOCK; + return EC_STATE_LOCK_REUSE; case -EC_STATE_LOCK: case -EC_STATE_DISPATCH: @@ -1538,6 +1564,12 @@ int32_t ec_manager_rmdir(ec_fop_data_t * fop, int32_t state) NULL, NULL, NULL); } + return EC_STATE_LOCK_REUSE; + + case -EC_STATE_LOCK_REUSE: + case EC_STATE_LOCK_REUSE: + ec_lock_reuse(fop, 0); + return EC_STATE_UNLOCK; case -EC_STATE_UNLOCK: @@ -1719,7 +1751,8 @@ int32_t ec_manager_symlink(ec_fop_data_t * fop, int32_t state) { case EC_STATE_INIT: case EC_STATE_LOCK: - ec_lock_entry(fop, &fop->loc[0]); + ec_lock_prepare_entry(fop, &fop->loc[0]); + ec_lock(fop); return EC_STATE_DISPATCH; @@ -1772,7 +1805,7 @@ int32_t ec_manager_symlink(ec_fop_data_t * fop, int32_t state) &cbk->iatt[1], &cbk->iatt[2], cbk->xdata); } - return EC_STATE_UNLOCK; + return EC_STATE_LOCK_REUSE; case -EC_STATE_LOCK: case -EC_STATE_DISPATCH: @@ -1786,6 +1819,12 @@ int32_t ec_manager_symlink(ec_fop_data_t * fop, int32_t state) NULL, NULL, NULL, NULL, NULL); } + return EC_STATE_LOCK_REUSE; + + case -EC_STATE_LOCK_REUSE: + case EC_STATE_LOCK_REUSE: + ec_lock_reuse(fop, 0); + return EC_STATE_UNLOCK; case -EC_STATE_UNLOCK: @@ -1963,7 +2002,8 @@ int32_t ec_manager_unlink(ec_fop_data_t * fop, int32_t state) { case EC_STATE_INIT: case EC_STATE_LOCK: - ec_lock_entry(fop, &fop->loc[0]); + ec_lock_prepare_entry(fop, &fop->loc[0]); + ec_lock(fop); return EC_STATE_GET_SIZE_AND_VERSION; @@ -2013,7 +2053,7 @@ int32_t ec_manager_unlink(ec_fop_data_t * fop, int32_t state) cbk->xdata); } - return EC_STATE_UNLOCK; + return EC_STATE_LOCK_REUSE; case -EC_STATE_LOCK: case -EC_STATE_GET_SIZE_AND_VERSION: @@ -2028,6 +2068,12 @@ int32_t ec_manager_unlink(ec_fop_data_t * fop, int32_t state) NULL, NULL, NULL); } + return EC_STATE_LOCK_REUSE; + + case -EC_STATE_LOCK_REUSE: + case EC_STATE_LOCK_REUSE: + ec_lock_reuse(fop, 0); + return EC_STATE_UNLOCK; case -EC_STATE_UNLOCK: -- cgit