aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/drbd/drbd_bitmap.c
diff options
context:
space:
mode:
authorPhilipp Reisner <philipp.reisner@linbit.com>2011-06-27 08:56:52 -0400
committerPhilipp Reisner <philipp.reisner@linbit.com>2012-05-09 04:37:19 -0400
commitd1f3779bbeae70b9552c9ac70d6ec8c4d3545615 (patch)
tree306089519ac84f24e0674de930931e21f3859d6a /drivers/block/drbd/drbd_bitmap.c
parentb2057629ea96c33e4ae38102ecd0f27ed9a3c3ef (diff)
drbd: Added a kref to bm_aio_ctx
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com> Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
Diffstat (limited to 'drivers/block/drbd/drbd_bitmap.c')
-rw-r--r--drivers/block/drbd/drbd_bitmap.c84
1 files changed, 59 insertions, 25 deletions
diff --git a/drivers/block/drbd/drbd_bitmap.c b/drivers/block/drbd/drbd_bitmap.c
index 3030201c69d8..a2c337b38d6e 100644
--- a/drivers/block/drbd/drbd_bitmap.c
+++ b/drivers/block/drbd/drbd_bitmap.c
@@ -890,8 +890,16 @@ struct bm_aio_ctx {
890 unsigned flags; 890 unsigned flags;
891#define BM_AIO_COPY_PAGES 1 891#define BM_AIO_COPY_PAGES 1
892 int error; 892 int error;
893 struct kref kref;
893}; 894};
894 895
896static void bm_aio_ctx_destroy(struct kref *kref)
897{
898 struct bm_aio_ctx *ctx = container_of(kref, struct bm_aio_ctx, kref);
899
900 kfree(ctx);
901}
902
895/* bv_page may be a copy, or may be the original */ 903/* bv_page may be a copy, or may be the original */
896static void bm_async_io_complete(struct bio *bio, int error) 904static void bm_async_io_complete(struct bio *bio, int error)
897{ 905{
@@ -936,8 +944,10 @@ static void bm_async_io_complete(struct bio *bio, int error)
936 944
937 bio_put(bio); 945 bio_put(bio);
938 946
939 if (atomic_dec_and_test(&ctx->in_flight)) 947 if (atomic_dec_and_test(&ctx->in_flight)) {
940 complete(&ctx->done); 948 complete(&ctx->done);
949 kref_put(&ctx->kref, &bm_aio_ctx_destroy);
950 }
941} 951}
942 952
943static void bm_page_io_async(struct bm_aio_ctx *ctx, int page_nr, int rw) __must_hold(local) 953static void bm_page_io_async(struct bm_aio_ctx *ctx, int page_nr, int rw) __must_hold(local)
@@ -1001,12 +1011,7 @@ static void bm_page_io_async(struct bm_aio_ctx *ctx, int page_nr, int rw) __must
1001 */ 1011 */
1002static int bm_rw(struct drbd_conf *mdev, int rw, unsigned lazy_writeout_upper_idx) __must_hold(local) 1012static int bm_rw(struct drbd_conf *mdev, int rw, unsigned lazy_writeout_upper_idx) __must_hold(local)
1003{ 1013{
1004 struct bm_aio_ctx ctx = { 1014 struct bm_aio_ctx *ctx;
1005 .mdev = mdev,
1006 .in_flight = ATOMIC_INIT(1),
1007 .done = COMPLETION_INITIALIZER_ONSTACK(ctx.done),
1008 .flags = lazy_writeout_upper_idx ? BM_AIO_COPY_PAGES : 0,
1009 };
1010 struct drbd_bitmap *b = mdev->bitmap; 1015 struct drbd_bitmap *b = mdev->bitmap;
1011 int num_pages, i, count = 0; 1016 int num_pages, i, count = 0;
1012 unsigned long now; 1017 unsigned long now;
@@ -1021,7 +1026,21 @@ static int bm_rw(struct drbd_conf *mdev, int rw, unsigned lazy_writeout_upper_id
1021 * For lazy writeout, we don't care for ongoing changes to the bitmap, 1026 * For lazy writeout, we don't care for ongoing changes to the bitmap,
1022 * as we submit copies of pages anyways. 1027 * as we submit copies of pages anyways.
1023 */ 1028 */
1024 if (!ctx.flags) 1029
1030 ctx = kmalloc(sizeof(struct bm_aio_ctx), GFP_KERNEL);
1031 if (!ctx)
1032 return -ENOMEM;
1033
1034 *ctx = (struct bm_aio_ctx) {
1035 .mdev = mdev,
1036 .in_flight = ATOMIC_INIT(1),
1037 .done = COMPLETION_INITIALIZER(ctx->done),
1038 .flags = lazy_writeout_upper_idx ? BM_AIO_COPY_PAGES : 0,
1039 .error = 0,
1040 .kref = { ATOMIC_INIT(2) },
1041 };
1042
1043 if (!ctx->flags)
1025 WARN_ON(!(BM_LOCKED_MASK & b->bm_flags)); 1044 WARN_ON(!(BM_LOCKED_MASK & b->bm_flags));
1026 1045
1027 num_pages = b->bm_number_of_pages; 1046 num_pages = b->bm_number_of_pages;
@@ -1046,27 +1065,28 @@ static int bm_rw(struct drbd_conf *mdev, int rw, unsigned lazy_writeout_upper_id
1046 continue; 1065 continue;
1047 } 1066 }
1048 } 1067 }
1049 atomic_inc(&ctx.in_flight); 1068 atomic_inc(&ctx->in_flight);
1050 bm_page_io_async(&ctx, i, rw); 1069 bm_page_io_async(ctx, i, rw);
1051 ++count; 1070 ++count;
1052 cond_resched(); 1071 cond_resched();
1053 } 1072 }
1054 1073
1055 /* 1074 /*
1056 * We initialize ctx.in_flight to one to make sure bm_async_io_complete 1075 * We initialize ctx->in_flight to one to make sure bm_async_io_complete
1057 * will not complete() early, and decrement / test it here. If there 1076 * will not complete() early, and decrement / test it here. If there
1058 * are still some bios in flight, we need to wait for them here. 1077 * are still some bios in flight, we need to wait for them here.
1059 */ 1078 */
1060 if (!atomic_dec_and_test(&ctx.in_flight)) 1079 if (!atomic_dec_and_test(&ctx->in_flight))
1061 wait_for_completion(&ctx.done); 1080 wait_for_completion(&ctx->done);
1081
1062 dev_info(DEV, "bitmap %s of %u pages took %lu jiffies\n", 1082 dev_info(DEV, "bitmap %s of %u pages took %lu jiffies\n",
1063 rw == WRITE ? "WRITE" : "READ", 1083 rw == WRITE ? "WRITE" : "READ",
1064 count, jiffies - now); 1084 count, jiffies - now);
1065 1085
1066 if (ctx.error) { 1086 if (ctx->error) {
1067 dev_alert(DEV, "we had at least one MD IO ERROR during bitmap IO\n"); 1087 dev_alert(DEV, "we had at least one MD IO ERROR during bitmap IO\n");
1068 drbd_chk_io_error(mdev, 1, true); 1088 drbd_chk_io_error(mdev, 1, true);
1069 err = -EIO; /* ctx.error ? */ 1089 err = -EIO; /* ctx->error ? */
1070 } 1090 }
1071 1091
1072 now = jiffies; 1092 now = jiffies;
@@ -1082,6 +1102,8 @@ static int bm_rw(struct drbd_conf *mdev, int rw, unsigned lazy_writeout_upper_id
1082 dev_info(DEV, "%s (%lu bits) marked out-of-sync by on disk bit-map.\n", 1102 dev_info(DEV, "%s (%lu bits) marked out-of-sync by on disk bit-map.\n",
1083 ppsize(ppb, now << (BM_BLOCK_SHIFT-10)), now); 1103 ppsize(ppb, now << (BM_BLOCK_SHIFT-10)), now);
1084 1104
1105 kref_put(&ctx->kref, &bm_aio_ctx_destroy);
1106
1085 return err; 1107 return err;
1086} 1108}
1087 1109
@@ -1130,28 +1152,40 @@ int drbd_bm_write_lazy(struct drbd_conf *mdev, unsigned upper_idx) __must_hold(l
1130 */ 1152 */
1131int drbd_bm_write_page(struct drbd_conf *mdev, unsigned int idx) __must_hold(local) 1153int drbd_bm_write_page(struct drbd_conf *mdev, unsigned int idx) __must_hold(local)
1132{ 1154{
1133 struct bm_aio_ctx ctx = { 1155 struct bm_aio_ctx *ctx;
1134 .mdev = mdev, 1156 int err;
1135 .in_flight = ATOMIC_INIT(1),
1136 .done = COMPLETION_INITIALIZER_ONSTACK(ctx.done),
1137 .flags = BM_AIO_COPY_PAGES,
1138 };
1139 1157
1140 if (bm_test_page_unchanged(mdev->bitmap->bm_pages[idx])) { 1158 if (bm_test_page_unchanged(mdev->bitmap->bm_pages[idx])) {
1141 dynamic_dev_dbg(DEV, "skipped bm page write for idx %u\n", idx); 1159 dynamic_dev_dbg(DEV, "skipped bm page write for idx %u\n", idx);
1142 return 0; 1160 return 0;
1143 } 1161 }
1144 1162
1145 bm_page_io_async(&ctx, idx, WRITE_SYNC); 1163 ctx = kmalloc(sizeof(struct bm_aio_ctx), GFP_KERNEL);
1146 wait_for_completion(&ctx.done); 1164 if (!ctx)
1165 return -ENOMEM;
1166
1167 *ctx = (struct bm_aio_ctx) {
1168 .mdev = mdev,
1169 .in_flight = ATOMIC_INIT(1),
1170 .done = COMPLETION_INITIALIZER(ctx->done),
1171 .flags = BM_AIO_COPY_PAGES,
1172 .error = 0,
1173 .kref = { ATOMIC_INIT(2) },
1174 };
1175
1176 bm_page_io_async(ctx, idx, WRITE_SYNC);
1177 wait_for_completion(&ctx->done);
1147 1178
1148 if (ctx.error) 1179 if (ctx->error)
1149 drbd_chk_io_error(mdev, 1, true); 1180 drbd_chk_io_error(mdev, 1, true);
1150 /* that should force detach, so the in memory bitmap will be 1181 /* that should force detach, so the in memory bitmap will be
1151 * gone in a moment as well. */ 1182 * gone in a moment as well. */
1152 1183
1153 mdev->bm_writ_cnt++; 1184 mdev->bm_writ_cnt++;
1154 return ctx.error; 1185 err = ctx->error;
1186 kref_put(&ctx->kref, &bm_aio_ctx_destroy);
1187
1188 return err;
1155} 1189}
1156 1190
1157/* NOTE 1191/* NOTE