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 */