summaryrefslogtreecommitdiffstats
path: root/xlators/cluster/dht/src/tier-common.c
diff options
context:
space:
mode:
Diffstat (limited to 'xlators/cluster/dht/src/tier-common.c')
-rw-r--r--xlators/cluster/dht/src/tier-common.c126
1 files changed, 126 insertions, 0 deletions
diff --git a/xlators/cluster/dht/src/tier-common.c b/xlators/cluster/dht/src/tier-common.c
index 27a780d6f6c..08664ae6a16 100644
--- a/xlators/cluster/dht/src/tier-common.c
+++ b/xlators/cluster/dht/src/tier-common.c
@@ -17,6 +17,132 @@
#include "tier.h"
int
+dht_link_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int op_ret, int op_errno,
+ inode_t *inode, struct iatt *stbuf, struct iatt *preparent,
+ struct iatt *postparent, dict_t *xdata);
+
+
+int
+tier_link_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int op_ret, int op_errno,
+ inode_t *inode, struct iatt *stbuf, struct iatt *preparent,
+ struct iatt *postparent, dict_t *xdata)
+{
+ dht_local_t *local = NULL;
+ dht_conf_t *conf = NULL;
+ loc_t *oldloc = NULL;
+ loc_t *newloc = NULL;
+
+ local = frame->local;
+ conf = this->private;
+
+ oldloc = &local->loc;
+ newloc = &local->loc2;
+
+ if (op_ret == -1) {
+ /* No continuation on DHT inode missing errors, as we should
+ * then have a good stbuf that states P2 happened. We would
+ * get inode missing if, the file completed migrated between
+ * the lookup and the link call */
+ goto out;
+ }
+
+ if (local->call_cnt != 1) {
+ goto out;
+ }
+
+ local->call_cnt = 2;
+
+ /* Do this on the hot tier now */
+
+ STACK_WIND (frame, tier_link_cbk, local->cached_subvol,
+ local->cached_subvol->fops->link,
+ oldloc, newloc, xdata);
+
+ return 0;
+
+out:
+ DHT_STRIP_PHASE1_FLAGS (stbuf);
+
+ DHT_STACK_UNWIND (link, frame, op_ret, op_errno, inode, stbuf,
+ preparent, postparent, NULL);
+
+ return 0;
+}
+
+
+int
+tier_link (call_frame_t *frame, xlator_t *this,
+ loc_t *oldloc, loc_t *newloc, dict_t *xdata)
+{
+ xlator_t *cached_subvol = NULL;
+ xlator_t *hashed_subvol = NULL;
+ int op_errno = -1;
+ int ret = -1;
+ dht_local_t *local = NULL;
+ dht_conf_t *conf = NULL;
+
+
+ VALIDATE_OR_GOTO (frame, err);
+ VALIDATE_OR_GOTO (this, err);
+ VALIDATE_OR_GOTO (oldloc, err);
+ VALIDATE_OR_GOTO (newloc, err);
+
+ conf = this->private;
+
+ local = dht_local_init (frame, oldloc, NULL, GF_FOP_LINK);
+ if (!local) {
+ op_errno = ENOMEM;
+ goto err;
+ }
+ local->call_cnt = 1;
+
+ cached_subvol = local->cached_subvol;
+
+ if (!cached_subvol) {
+ gf_msg_debug (this->name, 0,
+ "no cached subvolume for path=%s", oldloc->path);
+ op_errno = ENOENT;
+ goto err;
+ }
+
+ hashed_subvol = TIER_HASHED_SUBVOL;
+
+ ret = loc_copy (&local->loc2, newloc);
+ if (ret == -1) {
+ op_errno = ENOMEM;
+ goto err;
+ }
+
+ if (hashed_subvol == cached_subvol) {
+ STACK_WIND (frame, dht_link_cbk,
+ cached_subvol, cached_subvol->fops->link,
+ oldloc, newloc, xdata);
+ return 0;
+ }
+
+
+ /* Create hardlinks to both the data file on the hot tier
+ and the linkto file on the cold tier */
+
+ gf_uuid_copy (local->gfid, oldloc->inode->gfid);
+
+ STACK_WIND (frame, tier_link_cbk,
+ hashed_subvol, hashed_subvol->fops->link,
+ oldloc, newloc, xdata);
+
+ return 0;
+err:
+ op_errno = (op_errno == -1) ? errno : op_errno;
+ DHT_STACK_UNWIND (link, frame, -1, op_errno, NULL, NULL, NULL, NULL,
+ NULL);
+ return 0;
+}
+
+
+
+int
tier_create_unlink_stale_linkto_cbk (call_frame_t *frame, void *cookie,
xlator_t *this, int op_ret, int op_errno,
struct iatt *preparent,