diff options
Diffstat (limited to 'xlators/cluster/dht/src/tier-common.c')
-rw-r--r-- | xlators/cluster/dht/src/tier-common.c | 296 |
1 files changed, 296 insertions, 0 deletions
diff --git a/xlators/cluster/dht/src/tier-common.c b/xlators/cluster/dht/src/tier-common.c index 7d05c2973f2..19ed224c58c 100644 --- a/xlators/cluster/dht/src/tier-common.c +++ b/xlators/cluster/dht/src/tier-common.c @@ -17,6 +17,302 @@ #include "tier.h" int +tier_unlink_nonhashed_linkfile_cbk (call_frame_t *frame, void *cookie, + xlator_t *this, int op_ret, int op_errno, + struct iatt *preparent, + struct iatt *postparent, dict_t *xdata) +{ + dht_local_t *local = NULL; + call_frame_t *prev = NULL; + + local = frame->local; + prev = cookie; + + LOCK (&frame->lock); + { + if ((op_ret == -1) && (op_errno != ENOENT)) { + local->op_errno = op_errno; + local->op_ret = op_ret; + gf_msg_debug (this->name, op_errno, + "Unlink link: subvolume %s" + " returned -1", + prev->this->name); + goto unlock; + } + + local->op_ret = 0; + } +unlock: + UNLOCK (&frame->lock); + + if (local->op_ret == -1) + goto err; + DHT_STACK_UNWIND (unlink, frame, local->op_ret, local->op_errno, + &local->preparent, &local->postparent, NULL); + + + return 0; + +err: + DHT_STACK_UNWIND (unlink, frame, -1, local->op_errno, + NULL, NULL, NULL); + return 0; +} + +int +tier_unlink_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this, + int op_ret, int op_errno, inode_t *inode, + struct iatt *preparent, dict_t *xdata, + struct iatt *postparent) +{ + dht_local_t *local = NULL; + call_frame_t *prev = NULL; + dht_conf_t *conf = NULL; + xlator_t *hot_subvol = NULL; + + local = frame->local; + prev = cookie; + conf = this->private; + hot_subvol = TIER_UNHASHED_SUBVOL; + + if (!op_ret) { + /* + * linkfile present on hot tier. unlinking the linkfile + */ + STACK_WIND (frame, tier_unlink_nonhashed_linkfile_cbk, + hot_subvol, hot_subvol->fops->unlink, + &local->loc, local->flags, NULL); + return 0; + } + + LOCK (&frame->lock); + { + if (op_errno == ENOENT) { + local->op_ret = 0; + local->op_errno = op_errno; + } else { + local->op_ret = op_ret; + local->op_errno = op_errno; + } + gf_msg_debug (this->name, op_errno, + "Lookup : subvolume %s returned -1", + prev->this->name); + } + + UNLOCK (&frame->lock); + + DHT_STACK_UNWIND (unlink, frame, local->op_ret, local->op_errno, + &local->preparent, &local->postparent, xdata); + + return 0; +} + +int +tier_unlink_linkfile_cbk (call_frame_t *frame, void *cookie, xlator_t *this, + int op_ret, int op_errno, struct iatt *preparent, + struct iatt *postparent, dict_t *xdata) +{ + dht_local_t *local = NULL; + call_frame_t *prev = NULL; + + local = frame->local; + prev = cookie; + + LOCK (&frame->lock); + { + /* Ignore EINVAL for tier to ignore error when the file + does not exist on the other tier */ + if ((op_ret == -1) && !((op_errno == ENOENT) || + (op_errno == EINVAL))) { + local->op_errno = op_errno; + local->op_ret = op_ret; + gf_msg_debug (this->name, op_errno, + "Unlink link: subvolume %s" + " returned -1", + prev->this->name); + goto unlock; + } + + local->op_ret = 0; + } +unlock: + UNLOCK (&frame->lock); + + if (local->op_ret == -1) + goto err; + + DHT_STACK_UNWIND (unlink, frame, local->op_ret, local->op_errno, + &local->preparent, &local->postparent, xdata); + + return 0; + +err: + DHT_STACK_UNWIND (unlink, frame, -1, local->op_errno, + NULL, NULL, NULL); + return 0; +} + +int32_t +tier_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this, + int op_ret, int op_errno, struct iatt *preparent, + struct iatt *postparent, dict_t *xdata) +{ + dht_local_t *local = NULL; + call_frame_t *prev = NULL; + struct iatt *stbuf = NULL; + dht_conf_t *conf = NULL; + int ret = -1; + xlator_t *hot_tier = NULL; + xlator_t *cold_tier = NULL; + + local = frame->local; + prev = cookie; + conf = this->private; + + cold_tier = TIER_HASHED_SUBVOL; + hot_tier = TIER_UNHASHED_SUBVOL; + + LOCK (&frame->lock); + { + if (op_ret == -1) { + if (op_errno == ENOENT) { + local->op_ret = 0; + } else { + local->op_ret = -1; + local->op_errno = op_errno; + } + gf_msg_debug (this->name, op_errno, + "Unlink: subvolume %s returned -1" + " with errno = %d", + prev->this->name, op_errno); + goto unlock; + } + + local->op_ret = 0; + + local->postparent = *postparent; + local->preparent = *preparent; + + if (local->loc.parent) { + dht_inode_ctx_time_update (local->loc.parent, this, + &local->preparent, 0); + dht_inode_ctx_time_update (local->loc.parent, this, + &local->postparent, 1); + } + } +unlock: + UNLOCK (&frame->lock); + + if (local->op_ret) + goto out; + + if (cold_tier != local->cached_subvol) { + /* + * File is present in hot tier, so there will be + * a link file on cold tier, deleting the linkfile + * from cold tier + */ + STACK_WIND (frame, tier_unlink_linkfile_cbk, + cold_tier, + cold_tier->fops->unlink, &local->loc, + local->flags, xdata); + return 0; + } + + ret = dict_get_bin (xdata, DHT_IATT_IN_XDATA_KEY, (void **) &stbuf); + if (!ret && stbuf && ((IS_DHT_MIGRATION_PHASE2 (stbuf)) || + IS_DHT_MIGRATION_PHASE1 (stbuf))) { + /* + * File is migrating from cold to hot tier. + * Delete the destination linkfile. + */ + STACK_WIND (frame, tier_unlink_lookup_cbk, + hot_tier, + hot_tier->fops->lookup, + &local->loc, NULL); + return 0; + + } + +out: + DHT_STACK_UNWIND (unlink, frame, local->op_ret, local->op_errno, + &local->preparent, &local->postparent, xdata); + + return 0; +} + +int +tier_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc, int xflag, + dict_t *xdata) +{ + xlator_t *cached_subvol = NULL; + xlator_t *hashed_subvol = NULL; + dht_conf_t *conf = NULL; + int op_errno = -1; + dht_local_t *local = NULL; + int ret = -1; + + VALIDATE_OR_GOTO (frame, err); + VALIDATE_OR_GOTO (this, err); + VALIDATE_OR_GOTO (loc, err); + + conf = this->private; + + local = dht_local_init (frame, loc, NULL, GF_FOP_UNLINK); + if (!local) { + op_errno = ENOMEM; + + goto err; + } + + hashed_subvol = TIER_HASHED_SUBVOL; + + cached_subvol = local->cached_subvol; + if (!cached_subvol) { + gf_msg_debug (this->name, 0, + "no cached subvolume for path=%s", loc->path); + op_errno = EINVAL; + goto err; + } + + local->flags = xflag; + if (hashed_subvol == cached_subvol) { + /* + * File resides in cold tier. We need to stat + * the file to see if it is being promoted. + * If yes we need to delete the destination + * file as well. + */ + xdata = xdata ? dict_ref (xdata) : dict_new (); + if (xdata) { + ret = dict_set_dynstr_with_alloc (xdata, + DHT_IATT_IN_XDATA_KEY, "yes"); + if (ret) { + gf_msg_debug (this->name, 0, + "Failed to set dictionary key %s", + DHT_IATT_IN_XDATA_KEY); + } + } + } + + /* + * File is on hot tier, delete the data file first, then + * linkfile from cold. + */ + STACK_WIND (frame, tier_unlink_cbk, + cached_subvol, cached_subvol->fops->unlink, loc, + xflag, xdata); + if (xdata) + dict_unref (xdata); + return 0; +err: + op_errno = (op_errno == -1) ? errno : op_errno; + DHT_STACK_UNWIND (unlink, frame, -1, op_errno, NULL, NULL, NULL); + + return 0; +} + +int tier_readdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, gf_dirent_t *orig_entries, dict_t *xdata) |