From 73366888815d308feb0393775db0dc5ea8f5a026 Mon Sep 17 00:00:00 2001 From: Emmanuel Dreyfus Date: Sat, 2 Jun 2012 18:36:43 +0200 Subject: 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 Reviewed-on: http://review.gluster.com/3507 Tested-by: Gluster Build System Reviewed-by: Anand Avati --- xlators/storage/posix/src/posix-handle.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'xlators/storage') 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; -- cgit