diff -urpN -X /home/fletch/.diff.exclude 711-fs_aio_1_retry/include/linux/pagemap.h 712-fs_aio_2_read/include/linux/pagemap.h
--- 711-fs_aio_1_retry/include/linux/pagemap.h	Sat May 10 19:03:12 2003
+++ 712-fs_aio_2_read/include/linux/pagemap.h	Sat May 10 19:47:42 2003
@@ -144,6 +144,16 @@ static inline void lock_page(struct page
 	if (TestSetPageLocked(page))
 		__lock_page(page);
 }
+
+extern int FASTCALL(__lock_page_wq(struct page *page, wait_queue_t *wait));
+static inline int lock_page_wq(struct page *page, wait_queue_t *wait)
+{
+	if (TestSetPageLocked(page))
+		return __lock_page_wq(page, wait);
+	else
+		return 0;
+}
+
 	
 /*
  * This is exported only for wait_on_page_locked/wait_on_page_writeback.
@@ -162,6 +172,15 @@ static inline void wait_on_page_locked(s
 {
 	if (PageLocked(page))
 		wait_on_page_bit(page, PG_locked);
+}
+
+extern int FASTCALL(wait_on_page_bit_wq(struct page *page, int bit_nr, 
+	wait_queue_t *wait));
+static inline int wait_on_page_locked_wq(struct page *page, wait_queue_t *wait)
+{
+	if (PageLocked(page))
+		return wait_on_page_bit_wq(page, PG_locked, wait);
+	return 0;
 }
 
 /* 
diff -urpN -X /home/fletch/.diff.exclude 711-fs_aio_1_retry/mm/filemap.c 712-fs_aio_2_read/mm/filemap.c
--- 711-fs_aio_1_retry/mm/filemap.c	Sat May 10 18:42:19 2003
+++ 712-fs_aio_2_read/mm/filemap.c	Sat May 10 19:47:42 2003
@@ -270,19 +270,32 @@ static wait_queue_head_t *page_waitqueue
 	return &zone->wait_table[hash_ptr(page, zone->wait_table_bits)];
 }
 
-void wait_on_page_bit(struct page *page, int bit_nr)
+int wait_on_page_bit_wq(struct page *page, int bit_nr, wait_queue_t *wait)
 {
 	wait_queue_head_t *waitqueue = page_waitqueue(page);
-	DEFINE_WAIT(wait);
+	DEFINE_WAIT(local_wait);
 
+	if (!wait)
+		wait = &local_wait;
+		
 	do {
-		prepare_to_wait(waitqueue, &wait, TASK_UNINTERRUPTIBLE);
+		prepare_to_wait(waitqueue, wait, TASK_UNINTERRUPTIBLE);
 		if (test_bit(bit_nr, &page->flags)) {
 			sync_page(page);
+			if (!is_sync_wait(wait))
+				return -EIOCBRETRY;
 			io_schedule();
 		}
 	} while (test_bit(bit_nr, &page->flags));
-	finish_wait(waitqueue, &wait);
+	finish_wait(waitqueue, wait);
+
+	return 0;
+}
+EXPORT_SYMBOL(wait_on_page_bit_wq);
+
+void wait_on_page_bit(struct page *page, int bit_nr)
+{
+	wait_on_page_bit_wq(page, bit_nr, NULL);
 }
 EXPORT_SYMBOL(wait_on_page_bit);
 
@@ -338,19 +351,31 @@ EXPORT_SYMBOL(end_page_writeback);
  * chances are that on the second loop, the block layer's plug list is empty,
  * so sync_page() will then return in state TASK_UNINTERRUPTIBLE.
  */
-void __lock_page(struct page *page)
+int __lock_page_wq(struct page *page, wait_queue_t *wait)
 {
 	wait_queue_head_t *wqh = page_waitqueue(page);
-	DEFINE_WAIT(wait);
+	DEFINE_WAIT(local_wait);
 
+	if (!wait)
+		wait = &local_wait;
+		
 	while (TestSetPageLocked(page)) {
-		prepare_to_wait(wqh, &wait, TASK_UNINTERRUPTIBLE);
+		prepare_to_wait(wqh, wait, TASK_UNINTERRUPTIBLE);
 		if (PageLocked(page)) {
 			sync_page(page);
+			if (!is_sync_wait(wait))
+				return -EIOCBRETRY;
 			io_schedule();
 		}
 	}
-	finish_wait(wqh, &wait);
+	finish_wait(wqh, wait);
+	return 0;
+}
+EXPORT_SYMBOL(__lock_page_wq);
+
+void __lock_page(struct page *page)
+{
+	__lock_page_wq(page, NULL);	
 }
 EXPORT_SYMBOL(__lock_page);
 
@@ -623,7 +648,13 @@ page_not_up_to_date:
 			goto page_ok;
 
 		/* Get exclusive access to the page ... */
-		lock_page(page);
+		
+		if (lock_page_wq(page, current->io_wait)) {
+			pr_debug("queued lock page \n");
+			error = -EIOCBRETRY;
+			/* TBD: should we hold on to the cached page ? */
+			goto sync_error;
+		}
 
 		/* Did it get unhashed before we got the lock? */
 		if (!page->mapping) {
@@ -645,12 +676,19 @@ readpage:
 		if (!error) {
 			if (PageUptodate(page))
 				goto page_ok;
-			wait_on_page_locked(page);
+			if (wait_on_page_locked_wq(page, current->io_wait)) {
+				pr_debug("queued wait_on_page \n");
+				error = -EIOCBRETRY;
+				/*TBD:should we hold on to the cached page ?*/
+				goto sync_error;
+			}
+			
 			if (PageUptodate(page))
 				goto page_ok;
 			error = -EIO;
 		}
 
+sync_error:
 		/* UHHUH! A synchronous read error occurred. Report it */
 		desc->error = error;
 		page_cache_release(page);
@@ -821,6 +859,10 @@ generic_file_read(struct file *filp, cha
 	struct kiocb kiocb;
 	ssize_t ret;
 
+	if (current->io_wait != NULL) {
+		printk("current->io_wait != NULL\n");
+		dump_stack();
+	}
 	init_sync_kiocb(&kiocb, filp);
 	ret = __generic_file_aio_read(&kiocb, &local_iov, 1, ppos);
 	if (-EIOCBQUEUED == ret)
@@ -853,6 +895,7 @@ ssize_t generic_file_sendfile(struct fil
 {
 	read_descriptor_t desc;
 
+	BUG_ON(current->io_wait != NULL);
 	if (!count)
 		return 0;