diff -purN -X /home/mbligh/.diff.exclude 560-aio-O_SYNC-short-write-fix/fs/aio.c 570-aio-read-immediate/fs/aio.c
--- 560-aio-O_SYNC-short-write-fix/fs/aio.c	2004-02-28 11:21:41.000000000 -0800
+++ 570-aio-read-immediate/fs/aio.c	2004-02-28 11:22:11.000000000 -0800
@@ -1278,6 +1278,8 @@ asmlinkage long sys_io_destroy(aio_conte
 static ssize_t aio_pread(struct kiocb *iocb)
 {
 	struct file *file = iocb->ki_filp;
+	struct address_space *mapping = file->f_mapping;
+	struct inode *inode = mapping->host;
 	ssize_t ret = 0;
 
 	ret = file->f_op->aio_read(iocb, iocb->ki_buf,
@@ -1290,8 +1292,14 @@ static ssize_t aio_pread(struct kiocb *i
 	if (ret > 0) {
 		iocb->ki_buf += ret;
 		iocb->ki_left -= ret;
-
-		ret = -EIOCBRETRY;
+		/* 
+		 * For pipes and sockets we return once we have
+		 * some data; for regular files we retry till we
+		 * complete the entire read or find that we can't
+		 * read any more data (e.g short reads).
+		 */
+		if (!S_ISFIFO(inode->i_mode) && !S_ISSOCK(inode->i_mode))
+			ret = -EIOCBRETRY;
 	}
 
 	/* This means we must have transferred all that we could */