summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorN Balachandran <nbalacha@redhat.com>2016-02-25 12:53:07 +0530
committerDan Lambright <dlambrig@redhat.com>2016-02-27 10:48:50 -0800
commitcf86db23169a47008d963a5fd608b7352b0ed0cc (patch)
tree418bd6d8ba386ba2b06ee20f9923e80efc12d248
parent1dce0ff0c34b86da04862b1efe0221960e6911a8 (diff)
cluster/tier: Create linkfiles to hardlinks correctly
There is a bug in the way hardlinks are handled in tiered volumes. Ideally, the tier linkto files on the cold tier to files that are hardlinks to each other on the hot tier, should themselves be hardlinks of each other. As they are not, they end up being files with the same gfid but different names for the cold tier dht, and end up overwriting the cached-subvol information stored in the dht inode-ctx. > Change-Id: Ic658a316836e6a1729cfea848b7d212674b0edd2 > BUG: 1305277 > Signed-off-by: N Balachandran <nbalacha@redhat.com> > Reviewed-on: http://review.gluster.org/13391 > Smoke: Gluster Build System <jenkins@build.gluster.com> > NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org> > CentOS-regression: Gluster Build System <jenkins@build.gluster.com> > Reviewed-by: Dan Lambright <dlambrig@redhat.com> > Tested-by: Dan Lambright <dlambrig@redhat.com> (cherry picked from commit eb362c74db84d95aac07febf0d888bd98b3fb2b9) Change-Id: I5dd98e6d248619147974a630d7d72e1942a1cc83 BUG: 1311836 Signed-off-by: N Balachandran <nbalacha@redhat.com> Reviewed-on: http://review.gluster.org/13517 Smoke: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: mohammed rafi kc <rkavunga@redhat.com> NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org> CentOS-regression: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Dan Lambright <dlambrig@redhat.com>
-rw-r--r--xlators/cluster/dht/src/tier-common.c126
-rw-r--r--xlators/cluster/dht/src/tier-common.h5
-rw-r--r--xlators/cluster/dht/src/tier.c2
3 files changed, 132 insertions, 1 deletions
diff --git a/xlators/cluster/dht/src/tier-common.c b/xlators/cluster/dht/src/tier-common.c
index 64c850ca08d..6a62f42916e 100644
--- a/xlators/cluster/dht/src/tier-common.c
+++ b/xlators/cluster/dht/src/tier-common.c
@@ -22,6 +22,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,
diff --git a/xlators/cluster/dht/src/tier-common.h b/xlators/cluster/dht/src/tier-common.h
index 44d6d71cf84..2189f7ae5cb 100644
--- a/xlators/cluster/dht/src/tier-common.h
+++ b/xlators/cluster/dht/src/tier-common.h
@@ -58,5 +58,10 @@ tier_readdir (call_frame_t *frame,
xlator_t *this, fd_t *fd, size_t size,
off_t yoff, dict_t *xdata);
+
+
+int
+tier_link (call_frame_t *frame, xlator_t *this,
+ loc_t *oldloc, loc_t *newloc, dict_t *xdata);
#endif
diff --git a/xlators/cluster/dht/src/tier.c b/xlators/cluster/dht/src/tier.c
index e716dde35ab..8ce0bcbe32c 100644
--- a/xlators/cluster/dht/src/tier.c
+++ b/xlators/cluster/dht/src/tier.c
@@ -2362,7 +2362,7 @@ struct xlator_fops fops = {
.fsyncdir = dht_fsyncdir,
.symlink = dht_symlink,
.unlink = tier_unlink,
- .link = dht_link,
+ .link = tier_link,
.mkdir = dht_mkdir,
.rmdir = dht_rmdir,
.rename = dht_rename,