From d2a6bc99624528a04e4342a34cfe5a31dd706d56 Mon Sep 17 00:00:00 2001 From: Ashish Pandey Date: Thu, 9 Apr 2015 17:27:46 +0530 Subject: cluster/ec: Use fd instead of loc for get_size_version Change-Id: Ia7d43cb3b222db34ecb0e35424f1766715ed8e6a BUG: 1219358 Signed-off-by: Ashish Pandey Reviewed-on: http://review.gluster.org/10176 Reviewed-on: http://review.gluster.org/10625 Tested-by: Gluster Build System Reviewed-by: Pranith Kumar Karampuri --- xlators/cluster/ec/src/ec-common.c | 108 +++++++++++++++++---------------- xlators/cluster/ec/src/ec-generic.c | 4 +- xlators/cluster/ec/src/ec-inode-read.c | 8 +-- 3 files changed, 63 insertions(+), 57 deletions(-) diff --git a/xlators/cluster/ec/src/ec-common.c b/xlators/cluster/ec/src/ec-common.c index a4bd8dafe28..897dbe830ab 100644 --- a/xlators/cluster/ec/src/ec-common.c +++ b/xlators/cluster/ec/src/ec-common.c @@ -1083,6 +1083,8 @@ ec_prepare_update_cbk (call_frame_t *frame, void *cookie, { ec_fop_data_t *fop = cookie, *parent; ec_lock_t *lock = NULL; + uint64_t size = 0; + uint64_t version = 0; if (op_ret >= 0) { parent = fop->parent; @@ -1094,24 +1096,29 @@ ec_prepare_update_cbk (call_frame_t *frame, void *cookie, } lock = parent->locks[0].lock; - lock->is_dirty = _gf_true; + lock->is_dirty = _gf_true; - if (!ec_config_check(fop, dict)) { - return 0; + if (lock->loc.inode->ia_type == IA_IFREG) { + if (!ec_config_check(fop, dict) || + (ec_dict_del_number(dict, EC_XATTR_SIZE, &size) != 0)) { + ec_fop_set_error(fop, EIO); + return 0; + } } - LOCK(&lock->loc.inode->lock); - - if ((ec_dict_del_number(dict, EC_XATTR_VERSION, &lock->version) != 0) || - (ec_dict_del_number(dict, EC_XATTR_SIZE, &lock->size) != 0)) { - UNLOCK(&lock->loc.inode->lock); + if (ec_dict_del_number(dict, EC_XATTR_VERSION, &version) != 0) { + ec_fop_set_error(fop, EIO); + return 0; + } - ec_fop_set_error(fop, EIO); + LOCK(&lock->loc.inode->lock); - return 0; + if (lock->loc.inode->ia_type == IA_IFREG) { + lock->size = size; + fop->parent->pre_size = fop->parent->post_size = size; + fop->parent->have_size = lock->have_size = 1; } - - lock->have_size = 1; + lock->version = version; UNLOCK(&lock->loc.inode->lock); @@ -1119,9 +1126,6 @@ ec_prepare_update_cbk (call_frame_t *frame, void *cookie, /*As of now only data healing marks bricks as healing*/ if (ec_is_data_fop (fop->parent->id)) fop->parent->healing |= fop->healing; - - fop->parent->pre_size = fop->parent->post_size = lock->size; - fop->parent->have_size = 1; } else { gf_log(this->name, GF_LOG_WARNING, "Failed to get size and version (error %d: %s)", op_errno, @@ -1154,6 +1158,11 @@ void ec_get_size_version(ec_fop_data_t * fop) return; } + uid = fop->frame->root->uid; + gid = fop->frame->root->gid; + + fop->frame->root->uid = 0; + fop->frame->root->gid = 0; memset(&loc, 0, sizeof(loc)); @@ -1162,20 +1171,14 @@ void ec_get_size_version(ec_fop_data_t * fop) { goto out; } - if ((dict_set_uint64(xdata, EC_XATTR_VERSION, 0) != 0) || - (dict_set_uint64(xdata, EC_XATTR_SIZE, 0) != 0) || - (dict_set_uint64(xdata, EC_XATTR_CONFIG, 0) != 0) || - (dict_set_uint64(xdata, EC_XATTR_DIRTY, 0) != 0)) + if ((ec_dict_set_number(xdata, EC_XATTR_VERSION, 0) != 0) || + (ec_dict_set_number(xdata, EC_XATTR_SIZE, 0) != 0) || + (ec_dict_set_number(xdata, EC_XATTR_CONFIG, 0) != 0) || + (ec_dict_set_number(xdata, EC_XATTR_DIRTY, 0) != 0)) { goto out; } - uid = fop->frame->root->uid; - gid = fop->frame->root->gid; - - fop->frame->root->uid = 0; - fop->frame->root->gid = 0; - error = EIO; if (!fop->use_fd) @@ -1192,28 +1195,31 @@ void ec_get_size_version(ec_fop_data_t * fop) loc.parent = NULL; } GF_FREE((char *)loc.path); - loc.path = NULL; - loc.name = NULL; + loc.path = NULL; + loc.name = NULL; } - } else if (ec_loc_from_fd(fop->xl, &loc, fop->fd) != 0) { - goto out; + /* For normal fops, ec_lookup() must succeed on at least EC_MINIMUM_MIN + * bricks, however when this is called as part of a self-heal operation + * the mask of target bricks (fop->mask) could contain less than + * EC_MINIMUM_MIN bricks, causing the lookup to always fail. Thus we + * always use the same minimum used for the main fop. + */ + ec_lookup(fop->frame, fop->xl, fop->mask, fop->minimum, + ec_get_size_version_set, NULL, &loc, xdata); + } else { + if (ec_loc_from_fd(fop->xl, &loc, fop->fd) != 0) { + goto out; + } + ec_fxattrop(fop->frame, fop->xl, fop->mask, fop->minimum, + ec_prepare_update_cbk, NULL, fop->fd, + GF_XATTROP_ADD_ARRAY64, xdata, NULL); } + error = 0; - /* For normal fops, ec_lookup() must succeed on at least EC_MINIMUM_MIN - * bricks, however when this is called as part of a self-heal operation - * the mask of target bricks (fop->mask) could contain less than - * EC_MINIMUM_MIN bricks, causing the lookup to always fail. Thus we - * always use the same minimum used for the main fop. - */ - ec_lookup(fop->frame, fop->xl, fop->mask, fop->minimum, - ec_get_size_version_set, NULL, &loc, xdata); - +out: fop->frame->root->uid = uid; fop->frame->root->gid = gid; - error = 0; - -out: loc_wipe(&loc); if (xdata != NULL) @@ -1248,6 +1254,11 @@ void ec_prepare_update(ec_fop_data_t *fop) return; } + uid = fop->frame->root->uid; + gid = fop->frame->root->gid; + + fop->frame->root->uid = 0; + fop->frame->root->gid = 0; memset(&loc, 0, sizeof(loc)); @@ -1259,15 +1270,9 @@ void ec_prepare_update(ec_fop_data_t *fop) (ec_dict_set_number(xdata, EC_XATTR_SIZE, 0) != 0) || (ec_dict_set_number(xdata, EC_XATTR_CONFIG, 0) != 0) || (ec_dict_set_number(xdata, EC_XATTR_DIRTY, 1) != 0)) { - goto out; + goto out; } - uid = fop->frame->root->uid; - gid = fop->frame->root->gid; - - fop->frame->root->uid = 0; - fop->frame->root->gid = 0; - error = EIO; if (!fop->use_fd) { @@ -1284,12 +1289,13 @@ void ec_prepare_update(ec_fop_data_t *fop) GF_XATTROP_ADD_ARRAY64, xdata, NULL); } - fop->frame->root->uid = uid; - fop->frame->root->gid = gid; - error = 0; out: + + fop->frame->root->uid = uid; + fop->frame->root->gid = gid; + loc_wipe(&loc); if (xdata != NULL) { diff --git a/xlators/cluster/ec/src/ec-generic.c b/xlators/cluster/ec/src/ec-generic.c index c22fb0a950f..fdab9ec2ae9 100644 --- a/xlators/cluster/ec/src/ec-generic.c +++ b/xlators/cluster/ec/src/ec-generic.c @@ -327,9 +327,9 @@ int32_t ec_manager_fsync(ec_fop_data_t * fop, int32_t state) return EC_STATE_GET_SIZE_AND_VERSION; case EC_STATE_GET_SIZE_AND_VERSION: - ec_get_size_version(fop); + ec_get_size_version(fop); - return EC_STATE_DISPATCH; + return EC_STATE_DISPATCH; case EC_STATE_DISPATCH: ec_flush_size_version(fop); diff --git a/xlators/cluster/ec/src/ec-inode-read.c b/xlators/cluster/ec/src/ec-inode-read.c index d126d48eb12..365ea3db0ec 100644 --- a/xlators/cluster/ec/src/ec-inode-read.c +++ b/xlators/cluster/ec/src/ec-inode-read.c @@ -1321,9 +1321,9 @@ int32_t ec_manager_readv(ec_fop_data_t * fop, int32_t state) return EC_STATE_GET_SIZE_AND_VERSION; case EC_STATE_GET_SIZE_AND_VERSION: - ec_get_size_version(fop); + ec_get_size_version(fop); - return EC_STATE_DISPATCH; + return EC_STATE_DISPATCH; case EC_STATE_DISPATCH: ec_dispatch_min(fop); @@ -1577,9 +1577,9 @@ int32_t ec_manager_stat(ec_fop_data_t * fop, int32_t state) return EC_STATE_GET_SIZE_AND_VERSION; case EC_STATE_GET_SIZE_AND_VERSION: - ec_get_size_version(fop); + ec_get_size_version(fop); - return EC_STATE_DISPATCH; + return EC_STATE_DISPATCH; case EC_STATE_DISPATCH: ec_dispatch_all(fop); -- cgit