diff -druN Linux-2.4.18-pre3/fs/nfs/direct.c linux-2.4.18-pre3/fs/nfs/direct.c
--- Linux-2.4.18-pre3/fs/nfs/direct.c	Mon Jan 21 17:15:26 2002
+++ linux-2.4.18-pre3/fs/nfs/direct.c	Sat Mar  2 19:22:33 2002
@@ -172,10 +172,11 @@
                         request = rsize;
 		args.count = request;
 		args.offset = offset;
+		args.nriov = 0;
 
 		starting_offset = iobuf->offset;
 		first = last = curpage;
-		while (curpage < iobuf->nr_pages) {
+		while ((request > 0) && (curpage < iobuf->nr_pages)) {
 			struct page *page = iobuf->maplist[curpage];
 
 			if (!page)
@@ -187,16 +188,27 @@
 				iovec->iov_len = request;
 
 			request -= iovec->iov_len;
-			starting_offset = 0;	/* zero after the first page */
+			/* zero after the first iov */
+			starting_offset = 0;
 			last = curpage;
 			curpage++;
 			iovec++;
 			args.nriov++;
 		}
 
+		/*
+		 * if the last iov didn't end at a page boundary, make
+		 * curpage point back to it.  if we come back around for
+		 * another iovec construction, we then pick up the
+		 * remaining contents of the incomplete page.
+		 */
+		iovec--;
+		if (iovec->iov_len < PAGE_SIZE)
+			curpage--;
+
                 result = nfs_direct_read_rpc(file, &args);
 
-		for (i = first; i < last; i++) {
+		for (i = first; i <= last; i++) {
 			flush_dcache_page(iobuf->maplist[i]);
 			kunmap(iobuf->maplist[i]);
 		}
@@ -258,10 +270,11 @@
                         request = wsize;
 		args.count = request;
 		args.offset = offset;
+		args.nriov = 0;
 
 		starting_offset = iobuf->offset;
 		first = last = curpage;
-		while (curpage < iobuf->nr_pages) {
+		while ((request > 0) && (curpage < iobuf->nr_pages)) {
 			struct page *page = iobuf->maplist[curpage];
 
 			if (!page)
@@ -273,16 +286,27 @@
 				iovec->iov_len = request;
 
 			request -= iovec->iov_len;
-			starting_offset = 0;	/* zero after the first page */
+			/* zero after the first iov */
+			starting_offset = 0;
 			last = curpage;
 			curpage++;
 			iovec++;
 			args.nriov++;
 		}
 
+		/*
+		 * if the last iov didn't end at a page boundary, make
+		 * curpage point back to it.  if we come back around for
+		 * another iovec construction, we then pick up the
+		 * remaining contents of the incomplete page.
+		 */
+		iovec--;
+		if (iovec->iov_len < PAGE_SIZE)
+			curpage--;
+
                 result = nfs_direct_write_rpc(file, &args, &ret_verf);
 
-		for (i = first; i < last; i++)
+		for (i = first; i <= last; i++)
 			kunmap(iobuf->maplist[i]);
 
                 if (result < 0) {
diff -druN Linux-2.4.18-pre3/include/linux/sunrpc/xprt.h linux-2.4.18-pre3/include/linux/sunrpc/xprt.h
--- Linux-2.4.18-pre3/include/linux/sunrpc/xprt.h	Tue Jan 22 16:18:53 2002
+++ linux-2.4.18-pre3/include/linux/sunrpc/xprt.h	Wed Feb 20 13:12:00 2002
@@ -17,7 +17,7 @@
 /*
  * Maximum number of iov's we use.
  */
-#define MAX_IOVEC	10
+#define MAX_IOVEC	12
 
 /*
  * The transport code maintains an estimate on the maximum number of out-
