[Cbe-oss-dev] [PATCH] libspe2 add assist calls for pread, pwrite, readv and writev

Patrick Mansfield patmans at us.ibm.com
Fri Jun 22 02:39:44 EST 2007


Add assist calls for:

	ssize_t pread(int fd, void *buf, size_t count, off_t offset)
	ssize_t pwrite(int fd, const void *buf, size_t count, off_t offset)
	ssize_t readv(int fd, const struct iovec *vector, int count)
	ssize_t writev(int fd, const struct iovec *vector, int count)

PS: the last of these types of patches for now!

Signed-off-by: Patrick Mansfield <patmans at us.ibm.com>

Index: quilt-libspe2/spebase/default_posix1_handler.c
===================================================================
--- quilt-libspe2.orig/spebase/default_posix1_handler.c
+++ quilt-libspe2/spebase/default_posix1_handler.c
@@ -31,6 +31,7 @@
 #include <sys/stat.h>
 #include <sys/timex.h>
 #include <sys/types.h>
+#include <sys/uio.h>
 #include <sys/wait.h>
 #include <fcntl.h>
 #include <linux/limits.h>
@@ -156,6 +157,10 @@ enum {
 	SPE_POSIX1_UMASK,
 	SPE_POSIX1_UTIME,
 	SPE_POSIX1_UTIMES,
+	SPE_POSIX1_PREAD,
+	SPE_POSIX1_PWRITE,
+	SPE_POSIX1_READV,
+	SPE_POSIX1_WRITEV,
 	SPE_POSIX1_LAST_OPCODE,
 };
 #define SPE_POSIX1_NR_OPCODES	\
@@ -264,6 +269,42 @@ static void spe_copy_dirent(struct spe_c
     memcpy(spe_ent->d_name, ent->d_name, sizeof(spe_ent->d_name));
 }
 
