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

[Linux-cluster] dlm - update dlm32 layer



Hi folks

The attached patch adds biarch support to the dlm32 layer of libdlm. It
is currently only enabled on s390 and sparc.

Bastian

-- 
Those who hate and fight must stop themselves -- otherwise it is not stopped.
		-- Spock, "Day of the Dove", stardate unknown
=== lib/Makefile
==================================================================
--- lib/Makefile  (revision 308)
+++ lib/Makefile  (local)
@@ -22,7 +22,7 @@
 
 include ${top_srcdir}/make/defines.mk
 
-CFLAGS += -g -O -I. -fPIC
+CFLAGS += -g -O -I.
 
 ifneq (${KERNEL_SRC}, )
 # Use the kernel tree if patched, otherwise, look where cluster headers
@@ -37,38 +37,35 @@
 
 all: $(STATICLIB) $(SHAREDLIB)
 
-$(LIBNAME).a: libdlm.o libaislock.o
-	${AR} cr libdlm.a libdlm.o libaislock.o
+lib_SOURCES = libdlm.c libaislock.c dlm32.c
+lib_lt_SOURCES = libdlm_lt.c dlm32.c
+
+$(LIBNAME).a: $(lib_SOURCES:.c=.po)
+	${AR} cr libdlm.a $^
 	${RANLIB} libdlm.a 
 
-$(LIBNAME)_lt.a: libdlm_lt.o 
-	${AR} r libdlm_lt.a libdlm_lt.o 
+$(LIBNAME)_lt.a: $(lib_lt_SOURCES:.c=.po)
+	${AR} r libdlm_lt.a $^
 	${RANLIB} libdlm_lt.a 
 
-$(LIBNAME).so.${RELEASE_MAJOR}.${RELEASE_MINOR}: libdlm.po libaislock.po
-	$(LD) -shared -o $@ -soname=$(LIBNAME).so.$(RELEASE_MAJOR) $^
+$(LIBNAME).so.${RELEASE_MAJOR}.${RELEASE_MINOR}: $(lib_SOURCES:.c=.po)
+	$(CC) -shared -o $@ -Wl,-soname=$(LIBNAME).so.$(RELEASE_MAJOR) $^
 
-$(LIBNAME)_lt.so.${RELEASE_MAJOR}.${RELEASE_MINOR}: libdlm_lt.po
+$(LIBNAME)_lt.so.${RELEASE_MAJOR}.${RELEASE_MINOR}: $(lib_lt_SOURCES:.c=.po)
 	$(CC) -shared -o $@ -Wl,-soname=$(LIBNAME)_lt.so.$(RELEASE_MAJOR) $^
 
-libdlm.po: libdlm.c
-	$(CC) $(CFLAGS) -D_REENTRANT -c -o $@ $<
+%_lt.o: %.c
+	$(CC) $(CFLAGS) -c -o $@ $<
 
-libdlm.o: libdlm.c
-	$(CC) $(CFLAGS) -D_REENTRANT -c -o $@ $<
+%_lt.po: %.c
+	$(CC) $(CFLAGS) -fPIC -c -o $@ $<
 
-libaislock.po: libaislock.c
+%.o: %.c
 	$(CC) $(CFLAGS) -D_REENTRANT -c -o $@ $<
 
-libaislock.o: libaislock.c
-	$(CC) $(CFLAGS) -D_REENTRANT -c -o $@ $<
+%.po: %.c
+	$(CC) $(CFLAGS) -fPIC -D_REENTRANT -c -o $@ $<
 
-libdlm_lt.po: libdlm.c
-	$(CC) $(CFLAGS) -c -o $@ $<
-
-libdlm_lt.o: libdlm.c
-	$(CC) $(CFLAGS) -c -o $@ $<
-
 copytobin: all
 
 
=== lib/dlm32.c
==================================================================
--- lib/dlm32.c  (revision 308)
+++ lib/dlm32.c  (local)
@@ -23,7 +23,23 @@
 /* Convert 32 bit userland reads & writes to something suitable for
    a 64 bit kernel */
 
