process-request-ret-overflow.patch:
-------------------------
There is a bug in PINT_process_request() that can be triggered through io_find_total_size() when reading from very large files near eof, therefore causing read operations to fail. PINT_process_request() has an "int" return code, but was returning a 64 bit value through it. If the 64 bit value is large enough it will overflow the int and show up as a negative number which is interpreted as an error by io_find_total_size().

This patch changes the semantics slightly so that PINT_process_request() instead returns 0 or -PVFS_error rather than returning the number of bytes processed on success. It turns out that no callers were paying attention to the exact return code if it was positive anyway, because the value is duplicated in the results->bytes field.

pvfs2-perror.patch:
--------------------------
This is a trivial utility that mimics the "perror" command line tool, but handles PVFS2 error codes. It is just a handy way to find out what an error code means if you see one in log files/debugger/etc. that has not been converted to a string yet.

-Phil

diff -Naur pvfs2-old/src/apps/kernel/linux/pvfs2-client-core.c pvfs2-new/src/apps/kernel/linux/pvfs2-client-core.c
--- pvfs2-old/src/apps/kernel/linux/pvfs2-client-core.c	2006-01-09 17:12:32.000000000 +0100
+++ pvfs2-new/src/apps/kernel/linux/pvfs2-client-core.c	2006-01-12 15:21:59.000000000 +0100
@@ -2088,6 +2088,8 @@
             break;
     }
 
+    gossip_debug(GOSSIP_CLIENTCORE_DEBUG, "packaging downcall type: %d, status %d\n", 
+        vfs_request->in_upcall.type, *error_code);
     vfs_request->out_downcall.status = *error_code;
     vfs_request->out_downcall.type = vfs_request->in_upcall.type;
 }
diff -Naur pvfs2-old/src/client/sysint/sys-io.sm pvfs2-new/src/client/sysint/sys-io.sm
--- pvfs2-old/src/client/sysint/sys-io.sm	2006-01-10 20:26:18.000000000 +0100
+++ pvfs2-new/src/client/sysint/sys-io.sm	2006-01-12 15:21:59.000000000 +0100
@@ -1467,6 +1467,8 @@
     attr = &sm_p->getattr.attr;
     assert(attr);
     
+    gossip_debug(GOSSIP_CLIENT_DEBUG, "(%p) io state: io_analyze_size_results\n", sm_p);
+    
     ret = io_find_offset(
         sm_p, 
         PINT_REQUEST_TOTAL_BYTES(sm_p->u.io.mem_req),
@@ -2362,7 +2364,7 @@
 
     PINT_free_request_state(filereq_state);
     PINT_free_request_state(memreq_state);
-    return res;
+    return 0;
 }
 
 /* computes the logical offset in the file request from the size
diff -Naur pvfs2-old/src/io/description/pint-request.c pvfs2-new/src/io/description/pint-request.c
--- pvfs2-old/src/io/description/pint-request.c	2006-01-04 14:48:51.000000000 +0100
+++ pvfs2-new/src/io/description/pint-request.c	2006-01-12 15:22:00.000000000 +0100
@@ -59,7 +59,8 @@
 /* of the request.  PVFS_Distribute returns the number of bytes */
 /* processed.  If this is less than the total bytes in the chunk */
 /* this function returns otherwise it keeps processing until all */
-/* chunks are done.  Returns the number of bytes processed.  It */
+/* chunks are done.  Returns 0 on success and -PVFS_error on failure.  The */
+/* number of bytes processed is stored in result->bytes.  It */
 /* is assumed caller we retry if this is less than the total bytes */
 /* in the request */
 int PINT_process_request(PINT_Request_state *req,
@@ -82,22 +83,22 @@
 	if (!req)
 	{
 		gossip_lerr("PINT_process_request: Bad PINT_Request_state!\n");
-		return -1;
+		return -PVFS_EINVAL;
 	}
 	if (!result || !result->segmax || !result->bytemax)
 	{
 		gossip_lerr("PINT_process_request: NULL segmax or bytemax!\n");
-		return -1;
+		return -PVFS_EINVAL;
 	}
 	if (result->segs >= result->segmax || result->bytes >= result->bytemax)
 	{
 		gossip_lerr("PINT_process_request: no segments or bytes requested!\n");
-		return -1;
+		return -PVFS_EINVAL;
 	}
 	if (!PINT_IS_CKSIZE(mode) && (!result->offset_array || !result->size_array))
 	{
 		gossip_lerr("PINT_process_request: NULL offset or size array!\n");
-		return -1;
+		return -PVFS_EINVAL;
 	}
 	/* initialize some variables */
 	retval = 0;
@@ -247,7 +248,7 @@
 					req->lvl+1 >= req->cur[0].rqbase->depth)
 			{
 				gossip_lerr("PINT_process_request exceeded request depth - possibly corrupted request or request state\n");
-				return -1;
+				return -PVFS_EINVAL;
 			}
 			req->cur[req->lvl+1].el = 0;
 			req->cur[req->lvl+1].maxel = req->cur[req->lvl].rq->num_ereqs;
