diff options
author | Emmanuel Dreyfus <manu@netbsd.org> | 2012-06-02 18:36:43 +0200 |
---|---|---|
committer | Anand Avati <avati@redhat.com> | 2012-06-05 10:46:25 -0700 |
commit | 73366888815d308feb0393775db0dc5ea8f5a026 (patch) | |
tree | a3df57a467f1e2e242236ccd6a696f81e8072506 /xlators/storage/posix/src/posix-handle.c | |
parent | 6eee473eba94697953e8b3e1b04fe5ef1de5f474 (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/storage/posix/src/posix-handle.c')
-rw-r--r-- | xlators/storage/posix/src/posix-handle.c | 18 |
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; |