From 269b58474d046575f92f4e7ef4a981f1c7aa627a Mon Sep 17 00:00:00 2001
From: cee1 <chenj@lemote.com>
Date: Wed, 16 Mar 2011 18:51:30 +0800
Subject: [PATCH] Fix broken systemd-readahead-collect on mips.

---
 config.h.in   |    3 ++
 configure.ac  |    3 ++
 src/missing.h |   90 +++++++++++++++++++++++++++++++++++++++++++++++++-------
 3 files changed, 84 insertions(+), 12 deletions(-)

diff --git a/config.h.in b/config.h.in
index d6bd256..f1fdcec 100644
--- a/config.h.in
+++ b/config.h.in
@@ -3,6 +3,9 @@
 /* Canonical host string. */
 #undef CANONICAL_HOST
 
+/* Whether on mips arch */
+#undef ARCH_MIPS
+
 /* Target Distribution */
 #undef DISTRIBUTION
 
diff --git a/configure.ac b/configure.ac
index cae2dce..8a28c8e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -28,6 +28,9 @@ AC_SUBST(PACKAGE_URL, [http://www.freedesktop.org/wiki/Software/systemd])
 
 AC_CANONICAL_HOST
 AC_DEFINE_UNQUOTED([CANONICAL_HOST], "$host", [Canonical host string.])
+AS_IF([test "x$host_cpu" = "xmips" || test "x$host_cpu" = "xmipsel" ||
+       test "x$host_cpu" = "xmips64" || test "x$host_cpu" = "xmips64el"],
+      [AC_DEFINE(ARCH_MIPS, [], [Whether on mips arch])])
 
 AM_SILENT_RULES([yes])
 
diff --git a/src/missing.h b/src/missing.h
index ff5dcb4..f65a5b8 100644
--- a/src/missing.h
+++ b/src/missing.h
@@ -35,6 +35,11 @@
 #endif
 
 #include "macro.h"
+#include "config.h"
+
+#ifdef ARCH_MIPS 
+#include <asm/sgidefs.h>
+#endif
 
 #ifndef RLIMIT_RTTIME
 #define RLIMIT_RTTIME 15
@@ -77,29 +82,90 @@ static inline int pivot_root(const char *new_root, const char *put_old) {
 }
 
 #ifdef __x86_64__
-#ifndef __NR_fanotify_init
-#define __NR_fanotify_init 300
-#endif
-#ifndef __NR_fanotify_mark
-#define __NR_fanotify_mark 301
-#endif
+#  ifndef __NR_fanotify_init
+#    define __NR_fanotify_init 300
+#  endif
+#  ifndef __NR_fanotify_mark
+#    define __NR_fanotify_mark 301
+#  endif
+#elif defined _MIPS_SIM
+#  if _MIPS_SIM == _MIPS_SIM_ABI32
+#    ifndef __NR_fanotify_init
+#      define __NR_fanotify_init 4336
+#    endif
+#    ifndef __NR_fanotify_mark
+#      define __NR_fanotify_mark 4337
+#    endif
+#  elif _MIPS_SIM == _MIPS_SIM_NABI32
+#    ifndef __NR_fanotify_init
+#      define __NR_fanotify_init 6300
+#    endif
+#    ifndef __NR_fanotify_mark
+#      define __NR_fanotify_mark 6301
+#    endif
+#  elif _MIPS_SIM == _MIPS_SIM_ABI64
+#    ifndef __NR_fanotify_init
+#      define __NR_fanotify_init 5295
+#    endif
+#    ifndef __NR_fanotify_mark
+#      define __NR_fanotify_mark 5296
+#    endif
+#  endif
 #else
-#ifndef __NR_fanotify_init
-#define __NR_fanotify_init 338
-#endif
-#ifndef __NR_fanotify_mark
-#define __NR_fanotify_mark 339
-#endif
+#  ifndef __NR_fanotify_init
+#    define __NR_fanotify_init 338
+#  endif
+#  ifndef __NR_fanotify_mark
+#    define __NR_fanotify_mark 339
+#  endif
 #endif
 
 static inline int fanotify_init(unsigned int flags, unsigned int event_f_flags) {
         return syscall(__NR_fanotify_init, flags, event_f_flags);
 }
 
+#if defined _MIPS_SIM && _MIPS_SIM == _MIPS_SIM_ABI32
+/* The o32 'syscall' with fanotify_mark is broken*/
+static inline int fanotify_mark(int fanotify_fd, unsigned int flags, uint64_t mask,
+                                int dfd, const char *pathname)
+{
+	long _sys_result;
+
+	/* We need to use a frame pointer for the functions in which we
+	 * adjust $sp around the syscall, or debug information and unwind
+	 * information will be $sp relative and thus wrong during the syscall.  As
+	 * of GCC 3.4.3, this is sufficient.  */
+	alloca (4);
+	{
+		register long __v0 asm("$2");
+		register long __a0 asm("$4") = (long) fanotify_fd;
+		register long __a1 asm("$5") = (long) flags;
+		register long __a2 asm("$6") = *((long *) &mask);
+		register long __a3 asm("$7") = *((long *) &mask+1);
+		__asm__ volatile (
+			".set noreorder\n\t"
+			"subu	$29, 32\n\t"
+			"sw	%6, 16($29)\n\t"
+			"sw	%7, 20($29)\n\t"
+			"li     $2, %2\n\t"
+			"syscall\n\t"
+			"addiu	$29, 32\n\t"
+			".set reorder"
+			: "=r" (__v0), "+r" (__a3)	
+			: "i" (__NR_fanotify_mark), "r" (__a0), "r" (__a1), "r" (__a2),
+			  "r" ((long) dfd), "r" ((long) pathname)
+			: "$1", "$3", "memory");	
+		errno = __a3;
+		_sys_result = __v0;
+	}
+	return _sys_result;
+}
+#else
 static inline int fanotify_mark(int fanotify_fd, unsigned int flags, uint64_t mask,
                                 int dfd, const char *pathname) {
         return syscall(__NR_fanotify_mark, fanotify_fd, flags, mask, dfd, pathname);
 }
+#endif
 
 #ifndef BTRFS_IOCTL_MAGIC
 #define BTRFS_IOCTL_MAGIC 0x94
-- 
1.7.2.3

