summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEmmanuel Dreyfus <manu@netbsd.org>2012-06-15 09:58:53 +0200
committerAnand Avati <avati@redhat.com>2012-07-13 14:07:39 -0700
commite14095fbbe5c410863ffca865803762dd8cf6e87 (patch)
tree322f96ab187f900ddb94843794a59ced07ccd377
parentf626ea8e9121baab4c0447f9aaf273e1141a79ed (diff)
Use linkat(2) for symlink to get portable behavior
This is a backport of Change-Id: If7f6f17b48a4ccf8827c3795ec147306df6b5542 BUG: 764655 Change-Id: I374aca5d72d003d67a2bdc9a22b88ce7dd412a0d Signed-off-by: Emmanuel Dreyfus <manu@netbsd.org> Reviewed-on: http://review.gluster.com/3580 Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Anand Avati <avati@redhat.com>
-rw-r--r--xlators/storage/posix/src/posix-handle.c18
1 files changed, 18 insertions, 0 deletions
diff --git a/xlators/storage/posix/src/posix-handle.c b/xlators/storage/posix/src/posix-handle.c
index 38b28edc386..a611358454d 100644
--- a/xlators/storage/posix/src/posix-handle.c
+++ b/xlators/storage/posix/src/posix-handle.c
@@ -454,7 +454,16 @@ posix_handle_hard (xlator_t *this, const char *oldpath, uuid_t gfid, struct stat
return -1;
}
+#ifdef HAVE_LINKAT
+ /*
+ * Use linkat if the target may be a symlink to a directory
+ * or without an existing target. See comment about linkat()
+ * usage in posix_link() in posix.c for details
+ */
+ ret = linkat (AT_FDCWD, oldpath, AT_FDCWD, newpath, 0);
+#else
ret = link (oldpath, newpath);
+#endif
if (ret) {
gf_log (this->name, GF_LOG_WARNING,
"link %s -> %s failed (%s)",
@@ -633,7 +642,16 @@ posix_create_link_if_gfid_exists (xlator_t *this, uuid_t gfid,
MAKE_HANDLE_PATH (newpath, this, gfid, NULL);
ret = lstat (newpath, &stbuf);
if (!ret) {
+#ifdef HAVE_LINKAT
+ /*
+ * Use linkat if the target may be a symlink to a directory
+ * or without an existing target. See comment about linkat()
+ * usage in posix_link() in posix.c for details
+ */
+ ret = linkat (AT_FDCWD, newpath, AT_FDCWD, real_path, 0);
+#else
ret = link (newpath, real_path);
+#endif
}
return ret;