summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2014-09-09 14:13:51 +1000
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2015-01-08 09:58:15 -0800
commit15225559b32c87614b39713875f6d799df05c9b0 (patch)
tree8ddf3cca54744707b05b28011ef3176715204419
parent9d2b6132e6963ccdfb15a4570984382425b96529 (diff)
md/bitmap: always wait for writes on unplug.
commit 4b5060ddae2b03c5387321fafc089d242225697a upstream. 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> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/md/bitmap.c16
1 files changed, 6 insertions, 10 deletions
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c
index 5a2c75499824..a79cbd6038f6 100644
--- a/drivers/md/bitmap.c
+++ b/drivers/md/bitmap.c
@@ -883,7 +883,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))
@@ -901,16 +900,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);
}