aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/block')
-rw-r--r--drivers/block/drbd/drbd_bitmap.c38
1 files changed, 22 insertions, 16 deletions
diff --git a/drivers/block/drbd/drbd_bitmap.c b/drivers/block/drbd/drbd_bitmap.c
index 314a3632303b..25428bc28476 100644
--- a/drivers/block/drbd/drbd_bitmap.c
+++ b/drivers/block/drbd/drbd_bitmap.c
@@ -897,7 +897,7 @@ void drbd_bm_clear_all(struct drbd_conf *mdev)
897struct bm_aio_ctx { 897struct bm_aio_ctx {
898 struct drbd_conf *mdev; 898 struct drbd_conf *mdev;
899 atomic_t in_flight; 899 atomic_t in_flight;
900 wait_queue_head_t io_wait; 900 struct completion done;
901 unsigned flags; 901 unsigned flags;
902#define BM_AIO_COPY_PAGES 1 902#define BM_AIO_COPY_PAGES 1
903 int error; 903 int error;
@@ -948,7 +948,7 @@ static void bm_async_io_complete(struct bio *bio, int error)
948 bio_put(bio); 948 bio_put(bio);
949 949
950 if (atomic_dec_and_test(&ctx->in_flight)) 950 if (atomic_dec_and_test(&ctx->in_flight))
951 wake_up(&ctx->io_wait); 951 complete(&ctx->done);
952} 952}
953 953
954static void bm_page_io_async(struct bm_aio_ctx *ctx, int page_nr, int rw) __must_hold(local) 954static void bm_page_io_async(struct bm_aio_ctx *ctx, int page_nr, int rw) __must_hold(local)
@@ -1009,8 +1009,12 @@ static void bm_page_io_async(struct bm_aio_ctx *ctx, int page_nr, int rw) __must
1009 */ 1009 */
1010static int bm_rw(struct drbd_conf *mdev, int rw, unsigned lazy_writeout_upper_idx) __must_hold(local) 1010static int bm_rw(struct drbd_conf *mdev, int rw, unsigned lazy_writeout_upper_idx) __must_hold(local)
1011{ 1011{
1012 struct bm_aio_ctx ctx = 1012 struct bm_aio_ctx ctx = {
1013 { .flags = lazy_writeout_upper_idx ? BM_AIO_COPY_PAGES : 0 }; 1013 .mdev = mdev,
1014 .in_flight = ATOMIC_INIT(1),
1015 .done = COMPLETION_INITIALIZER_ONSTACK(ctx.done),
1016 .flags = lazy_writeout_upper_idx ? BM_AIO_COPY_PAGES : 0,
1017 };
1014 struct drbd_bitmap *b = mdev->bitmap; 1018 struct drbd_bitmap *b = mdev->bitmap;
1015 int num_pages, i, count = 0; 1019 int num_pages, i, count = 0;
1016 unsigned long now; 1020 unsigned long now;
@@ -1031,10 +1035,6 @@ static int bm_rw(struct drbd_conf *mdev, int rw, unsigned lazy_writeout_upper_id
1031 num_pages = b->bm_number_of_pages; 1035 num_pages = b->bm_number_of_pages;
1032 1036
1033 now = jiffies; 1037 now = jiffies;
1034 ctx.mdev = mdev;
1035 atomic_set(&ctx.in_flight, 1); /* one extra ref */
1036 init_waitqueue_head(&ctx.io_wait);
1037 ctx.error = 0;
1038 1038
1039 /* let the layers below us try to merge these bios... */ 1039 /* let the layers below us try to merge these bios... */
1040 for (i = 0; i < num_pages; i++) { 1040 for (i = 0; i < num_pages; i++) {
@@ -1060,8 +1060,13 @@ static int bm_rw(struct drbd_conf *mdev, int rw, unsigned lazy_writeout_upper_id
1060 cond_resched(); 1060 cond_resched();
1061 } 1061 }
1062 1062
1063 atomic_dec(&ctx.in_flight); /* drop the extra ref */ 1063 /*
1064 wait_event(ctx.io_wait, atomic_read(&ctx.in_flight) == 0); 1064 * We initialize ctx.in_flight to one to make sure bm_async_io_complete
1065 * will not complete() early, and decrement / test it here. If there
1066 * are still some bios in flight, we need to wait for them here.
1067 */
1068 if (!atomic_dec_and_test(&ctx.in_flight))
1069 wait_for_completion(&ctx.done);
1065 dev_info(DEV, "bitmap %s of %u pages took %lu jiffies\n", 1070 dev_info(DEV, "bitmap %s of %u pages took %lu jiffies\n",
1066 rw == WRITE ? "WRITE" : "READ", 1071 rw == WRITE ? "WRITE" : "READ",
1067 count, jiffies - now); 1072 count, jiffies - now);
@@ -1133,19 +1138,20 @@ int drbd_bm_write_lazy(struct drbd_conf *mdev, unsigned upper_idx) __must_hold(l
1133 */ 1138 */
1134int drbd_bm_write_page(struct drbd_conf *mdev, unsigned int idx) __must_hold(local) 1139int drbd_bm_write_page(struct drbd_conf *mdev, unsigned int idx) __must_hold(local)
1135{ 1140{
1136 struct bm_aio_ctx ctx = { .flags = BM_AIO_COPY_PAGES, }; 1141 struct bm_aio_ctx ctx = {
1142 .mdev = mdev,
1143 .in_flight = ATOMIC_INIT(1),
1144 .done = COMPLETION_INITIALIZER_ONSTACK(ctx.done),
1145 .flags = BM_AIO_COPY_PAGES,
1146 };
1137 1147
1138 if (bm_test_page_unchanged(mdev->bitmap->bm_pages[idx])) { 1148 if (bm_test_page_unchanged(mdev->bitmap->bm_pages[idx])) {
1139 dynamic_dev_dbg(DEV, "skipped bm page write for idx %u\n", idx); 1149 dynamic_dev_dbg(DEV, "skipped bm page write for idx %u\n", idx);
1140 return 0; 1150 return 0;
1141 } 1151 }
1142 1152
1143 ctx.mdev = mdev;
1144 atomic_set(&ctx.in_flight, 1);
1145 init_waitqueue_head(&ctx.io_wait);
1146
1147 bm_page_io_async(&ctx, idx, WRITE_SYNC); 1153 bm_page_io_async(&ctx, idx, WRITE_SYNC);
1148 wait_event(ctx.io_wait, atomic_read(&ctx.in_flight) == 0); 1154 wait_for_completion(&ctx.done);
1149 1155
1150 if (ctx.error) 1156 if (ctx.error)
1151 drbd_chk_io_error(mdev, 1, true); 1157 drbd_chk_io_error(mdev, 1, true);