summaryrefslogtreecommitdiffstats
path: root/xlators
diff options
context:
space:
mode:
authorEmmanuel Dreyfus <manu@netbsd.org>2012-06-02 18:36:43 +0200
committerAnand Avati <avati@redhat.com>2012-06-05 10:46:25 -0700
commit73366888815d308feb0393775db0dc5ea8f5a026 (patch)
treea3df57a467f1e2e242236ccd6a696f81e8072506 /xlators
parent6eee473eba94697953e8b3e1b04fe5ef1de5f474 (diff)
Use linkat(2) when linking on symlink
link(2) behavior is not standardized when it comes to symlink. BSD links to the symlink target (and fails if it does not exist), Linux links to the symlink itself. Use linkat(2) instead of link(2) in order to get a portable behavior. BUG: 764655 Change-Id: If7f6f17b48a4ccf8827c3795ec147306df6b5542 Signed-off-by: Emmanuel Dreyfus <manu@netbsd.org> Reviewed-on: http://review.gluster.com/3507 Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Anand Avati <avati@redhat.com>
Diffstat (limited to 'xlators')
-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 7c53bbc48d8..2c9277e7f3a 100644
--- a/xlators/storage/posix/src/posix-handle.c
+++ b/xlators/storage/posix/src/posix-handle.c
@@ -557,7 +557,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)",
@@ -736,7 +745,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;