diff options
author | Shyam <srangana@redhat.com> | 2014-09-04 14:17:48 -0400 |
---|---|---|
committer | Vijay Bellur <vbellur@redhat.com> | 2014-09-12 07:07:42 -0700 |
commit | fa599ee2de35d4538ae395935be2fbe8184f0806 (patch) | |
tree | 5ce7732c2c5c0c8ed34185c711d931a2600aad87 /xlators | |
parent | 0ae4768d35e76dee30b455e75a4b2552e4abb232 (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: 1138395
Signed-off-by: Shyam <srangana@redhat.com>
Reviewed-on-master: 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>
Reviewed-on: http://review.gluster.org/8614
Diffstat (limited to 'xlators')
-rw-r--r-- | xlators/cluster/dht/src/dht-rename.c | 50 |
1 files changed, 42 insertions, 8 deletions
diff --git a/xlators/cluster/dht/src/dht-rename.c b/xlators/cluster/dht/src/dht-rename.c index 138c985c8dc..1aff4f6fb9f 100644 --- a/xlators/cluster/dht/src/dht-rename.c +++ b/xlators/cluster/dht/src/dht-rename.c @@ -621,15 +621,49 @@ 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_msg (this->name, GF_LOG_WARNING, op_errno, - DHT_MSG_RENAME_FAILED, - "%s: Rename on %s failed, (gfid = %s) ", - local->loc.path, prev->this->name, - local->loc.inode? uuid_utoa(local->loc.inode->gfid):""); - 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_msg (this->name, GF_LOG_WARNING, op_errno, + DHT_MSG_RENAME_FAILED, + "%s: Rename on %s failed, (gfid = %s) ", + local->loc.path, prev->this->name, + local->loc.inode ? + uuid_utoa(local->loc.inode->gfid):""); + local->op_ret = op_ret; + local->op_errno = op_errno; + goto cleanup; + } else { + /* Non-critical failure, unable to rename the linkto + * file + */ + gf_msg (this->name, GF_LOG_INFO, op_errno, + DHT_MSG_RENAME_FAILED, + "%s: Rename (linkto file) on %s failed, " + "(gfid = %s) ", + local->loc.path, prev->this->name, + local->loc.inode ? + uuid_utoa(local->loc.inode->gfid):""); + } } if ((src_cached == dst_cached) && (dst_hashed != dst_cached)) { |