summaryrefslogtreecommitdiffstats
path: root/xlators
diff options
context:
space:
mode:
authorShyam <srangana@redhat.com>2014-09-10 23:58:35 +0530
committerNiels de Vos <ndevos@redhat.com>2014-10-01 03:36:11 -0700
commit58f1273c0831a0c0ac99f4bc66461ec88a112f62 (patch)
tree19e60e4458b7e4df2eaa05f331c79a159d1d1a06 /xlators
parentab29e0fed53f4628281be6e8290546fb88f4f6d2 (diff)
cluster/dht: Treat linkto file rename failure as non-critial error
It is a critical failure iff we fail to rename the cached file if the rename of the linkto failed, it is not a critical failure, and we do not want to lose the created hard link for the new name as that could have been read by other clients. NOTE: If another client is attempting the same oldname -> newname rename, and finds both file names as existing, and are hard links to each other, then FUSE would send in an unlink for oldname. In this time duration if we treat the linkto as a critical error and unlink the newname we created, we would have effectively lost the file to rename operations. Repercussions of treating this as a non-critical error is that we could leave behind a stale linkto file and/or not create the new linkto file, the second case would be rectified by a subsequent lookup, the first case by a rebalance, like for all stale linkto files Change-Id: Ia53ad8b43c3cf8f48ef5b43fd1fec4274e807556 BUG: 1140348 Signed-off-by: Shyam <srangana@redhat.com> Reviewed-on: http://review.gluster.org/8563 Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Jeff Darcy <jdarcy@redhat.com> Reviewed-by: Vijay Bellur <vbellur@redhat.com> (cherry picked from commit 890ab583a519b3b189a61c5fd563b4326836b988) Signed-off-by: Nithya Balachandran <nbalacha@redhat.com> Reviewed-on: http://review.gluster.org/8727 Reviewed-by: Niels de Vos <ndevos@redhat.com>
Diffstat (limited to 'xlators')
-rw-r--r--xlators/cluster/dht/src/dht-rename.c49
1 files changed, 43 insertions, 6 deletions
diff --git a/xlators/cluster/dht/src/dht-rename.c b/xlators/cluster/dht/src/dht-rename.c
index 8dfebef919e..3e4607d337b 100644
--- a/xlators/cluster/dht/src/dht-rename.c
+++ b/xlators/cluster/dht/src/dht-rename.c
@@ -597,13 +597,50 @@ dht_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
if (local->linked == _gf_true)
FRAME_SU_UNDO (frame, dht_local_t);
+
+ /* It is a critical failure iff we fail to rename the cached file
+ * if the rename of the linkto failed, it is not a critical failure,
+ * and we do not want to lose the created hard link for the new
+ * name as that could have been read by other clients.
+ *
+ * NOTE: If another client is attempting the same oldname -> newname
+ * rename, and finds both file names as existing, and are hard links
+ * to each other, then FUSE would send in an unlink for oldname. In
+ * this time duration if we treat the linkto as a critical error and
+ * unlink the newname we created, we would have effectively lost the
+ * file to rename operations.
+ *
+ * Repercussions of treating this as a non-critical error is that
+ * we could leave behind a stale linkto file and/or not create the new
+ * linkto file, the second case would be rectified by a subsequent
+ * lookup, the first case by a rebalance, like for all stale linkto
+ * files */
+
if (op_ret == -1) {
- gf_log (this->name, GF_LOG_WARNING,
- "%s: rename on %s failed (%s)", local->loc.path,
- prev->this->name, strerror (op_errno));
- local->op_ret = op_ret;
- local->op_errno = op_errno;
- goto cleanup;
+ /* Critical failure: unable to rename the cached file */
+ if (src_cached == dst_cached) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "%s: Rename on %s failed, (gfid = %s) "
+ "error : %s",
+ local->loc.path, prev->this->name,
+ local->loc.inode ?
+ uuid_utoa(local->loc.inode->gfid):"",
+ strerror(errno));
+ local->op_ret = op_ret;
+ local->op_errno = op_errno;
+ goto cleanup;
+ } else {
+ /* Non-critical failure, unable to rename the linkto
+ * file
+ */
+ gf_log (this->name, GF_LOG_INFO,
+ "%s: Rename (linkto file) on %s failed, "
+ "(gfid = %s) error : %s ",
+ local->loc.path, prev->this->name,
+ local->loc.inode ?
+ uuid_utoa(local->loc.inode->gfid):"",
+ strerror(errno));
+ }
}
if ((src_cached == dst_cached) && (dst_hashed != dst_cached)) {