+/*
+ * Needs to be compiled with -D_XOPEN_SOURCE to get IOV_MAX, but that
+ * sounds bad: IOV_MAX is the maximum number of vectors for readv and
+ * writev calls.
+ */
+#ifndef IOV_MAX
+#define IOV_MAX	1024
+#endif
+
+#define SPU_SSIZE_MAX	0x7fffffffL
+
+struct ls_iovec {
+    uint32_t iov_base;
+    uint32_t iov_len;
+};
+
+static int
+check_conv_spuvec(char *ls, struct iovec *vec, struct ls_iovec *lsvec, int
+          count)
+{
+    int i;
+    size_t sum;
+
+    sum = 0;
+    for (i = 0; i < count; i++) {
+        vec[i].iov_base = GET_LS_PTR(lsvec[i].iov_base);
+        vec[i].iov_len = lsvec[i].iov_len;
+        if (sum + vec[i].iov_len > SPU_SSIZE_MAX) {
+            errno = EINVAL;
+            return -1;
+        }
+        sum += vec[i].iov_len;
+    }
+    return 0;
+}
+
 /**
  * default_posix1_handler_stat
  * @ls: base pointer to local store area.
@@ -2054,6 +2095,122 @@ int default_posix1_handler_utimes(char *
     return 0;
 }
 
+/**
+ * default_posix1_handler_pread
+ * @ls: base pointer to local store area.
+ * @opdata: POSIX.1 call opcode & data.
+ *
+ * Implement:
+ *      ssize_t pread(int fd, void *buf, size_t count, off_t offset)
+ */
+int default_posix1_handler_pread(char *ls, unsigned long opdata)
+{
+    DECL_4_ARGS();
+    DECL_RET();
+    int fd;
+    void *buf;
+    size_t count;
+    off_t offset;
+    int rc;
+
+    DEBUG_PRINTF("%s\n", __func__);
+    fd = arg0->slot[0];
+    buf = GET_LS_PTR(arg1->slot[0]);
+    count = arg2->slot[0];
+    offset = arg3->slot[0];
+    rc = pread(fd, buf, count, offset);
+    PUT_LS_RC(rc, 0, 0, errno);
+    return 0;
+}
+
+/**
+ * default_posix1_handler_pwrite
+ * @ls: base pointer to local store area.
+ * @opdata: POSIX.1 call opcode & data.
+ *
+ * Implement:
+ *      ssize_t pwrite(int fd, const void *buf, size_t count, off_t offset)
+ */
+int default_posix1_handler_pwrite(char *ls, unsigned long opdata)
+{
+    DECL_4_ARGS();
+    DECL_RET();
+    int fd;
+    void *buf;
+    size_t count;
+    off_t offset;
+    ssize_t sz;
+    int rc;
+
+    DEBUG_PRINTF("%s\n", __func__);
+    fd = arg0->slot[0];
+    buf = GET_LS_PTR(arg1->slot[0]);
+    count = arg2->slot[0];
+    offset = arg3->slot[0];
+    sz = pwrite(fd, buf, count, offset);
+    rc = sz;
+    PUT_LS_RC(rc, 0, 0, errno);
+    return 0;
+}
+
+/**
+ * default_posix1_handler_readv
+ * @ls: base pointer to local store area.
+ * @opdata: POSIX.1 call opcode & data.
+ *
+ * Implement:
+ *      ssize_t readv(int fd, const struct iovec *vec, int count)
+ */
+int default_posix1_handler_readv(char *ls, unsigned long opdata)
+{
+    DECL_3_ARGS();
+    DECL_RET();
+    int fd;
+    struct iovec vec[IOV_MAX];
+    struct ls_iovec *lsvec;
+    size_t count;
+    int rc;
+
+    DEBUG_PRINTF("%s\n", __func__);
+    fd = arg0->slot[0];
+    lsvec = GET_LS_PTR(arg1->slot[0]);
+    count = arg2->slot[0];
+    rc = check_conv_spuvec(ls, vec, lsvec, count);
+    if (!rc)
+        rc = readv(fd, vec, count);
+    PUT_LS_RC(rc, 0, 0, errno);
+    return 0;
+}
+
+/**
+ * default_posix1_handler_writev
+ * @ls: base pointer to local store area.
+ * @opdata: POSIX.1 call opcode & data.
+ *
+ * Implement:
+ *      ssize_t writev(int fd, const struct iovec *vec, int count)
+ */
+int default_posix1_handler_writev(char *ls, unsigned long opdata)
+{
+    DECL_3_ARGS();
+    DECL_RET();
+    int fd;
+    struct iovec vec[IOV_MAX];
+    struct ls_iovec *lsvec;
+    size_t count;
+    int rc;
+
+    DEBUG_PRINTF("%s\n", __func__);
+    fd = arg0->slot[0];
+    lsvec = GET_LS_PTR(arg1->slot[0]);
+    count = arg2->slot[0];
+    rc = check_conv_spuvec(ls, vec, lsvec, count);
+    if (!rc)
+        rc = writev(fd, vec, count);
+    PUT_LS_RC(rc, 0, 0, errno);
+    return 0;
+}
+
 int (*default_posix1_funcs[SPE_POSIX1_NR_OPCODES]) (char *, unsigned long) = {
 	[SPE_POSIX1_UNUSED]		= NULL,
 	[SPE_POSIX1_ADJTIMEX]		= default_posix1_handler_adjtimex,
@@ -2120,6 +2277,10 @@ int (*default_posix1_funcs[SPE_POSIX1_NR
 	[SPE_POSIX1_UMASK]		= default_posix1_handler_umask,
 	[SPE_POSIX1_UTIME]		= default_posix1_handler_utime,
 	[SPE_POSIX1_UTIMES]		= default_posix1_handler_utimes,
+	[SPE_POSIX1_PREAD]		= default_posix1_handler_pread,
+	[SPE_POSIX1_PWRITE]		= default_posix1_handler_pwrite,
+	[SPE_POSIX1_READV]		= default_posix1_handler_readv,
+	[SPE_POSIX1_WRITEV]		= default_posix1_handler_writev,
 };
 
 /**
Index: quilt-libspe2/spebase/default_posix1_handler.h
===================================================================
--- quilt-libspe2.orig/spebase/default_posix1_handler.h
+++ quilt-libspe2/spebase/default_posix1_handler.h
@@ -87,5 +87,9 @@ extern int default_posix1_handler_sched_
 extern int default_posix1_handler_umask(char *ls, unsigned long args);
 extern int default_posix1_handler_utime(char *ls, unsigned long args);
 extern int default_posix1_handler_utimes(char *ls, unsigned long args);
+extern int default_posix1_handler_pread(char *ls, unsigned long args);
+extern int default_posix1_handler_pwrite(char *ls, unsigned long args);
+extern int default_posix1_handler_readv(char *ls, unsigned long args);
+extern int default_posix1_handler_writev(char *ls, unsigned long args);
 
 #endif /* __DEFAULT_POSIX1_HANDLER_H__ */



More information about the cbe-oss-dev mailing list