@@ -426,7 +427,7 @@
 	if (!PINT_IS_MEMREQ(mode))
         gossip_debug(GOSSIP_REQUEST_DEBUG,
             "=========================================================\n");
-	return result->bytes;
+	return 0;
 }
 
 /* this function runs down the ereq list and adds up the offsets */
---------------------
PatchSet 371 
Date: 2006/01/11 21:26:27
Author: pcarns
Branch: HEAD
Tag: (none) 
Log:
Added a pvfs2-perror command line utility for interpreting PVFS2 error codes
[task4255]

Members: 
	src/apps/admin/module.mk.in:1.6->1.7 
	src/apps/admin/pvfs2-perror.c:INITIAL->1.1 

Index: src/apps/admin/module.mk.in
diff -u src/apps/admin/module.mk.in:1.6 src/apps/admin/module.mk.in:1.7
--- src/apps/admin/module.mk.in:1.6	Wed Jan  4 08:50:58 2006
+++ src/apps/admin/module.mk.in	Wed Jan 11 14:26:27 2006
@@ -22,7 +22,8 @@
 	$(DIR)/pvfs2-viewdist.c \
 	$(DIR)/pvfs2-touch.c \
 	$(DIR)/pvfs2-remove-object.c \
-	$(DIR)/pvfs2-ln.c
+	$(DIR)/pvfs2-ln.c \
+	$(DIR)/pvfs2-perror.c
 
 ADMINSRC_SERVER := \
 	$(DIR)/pvfs2-mkspace.c \
--- /dev/null	1970-01-01 01:00:00.000000000 +0100
+++ src/apps/admin/pvfs2-perror.c	2006-01-12 16:40:14.292956000 +0100
@@ -0,0 +1,121 @@
+/*
+ * Copyright © Acxiom Corporation, 2006
+ *
+ * See COPYING in top-level directory.
+ */
+
+#include <unistd.h>
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/time.h>
+#include <time.h>
+#include <stdlib.h>
+
+#include "pvfs2.h"
+
+#ifndef PVFS2_VERSION
+#define PVFS2_VERSION "Unknown"
+#endif
+
+struct options
+{
+    int error_code;
+};
+
+static struct options* parse_args(int argc, char* argv[]);
+static void usage(int argc, char** argv);
+
+int main(int argc, char **argv)
+{
+    struct options* user_opts = NULL;
+
+    /* look at command line arguments */
+    user_opts = parse_args(argc, argv);
+    if(!user_opts)
+    {
+	fprintf(stderr, "Error: failed to parse command line arguments.\n");
+	usage(argc, argv);
+	return(-1);
+    }
+
+    fprintf(stderr, "Error code %d: ", user_opts->error_code);
+    PVFS_perror("", -user_opts->error_code);
+
+    return(0);
+}
+
+
+/* parse_args()
+ *
+ * parses command line arguments
+ *
+ * returns pointer to options structure on success, NULL on failure
+ */
+static struct options* parse_args(int argc, char* argv[])
+{
+    /* getopt stuff */
+    extern char* optarg;
+    extern int optind, opterr, optopt;
+    char flags[] = "vh";
+    int one_opt = 0;
+    struct options* tmp_opts = NULL;
+
+    /* create storage for the command line options */
+    tmp_opts = (struct options*)malloc(sizeof(struct options));
+    if(!tmp_opts){
+	return(NULL);
+    }
+    memset(tmp_opts, 0, sizeof(struct options));
+
+    /* look at command line arguments */
+    while((one_opt = getopt(argc, argv, flags)) != EOF){
+	switch(one_opt)
+        {
+            case('v'):
+                printf("%s\n", PVFS2_VERSION);
+                exit(0);
+	    case('h'):
+                usage(argc, argv);
+                exit(0);
+	    case('?'):
+		usage(argc, argv);
+		exit(EXIT_FAILURE);
+	}
+    }
+
+    if(optind != (argc - 1))
+    {
+	usage(argc, argv);
+	exit(EXIT_FAILURE);
+    }
+
+    if(sscanf(argv[argc-1], "%d", &tmp_opts->error_code) != 1)
+    {
+        usage(argc, argv);
+        exit(EXIT_FAILURE);
+    }
+
+    return(tmp_opts);
+}
+
+static void usage(int argc, char** argv)
+{
+    fprintf(stderr, "\n");
+    fprintf(stderr, "Usage  : %s <error_code>\n",
+	argv[0]);
+    return;
+}
+
+/*
+ * Local variables:
+ *  c-indent-level: 4
+ *  c-basic-offset: 4
+ * End:
+ *
+ * vim: ts=8 sts=4 sw=4 expandtab
+ */
+
_______________________________________________
PVFS2-developers mailing list
[email protected]
http://www.beowulf-underground.org/mailman/listinfo/pvfs2-developers

Reply via email to