+#include <stdbool.h>
+#include <stdint.h>
+#include <sys/utsname.h>
+#include <string.h>
+#include <unistd.h>
+#include "dlm.h"
+#include "dlm_device.h"
 
+#if (defined(__s390__) || defined(__sparc__)) && __WORDSIZE == 32
+# define BUILD_BIARCH
+#endif
+
+extern ssize_t dlm_read(int, struct dlm_lock_result *);
+extern ssize_t dlm_read_data(int, struct dlm_lock_result *, size_t);
+extern ssize_t dlm_write(int, struct dlm_write_request *, size_t);
+
+#ifdef BUILD_BIARCH
 /* 64 bit versions of the structs */
 struct dlm_lock_params64 {
 	uint8_t mode;
@@ -32,10 +48,10 @@
 	uint32_t parent;
 	struct dlm_range range;
 	uint8_t namelen;
-        uint64_t castparam;
+	uint64_t castparam;
 	uint64_t castaddr;
 	uint64_t bastparam;
-        uint64_t bastaddr;
+	uint64_t bastaddr;
 	uint64_t lksb;
 	char lvb[DLM_LVB_LEN];
 	char name[1];
@@ -73,10 +89,10 @@
 
 struct dlm_lksb64
 {
-        int      sb_status;
-        uint32_t sb_lkid;
-        char     sb_flags;
-        uint64_t sb_lvbptr;
+	int      sb_status;
+	uint32_t sb_lkid;
+	char     sb_flags;
+	uint64_t sb_lvbptr;
 };
 
 /* struct read from the "device" fd,
@@ -104,16 +120,38 @@
 	int gqi_lockcount;	/* output */
 };
 
+static bool check_biarch_convert(void)
+{
+	static enum { undefined, native, convert } status;
+	if (status == undefined)
+	{
+		struct utsname buf;
+		if (uname(&buf) != 0)
+			status = native;
+		else if (strcmp(buf.machine,
+#ifdef __s390__
+				"s390x"
+#endif
+#ifdef __sparc__
+				"sparc64"
+#endif
+			  ) == 0)
+			status = convert;
+		else
+			status = native;
+	}
+	if (status == convert)
+		return true;
+	return false;
+}
 
-int dlm_write(int fd, void *buf, int len)
+static ssize_t _dlm_write_convert(int fd, struct dlm_write_request *req32, size_t len32)
 {
 	char buf64[sizeof(struct dlm_write_request64) + DLM_RESNAME_MAXLEN];
 	struct dlm_write_request64 *req64;
-	struct dlm_write_request   *req32;
 	int len64;
 	int ret;
 
-	req32 = (struct dlm_write_request *)buf;
 	req64 = (struct dlm_write_request64 *)buf64;
 	len64 = sizeof(struct dlm_write_request64);
 
@@ -167,37 +205,33 @@
 
 	/* Fake the return length */
 	if (ret == len64)
-		ret = len;
+		ret = len32;
 
 	return ret;
 }
 
-
-int dlm_read(int fd, void *buf, int len)
+static ssize_t _dlm_read_convert(bool data, int fd, struct dlm_lock_result *res32, ssize_t len32)
 {
-	int ret;
-	int len64;
-	struct dlm_lock_result *res32;
+	ssize_t ret;
+	size_t len64;
 	struct dlm_lock_result64 *res64;
 	struct dlm_lock_result64 buf64;
 
-	res32 = (struct dlm_lock_result *)buf;
-
 	/* There are two types of read done here, the first just gets the structure, for that
 	   we need our own buffer because the 64 bit one is larger than the 32bit.
 	   When the user wants the extended information it has already been told the full (64bit)
 	   size of the buffer by the kernel so we can use that buffer for reading, that
 	   also avoids the need to copy the extended data blocks too.
 	*/
-	if (len == sizeof(struct dlm_lock_result))
+	if (!data)
 	{
-		len64 = sizeof(struct dlm_lock_result64);
+		len64 = sizeof(buf64);
 		res64 = &buf64;
 	}
 	else
 	{
-		len64 = len;
-		res64 = (struct dlm_lock_result64 *)buf;
+		len64 = len32;
+		res64 = (struct dlm_lock_result64 *)res32;
 	}
 
 	ret = read(fd, res64, len64);
@@ -222,10 +256,47 @@
 			struct dlm_queryinfo64 *qinfo64;
 			struct dlm_queryinfo *qinfo32;
 
-			qinfo64 = (struct dlm_queryinfo64 *)(buf+res32->qinfo_offset);
-			qinfo32 = (struct dlm_queryinfo *)(buf+res32->qinfo_offset);
+			qinfo64 = (struct dlm_queryinfo64 *)(res32+res32->qinfo_offset);
+			qinfo32 = (struct dlm_queryinfo *)(res32+res32->qinfo_offset);
 			qinfo32->gqi_lockcount = qinfo64->gqi_lockcount;
 		}
 	}
 	return ret;
 }
