md/bitmap: always wait for writes on unplug.
authorNeilBrown <neilb@suse.de>
Tue, 9 Sep 2014 04:13:51 +0000 (14:13 +1000)
committerNeilBrown <neilb@suse.de>
Wed, 8 Oct 2014 23:07:04 +0000 (10:07 +1100)
If two threads call bitmap_unplug at the same time, then
one might schedule all the writes, and the other might
decide that it doesn't need to wait.  But really it does.

It rarely hurts to wait when it isn't absolutely necessary,
and the current code doesn't really focus on 'absolutely necessary'
anyway.  So just wait always.

This can potentially lead to data corruption if a crash happens
at an awkward time and data was written before the bitmap was
updated.  It is very unlikely, but this should go to -stable
just to be safe.  Appropriate for any -stable.

Signed-off-by: NeilBrown <neilb@suse.de>
Cc: stable@vger.kernel.org (please delay until 3.18 is released)
drivers/md/bitmap.c

index 67f8b31e205491ebea3b02a5a28efedce2c26c8d..da3604e73e8abafbd8e127dbfc659360d23310e5 100644 (file)
@@ -879,7 +879,6 @@ void bitmap_unplug(struct bitmap *bitmap)
 {
        unsigned long i;
        int dirty, need_write;
-       int wait = 0;
 
        if (!bitmap || !bitmap->storage.filemap ||
            test_bit(BITMAP_STALE, &bitmap->flags))
@@ -897,16 +896,13 @@ void bitmap_unplug(struct bitmap *bitmap)
                        clear_page_attr(bitmap, i, BITMAP_PAGE_PENDING);
                        write_page(bitmap, bitmap->storage.filemap[i], 0);
                }
-               if (dirty)
-                       wait = 1;
-       }
-       if (wait) { /* if any writes were performed, we need to wait on them */
-               if (bitmap->storage.file)
-                       wait_event(bitmap->write_wait,
-                                  atomic_read(&bitmap->pending_writes)==0);
-               else
-                       md_super_wait(bitmap->mddev);
        }
+       if (bitmap->storage.file)
+               wait_event(bitmap->write_wait,
+                          atomic_read(&bitmap->pending_writes)==0);
+       else
+               md_super_wait(bitmap->mddev);
+
        if (test_bit(BITMAP_WRITE_ERROR, &bitmap->flags))
                bitmap_file_kick(bitmap);
 }
This page took 0.025655 seconds and 5 git commands to generate.