]> git.hungrycats.org Git - linux/commitdiff
[PATCH] dm-ioctl: replace dm_[add|remove]_wait_queue() with dm_wait_event()
authorAndrew Morton <akpm@osdl.org>
Sat, 29 May 2004 03:57:19 +0000 (20:57 -0700)
committerLinus Torvalds <torvalds@ppc970.osdl.org>
Sat, 29 May 2004 03:57:19 +0000 (20:57 -0700)
From: Kevin Corry <kevcorry@us.ibm.com>

Some testing of DM multipath has turned up a problem with the DEVICE_WAIT
command.  In the tests, while performing a DEVICE_WAIT on a multipath device,
the command sometimes returns immediately, even though the event-number is
correct and no path-failure has occurred to trigger an event.  The problem was
tracked down to the call to schedule() in dev_wait(), which would return even
though it was not woken up by a DM table event.

This patch moves the responsibility for waiting from the ioctl interface into
the core driver, and uses wait_event_interruptible() instead of relying on
wait-queues and schedule().

Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
drivers/md/dm-ioctl.c
drivers/md/dm.c
drivers/md/dm.h

index 814633226065bb00e401fa00b5c313b9fb59b2c0..ebfa4321f2ed02e0b489ca8a36746e1053e4b7fe 100644 (file)
@@ -850,7 +850,6 @@ static int dev_wait(struct dm_ioctl *param, size_t param_size)
        int r;
        struct mapped_device *md;
        struct dm_table *table;
-       DECLARE_WAITQUEUE(wq, current);
 
        md = find_device(param);
        if (!md)
@@ -859,12 +858,10 @@ static int dev_wait(struct dm_ioctl *param, size_t param_size)
        /*
         * Wait for a notification event
         */
-       set_current_state(TASK_INTERRUPTIBLE);
-       if (!dm_add_wait_queue(md, &wq, param->event_nr)) {
-               schedule();
-               dm_remove_wait_queue(md, &wq);
+       if (dm_wait_event(md, param->event_nr)) {
+               r = -ERESTARTSYS;
+               goto out;
        }
-       set_current_state(TASK_RUNNING);
 
        /*
         * The userland program is going to want to know what
index a347d88d426af4db02168543244fed960a686417..c2d115fcf4f3dd67ffa8388fde379c6861ff4d67 100644 (file)
@@ -80,7 +80,7 @@ struct mapped_device {
        /*
         * Event handling.
         */
-       uint32_t event_nr;
+       atomic_t event_nr;
        wait_queue_head_t eventq;
 
        /*
@@ -685,6 +685,7 @@ static struct mapped_device *alloc_dev(unsigned int minor, int persistent)
        init_rwsem(&md->lock);
        rwlock_init(&md->map_lock);
        atomic_set(&md->holders, 1);
+       atomic_set(&md->event_nr, 0);
 
        md->queue = blk_alloc_queue(GFP_KERNEL);
        if (!md->queue)
@@ -754,10 +755,8 @@ static void event_callback(void *context)
 {
        struct mapped_device *md = (struct mapped_device *) context;
 
-       down_write(&md->lock);
-       md->event_nr++;
+       atomic_inc(&md->event_nr);;
        wake_up(&md->eventq);
-       up_write(&md->lock);
 }
 
 static void __set_size(struct gendisk *disk, sector_t size)
@@ -1055,35 +1054,13 @@ int dm_resume(struct mapped_device *md)
  *---------------------------------------------------------------*/
 uint32_t dm_get_event_nr(struct mapped_device *md)
 {
-       uint32_t r;
-
-       down_read(&md->lock);
-       r = md->event_nr;
-       up_read(&md->lock);
-
-       return r;
-}
-
-int dm_add_wait_queue(struct mapped_device *md, wait_queue_t *wq,
-                     uint32_t event_nr)
-{
-       down_write(&md->lock);
-       if (event_nr != md->event_nr) {
-               up_write(&md->lock);
-               return 1;
-       }
-
-       add_wait_queue(&md->eventq, wq);
-       up_write(&md->lock);
-
-       return 0;
+       return atomic_read(&md->event_nr);
 }
 
-void dm_remove_wait_queue(struct mapped_device *md, wait_queue_t *wq)
+int dm_wait_event(struct mapped_device *md, int event_nr)
 {
-       down_write(&md->lock);
-       remove_wait_queue(&md->eventq, wq);
-       up_write(&md->lock);
+       return wait_event_interruptible(md->eventq,
+                       (event_nr != atomic_read(&md->event_nr)));
 }
 
 /*
index 34bf0e7cceb29c90633560e2b8dd1cea21dd24b5..93dd264b1630c66af39fd45e5c0bff2840c6626f 100644 (file)
@@ -81,9 +81,7 @@ struct dm_table *dm_get_table(struct mapped_device *md);
  * Event functions.
  */
 uint32_t dm_get_event_nr(struct mapped_device *md);
-int dm_add_wait_queue(struct mapped_device *md, wait_queue_t *wq,
-                     uint32_t event_nr);
-void dm_remove_wait_queue(struct mapped_device *md, wait_queue_t *wq);
+int dm_wait_event(struct mapped_device *md, int event_nr);
 
 /*
  * Info functions.