[PATCH] Fixing dht rename of directory symlink

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, Aug 02, 2011 at 09:08:38AM +0000, Emmanuel Dreyfus wrote:
> It seems this has been adressed by standards:
> http://pubs.opengroup.org/onlinepubs/9699919799/functions/link.html

Attached is a patch that fixes the problem for systems that implement
linkat(2). 

While there, I have two NetBSD compatibility patches:
- allow georeplication to build
- use mkfifo(2) to create FIFO instead of mknod(2)

-- 
Emmanuel Dreyfus
manu@xxxxxxxxxx
diff --git a/configure.ac b/configure.ac
index 6d343a4..7d3b188 100644
--- a/configure.ac
+++ b/configure.ac
@@ -295,6 +295,9 @@ case $host_os in
      linux*)
 #do nothing
        ;;
+     netbsd*)
+#do nothing
+       ;;
      *)
 #disabling geo replication for non-linux platforms
 	enable_georeplication=no
@@ -359,6 +362,11 @@ dnl Linux, Solaris, Cygwin
 AC_CHECK_MEMBERS([struct stat.st_atim.tv_nsec])
 dnl FreeBSD, NetBSD
 AC_CHECK_MEMBERS([struct stat.st_atimespec.tv_nsec])
+AC_CHECK_FUNC([linkat], [have_linkat=yes])
+if test "x${have_linkat}" = "xyes"; then
+   AC_DEFINE(HAVE_LINKAT, 1, [define if found linkat])
+fi
+AC_SUBST(HAVE_LINKAT)
 
 dnl Check for argp
 AC_CHECK_HEADER([argp.h], AC_DEFINE(HAVE_ARGP, 1, [have argp]))
diff --git a/xlators/storage/posix/src/posix.c b/xlators/storage/posix/src/posix.c
index 6b71683..4b4e856 100644
--- a/xlators/storage/posix/src/posix.c
+++ b/xlators/storage/posix/src/posix.c
@@ -37,6 +37,10 @@
 #include <alloca.h>
 #endif /* GF_BSD_HOST_OS */
 
+#ifdef HAVE_LINKAT
+#include <fcntl.h>
+#endif /* HAVE_LINKAT */
+
 #include "glusterfs.h"
 #include "md5.h"
 #include "checksum.h"
@@ -779,6 +783,11 @@ posix_mknod (call_frame_t *frame, xlator_t *this,
                 goto out;
         }
 
+#ifdef __NetBSD__
+	if (S_ISFIFO(mode))
+		op_ret = mkfifo (real_path, mode);
+	else
+#endif /* __NetBSD__ */
         op_ret = mknod (real_path, mode, dev);
 
         if (op_ret == -1) {
@@ -1526,7 +1535,18 @@ posix_link (call_frame_t *frame, xlator_t *this,
                 goto out;
         }
 
+#ifdef HAVE_LINKAT
+	/*
+	 * On most systems (Linux being the notable exception), link(2)
+	 * first resolves symlinks. If the target is a directory or
+	 * is nonexistent, it will fail. linkat(2) operates on the 
+	 * symlink instead of its target when the AT_SYMLINK_FOLLOW
+	 * flag is not supplied.
+	 */
+        op_ret = linkat (AT_FDCWD, real_oldpath, AT_FDCWD, real_newpath, 0);
+#else
         op_ret = link (real_oldpath, real_newpath);
+#endif
         if (op_ret == -1) {
                 op_errno = errno;
                 gf_log (this->name, GF_LOG_ERROR,

[Index of Archives]     [Gluster Users]     [Ceph Users]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux]     [Linux OMAP]     [Linux MIPS]     [eCos]     [Asterisk Internet PBX]     [Linux API]

  Powered by Linux