+
+ssize_t dlm_read(int fd, struct dlm_lock_result *res)
+{
+	if (check_biarch_convert())
+		return _dlm_read_convert(false, fd, res, 0);
+	return read(fd, res, sizeof(struct dlm_lock_result));
+}
+
+ssize_t dlm_read_data(int fd, struct dlm_lock_result *res, size_t len)
+{
+	if (check_biarch_convert())
+		return _dlm_read_convert(true, fd, res, len);
+	return read(fd, res, len);
+}
+
+ssize_t dlm_write(int fd, struct dlm_write_request *req, size_t len)
+{
+	if (check_biarch_convert())
+		return _dlm_write_convert(fd, req, len);
+	return write(fd, req, len);
+}
+#else /* BUILD_BIARCH */
+ssize_t dlm_read(int fd, struct dlm_lock_result *res)
+{
+	return read(fd, res, sizeof(struct dlm_lock_result));
+}
+
+ssize_t dlm_read_data(int fd, struct dlm_lock_result *res, size_t len)
+{
+	return read(fd, res, len);
+}
+
+ssize_t dlm_write(int fd, struct dlm_write_request *req, size_t len)
+{
+	return write(fd, req, len);
+}
+#endif /* BUILD_BIARCH */
=== lib/libdlm.c
==================================================================
--- lib/libdlm.c  (revision 308)
+++ lib/libdlm.c  (local)
@@ -46,15 +46,6 @@
 #include "libdlm.h"
 #include "dlm_device.h"
 
-/* Add other grotesqueries here as they arise */
-#if defined(__sparc__) && __WORDSIZE == 32
-#include "dlm32.c"
-#else
-#define dlm_write write
-#define dlm_read read
-#endif
-
-
 #define MISC_PREFIX "/dev/misc/"
 #define PROC_MISC "/proc/misc"
 #define DLM_PREFIX "dlm_"
@@ -76,6 +67,10 @@
 #endif
 };
 
+extern ssize_t dlm_read(int, struct dlm_lock_result *);
+extern ssize_t dlm_read_data(int, struct dlm_lock_result *, size_t);
+extern ssize_t dlm_write(int, struct dlm_write_request *, size_t);
+
 /* The default lockspace.
    I've resisted putting locking around this as the user should be
    "sensible" and only do lockspace operations either in the
@@ -399,14 +394,13 @@
 
 static int do_dlm_dispatch(int fd)
 {
-    char resultbuf[sizeof(struct dlm_lock_result)];
-    struct dlm_lock_result *result = (struct dlm_lock_result *)resultbuf;
-    char *fullresult=NULL;
+    struct dlm_lock_result resultbuf;
+    struct dlm_lock_result *result = &resultbuf, *fullresult = NULL;
     int status;
     void (*astaddr)(void *astarg);
 
     /* Just read the header first */
-    status = dlm_read(fd, result, sizeof(struct dlm_lock_result));
+    status = dlm_read(fd, result);
     if (status <= 0)
 	return -1;
 
@@ -418,7 +412,7 @@
 	if (!fullresult)
 	    return -1;
 
-	newstat = dlm_read(fd, fullresult, result->length);
+	newstat = dlm_read_data(fd, fullresult, result->length);
 
 	/* If it read OK then use the new data. otherwise we can
 	   still deliver the AST, it just might not have all the

Attachment: signature.asc
Description: Digital signature


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