diff options
Diffstat (limited to 'xlators/cluster/ec/src/ec-heal.c')
-rw-r--r-- | xlators/cluster/ec/src/ec-heal.c | 103 |
1 files changed, 52 insertions, 51 deletions
diff --git a/xlators/cluster/ec/src/ec-heal.c b/xlators/cluster/ec/src/ec-heal.c index ceddfeb6ac7..80725e5a9fa 100644 --- a/xlators/cluster/ec/src/ec-heal.c +++ b/xlators/cluster/ec/src/ec-heal.c @@ -119,9 +119,8 @@ void ec_heal_lookup_resume(ec_fop_data_t * fop) heal->version[0] = cbk->version[0]; heal->version[1] = cbk->version[1]; heal->raw_size = cbk->size; - heal->fop->pre_size = cbk->iatt[0].ia_size; - heal->fop->post_size = cbk->iatt[0].ia_size; - heal->fop->have_size = 1; + + GF_ASSERT(ec_set_inode_size(fop, cbk->inode, cbk->size)); if (ec_loc_update(heal->xl, &heal->loc, cbk->inode, &cbk->iatt[0]) != 0) @@ -532,12 +531,7 @@ ec_heal_init (ec_fop_data_t * fop) gf_log("ec", GF_LOG_INFO, "Healing '%s', gfid %s", heal->loc.path, uuid_utoa(heal->loc.gfid)); } else { - LOCK(&fop->lock); - - fop->jobs++; - fop->refs++; - - UNLOCK(&fop->lock); + ec_sleep(fop); } list_add_tail(&heal->list, &ctx->heal); @@ -552,25 +546,8 @@ out: return error; } -void ec_heal_entrylk(ec_heal_t * heal, entrylk_cmd cmd) -{ - loc_t loc; - - if (ec_loc_parent(heal->xl, &heal->loc, &loc) != 0) { - gf_log("ec", GF_LOG_NOTICE, "ec_loc_parent() failed"); - ec_fop_set_error(heal->fop, EIO); - - return; - } - - ec_entrylk(heal->fop->frame, heal->xl, -1, EC_MINIMUM_ALL, NULL, NULL, - heal->xl->name, &loc, NULL, cmd, ENTRYLK_WRLCK, NULL); - - loc_wipe(&loc); -} - -void ec_heal_inodelk(ec_heal_t * heal, int32_t type, int32_t use_fd, - off_t offset, size_t size) +void ec_heal_lock(ec_heal_t *heal, int32_t type, fd_t *fd, loc_t *loc, + off_t offset, size_t size) { struct gf_flock flock; @@ -581,20 +558,47 @@ void ec_heal_inodelk(ec_heal_t * heal, int32_t type, int32_t use_fd, flock.l_pid = 0; flock.l_owner.len = 0; - if (use_fd) + /* Remove inode size information before unlocking it. */ + if ((type == F_UNLCK) && (heal->loc.inode != NULL)) { + ec_clear_inode_info(heal->fop, heal->loc.inode); + } + + if (fd != NULL) { ec_finodelk(heal->fop->frame, heal->xl, heal->fop->mask, - EC_MINIMUM_ALL, NULL, NULL, heal->xl->name, heal->fd, + EC_MINIMUM_ALL, NULL, NULL, heal->xl->name, fd, F_SETLKW, &flock, NULL); } else { ec_inodelk(heal->fop->frame, heal->xl, heal->fop->mask, EC_MINIMUM_ALL, - NULL, NULL, heal->xl->name, &heal->loc, F_SETLKW, &flock, + NULL, NULL, heal->xl->name, loc, F_SETLKW, &flock, NULL); } } +void ec_heal_entrylk(ec_heal_t *heal, int32_t type) +{ + loc_t loc; + + if (ec_loc_parent(heal->xl, &heal->loc, &loc) != 0) { + ec_fop_set_error(heal->fop, EIO); + + return; + } + + ec_heal_lock(heal, type, NULL, &loc, 0, 0); + + loc_wipe(&loc); +} + +void ec_heal_inodelk(ec_heal_t *heal, int32_t type, int32_t use_fd, + off_t offset, size_t size) +{ + ec_heal_lock(heal, type, use_fd ? heal->fd : NULL, &heal->loc, offset, + size); +} + void ec_heal_lookup(ec_heal_t *heal, uintptr_t mask) { dict_t * xdata; @@ -1302,13 +1306,10 @@ ec_manager_heal (ec_fop_data_t * fop, int32_t state) case EC_STATE_DISPATCH: if (heal->done != 0) { - gf_log("ec", GF_LOG_NOTICE, "heal already done"); return EC_STATE_HEAL_DISPATCH; } - gf_log("ec", GF_LOG_NOTICE, "heal before entrylk"); - ec_heal_entrylk(heal, ENTRYLK_LOCK); - gf_log("ec", GF_LOG_NOTICE, "heal after entrylk"); + ec_heal_entrylk(heal, F_WRLCK); return EC_STATE_HEAL_ENTRY_LOOKUP; @@ -1336,7 +1337,7 @@ ec_manager_heal (ec_fop_data_t * fop, int32_t state) /* Only heal data/metadata if enough information is supplied. */ if (gf_uuid_is_null(heal->loc.gfid)) { - ec_heal_entrylk(heal, ENTRYLK_UNLOCK); + ec_heal_entrylk(heal, F_UNLCK); return EC_STATE_HEAL_DISPATCH; } @@ -1392,7 +1393,7 @@ ec_manager_heal (ec_fop_data_t * fop, int32_t state) case -EC_STATE_HEAL_UNLOCK_ENTRY: case EC_STATE_HEAL_UNLOCK_ENTRY: if (heal->nameheal) - ec_heal_entrylk(heal, ENTRYLK_UNLOCK); + ec_heal_entrylk(heal, F_UNLCK); heal->bad = ec_heal_needs_data_rebuild(heal); if (heal->bad != 0) @@ -2562,9 +2563,9 @@ ec_heal_name (call_frame_t *frame, ec_t *ec, inode_t *parent, char *name, EC_REPLIES_ALLOC (replies, ec->nodes); output = alloca0 (ec->nodes); locked_on = alloca0 (ec->nodes); - ret = cluster_entrylk (ec->xl_list, participants, ec->nodes, replies, + ret = cluster_inodelk (ec->xl_list, participants, ec->nodes, replies, locked_on, frame, ec->xl, ec->xl->name, parent, - NULL); + 0, 0); { if (ret <= ec->fragments) { gf_log (ec->xl->name, GF_LOG_DEBUG, "%s/%s: Skipping " @@ -2578,8 +2579,8 @@ ec_heal_name (call_frame_t *frame, ec_t *ec, inode_t *parent, char *name, ret = __ec_heal_name (frame, ec, parent, name, participants); } unlock: - cluster_unentrylk (ec->xl_list, locked_on, ec->nodes, replies, output, - frame, ec->xl, ec->xl->name, parent, NULL); + cluster_uninodelk (ec->xl_list, locked_on, ec->nodes, replies, output, + frame, ec->xl, ec->xl->name, parent, 0, 0); out: cluster_replies_wipe (replies, ec->nodes); loc_wipe (&loc); @@ -2663,9 +2664,9 @@ __ec_heal_entry (call_frame_t *frame, ec_t *ec, inode_t *inode, dirty = alloca0 (ec->nodes * sizeof (*dirty)); EC_REPLIES_ALLOC (replies, ec->nodes); - ret = cluster_entrylk (ec->xl_list, heal_on, ec->nodes, replies, + ret = cluster_inodelk (ec->xl_list, heal_on, ec->nodes, replies, locked_on, frame, ec->xl, ec->xl->name, inode, - NULL); + 0, 0); { if (ret <= ec->fragments) { gf_log (ec->xl->name, GF_LOG_DEBUG, "%s: Skipping heal " @@ -2680,8 +2681,8 @@ __ec_heal_entry (call_frame_t *frame, ec_t *ec, inode_t *inode, source = ret; } unlock: - cluster_unentrylk (ec->xl_list, locked_on, ec->nodes, replies, output, - frame, ec->xl, ec->xl->name, inode, NULL); + cluster_uninodelk (ec->xl_list, locked_on, ec->nodes, replies, output, + frame, ec->xl, ec->xl->name, inode, 0, 0); if (ret < 0) goto out; @@ -2728,9 +2729,9 @@ ec_heal_entry (call_frame_t *frame, ec_t *ec, inode_t *inode, sprintf (selfheal_domain, "%s:self-heal", ec->xl->name); ec_mask_to_char_array (ec->xl_up, up_subvols, ec->nodes); /*If other processes are already doing the heal, don't block*/ - ret = cluster_entrylk (ec->xl_list, up_subvols, ec->nodes, replies, + ret = cluster_inodelk (ec->xl_list, up_subvols, ec->nodes, replies, locked_on, frame, ec->xl, selfheal_domain, inode, - NULL); + 0, 0); { if (ret <= ec->fragments) { gf_log (ec->xl->name, GF_LOG_DEBUG, "%s: Skipping heal " @@ -2743,8 +2744,8 @@ ec_heal_entry (call_frame_t *frame, ec_t *ec, inode_t *inode, sources, healed_sinks); } unlock: - cluster_unentrylk (ec->xl_list, locked_on, ec->nodes, replies, output, - frame, ec->xl, selfheal_domain, inode, NULL); + cluster_uninodelk (ec->xl_list, locked_on, ec->nodes, replies, output, + frame, ec->xl, selfheal_domain, inode, 0, 0); cluster_replies_wipe (replies, ec->nodes); return ret; } @@ -3086,8 +3087,8 @@ ec_heal_block (call_frame_t *frame, xlator_t *this, uintptr_t target, if (fop == NULL) goto out; - fop->pre_size = fop->post_size = heal->total_size; - fop->have_size = 1; + GF_ASSERT(ec_set_inode_size(fop, heal->fd->inode, heal->total_size)); + error = 0; out: |