OK, here's a sample of what I meant.
Regards
Suparna
diff -pur linux-2.5.66/include/linux/aio.h linux-2.5.66aio/include/linux/aio.h
--- linux-2.5.66/include/linux/aio.h Tue Mar 25 03:29:54 2003
+++ linux-2.5.66aio/include/linux/aio.h Thu Apr 3 17:14:08 2003
@@ -151,6 +161,14 @@ extern void FASTCALL(exit_aio(struct mm_
#define get_ioctx(kioctx) do { if (unlikely(atomic_read(&(kioctx)->users) <= 0)) BUG(); atomic_inc(&(kioctx)->users); } while (0)
#define put_ioctx(kioctx) do { if (unlikely(atomic_dec_and_test(&(kioctx)->users))) __put_ioctx(kioctx); else if (unlikely(atomic_read(&(kioctx)->users) < 0)) BUG(); } while (0)
+#define do_sync_op(op) do { \
+ DEFINE_WAIT(sync_wait); \
+ wait_queue_t *wait = current->io_wait; \
+ current->io_wait = &sync_wait; \
+ op; \
+ current->io_wait = wait; \
+ } while (0);
+
#include <linux/aio_abi.h>
static inline struct kiocb *list_kiocb(struct list_head *h)
diff -pur linux-2.5.66/include/linux/init_task.h linux-2.5.66aio/include/linux/init_task.h
--- linux-2.5.66/include/linux/init_task.h Tue Mar 25 03:30:00 2003
+++ linux-2.5.66aio/include/linux/init_task.h Thu Apr 3 13:36:07 2003
@@ -103,6 +103,7 @@
.alloc_lock = SPIN_LOCK_UNLOCKED, \
.switch_lock = SPIN_LOCK_UNLOCKED, \
.journal_info = NULL, \
+ .io_wait = NULL, \
}
diff -pur linux-2.5.66/include/linux/sched.h linux-2.5.66aio/include/linux/sched.h
--- linux-2.5.66/include/linux/sched.h Tue Mar 25 03:30:00 2003
+++ linux-2.5.66aio/include/linux/sched.h Thu Apr 3 13:18:28 2003
@@ -438,6 +438,8 @@ struct task_struct {
unsigned long ptrace_message;
siginfo_t *last_siginfo; /* For ptrace use. */
+/* current io wait handle */
+ wait_queue_t *io_wait;
};
extern void __put_task_struct(struct task_struct *tsk);
diff -pur linux-2.5.66/include/linux/wait.h linux-2.5.66aio/include/linux/wait.h
--- linux-2.5.66/include/linux/wait.h Tue Mar 25 03:30:44 2003
+++ linux-2.5.66aio/include/linux/wait.h Thu Apr 3 13:51:11 2003
@@ -80,6 +80,8 @@ static inline int waitqueue_active(wait_
return !list_empty(&q->task_list);
}
+#define is_sync_wait(wait) ((wait)->task != NULL)
+
extern void FASTCALL(add_wait_queue(wait_queue_head_t *q, wait_queue_t * wait));
extern void FASTCALL(add_wait_queue_exclusive(wait_queue_head_t *q, wait_queue_t * wait));
extern void FASTCALL(remove_wait_queue(wait_queue_head_t *q, wait_queue_t * wait));
diff -pur linux-2.5.66/kernel/fork.c linux-2.5.66aio/kernel/fork.c
--- linux-2.5.66/kernel/fork.c Tue Mar 25 03:30:00 2003
+++ linux-2.5.66aio/kernel/fork.c Thu Apr 3 13:35:21 2003
@@ -139,8 +139,9 @@ void remove_wait_queue(wait_queue_head_t
void prepare_to_wait(wait_queue_head_t *q, wait_queue_t *wait, int state)
{
unsigned long flags;
-
- __set_current_state(state);
+
+ if (is_sync_wait(wait))
+ __set_current_state(state);
wait->flags &= ~WQ_FLAG_EXCLUSIVE;
spin_lock_irqsave(&q->lock, flags);
if (list_empty(&wait->task_list))
@@ -153,7 +154,8 @@ prepare_to_wait_exclusive(wait_queue_hea
{
unsigned long flags;
- __set_current_state(state);
+ if (is_sync_wait(wait))
+ __set_current_state(state);
wait->flags |= WQ_FLAG_EXCLUSIVE;
spin_lock_irqsave(&q->lock, flags);
if (list_empty(&wait->task_list))
@@ -856,6 +858,7 @@ static struct task_struct *copy_process(
p->lock_depth = -1; /* -1 = no lock */
p->start_time = get_jiffies_64();
p->security = NULL;
+ p->io_wait = NULL;
retval = -ENOMEM;
if (security_task_alloc(p))
diff -pur linux-2.5.66/mm/filemap.c linux-2.5.66aio/mm/filemap.c
--- linux-2.5.66/mm/filemap.c Tue Mar 25 03:30:15 2003
+++ linux-2.5.66aio/mm/filemap.c Thu Apr 3 16:54:33 2003
@@ -254,19 +254,29 @@ 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_async(struct page *page, int bit_nr)
{
wait_queue_head_t *waitqueue = page_waitqueue(page);
- DEFINE_WAIT(wait);
-
+ wait_queue_t *wait = current->io_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 -EIOCBQUEUED;
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_async);
+
+void wait_on_page_bit(struct page *page, int bit_nr)
+{
+ do_sync_op(wait_on_page_bit_async(page, bit_nr));
}
EXPORT_SYMBOL(wait_on_page_bit);
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/