aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/drbd/drbd_bitmap.c
diff options
context:
space:
mode:
authorPhilipp Reisner <philipp.reisner@linbit.com>2011-07-05 09:38:59 -0400
committerPhilipp Reisner <philipp.reisner@linbit.com>2012-11-08 10:57:50 -0500
commitcdfda633d235028e9b27381dedb65416409e8729 (patch)
treec2b07a9b0f1bfb2bb04dd118df15a53ff2592ade /drivers/block/drbd/drbd_bitmap.c
parent2fcb8f307f6014de9e771799d9ec0f050802c0ac (diff)
drbd: detach from frozen backing device
* drbd-8.3: documentation: Documented detach's --force and disk's --disk-timeout drbd: Implemented the disk-timeout option drbd: Force flag for the detach operation drbd: Allow new IOs while the local disk in in FAILED state drbd: Bitmap IO functions can not return prematurely if the disk breaks drbd: Added a kref to bm_aio_ctx drbd: Hold a reference to ldev while doing meta-data IO drbd: Keep a reference to the bio until the completion handler finished drbd: Implemented wait_until_done_or_disk_failure() drbd: Replaced md_io_mutex by an atomic: md_io_in_use drbd: moved md_io into mdev drbd: Immediately allow completion of IOs, that wait for IO completions on a failed disk drbd: Keep a reference to barrier acked requests 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.c115
1 files changed, 85 insertions, 30 deletions
diff --git a/drivers/block/drbd/drbd_bitmap.c b/drivers/block/drbd/drbd_bitmap.c
index 52c48143b22a..706e5220dd4a 100644
--- a/drivers/block/drbd/drbd_bitmap.c
+++ b/drivers/block/drbd/drbd_bitmap.c
@@ -918,13 +918,22 @@ void drbd_bm_clear_all(struct drbd_conf *mdev)
918struct bm_aio_ctx { 918struct bm_aio_ctx {
919 struct drbd_conf *mdev; 919 struct drbd_conf *mdev;
920 atomic_t in_flight; 920 atomic_t in_flight;
921 struct completion done; 921 unsigned int done;
922 unsigned flags; 922 unsigned flags;
923#define BM_AIO_COPY_PAGES 1 923#define BM_AIO_COPY_PAGES 1
924#define BM_AIO_WRITE_HINTED 2 924#define BM_AIO_WRITE_HINTED 2
925 int error; 925 int error;
926 struct kref kref;
926}; 927};
927 928
929static void bm_aio_ctx_destroy(struct kref *kref)
930{
931 struct bm_aio_ctx *ctx = container_of(kref, struct bm_aio_ctx, kref);
932
933 put_ldev(ctx->mdev);
934 kfree(ctx);
935}
936
928/* bv_page may be a copy, or may be the original */ 937/* bv_page may be a copy, or may be the original */
929static void bm_async_io_complete(struct bio *bio, int error) 938static void bm_async_io_complete(struct bio *bio, int error)
930{ 939{
@@ -968,13 +977,16 @@ static void bm_async_io_complete(struct bio *bio, int error)
968 977
969 bio_put(bio); 978 bio_put(bio);
970 979
971 if (atomic_dec_and_test(&ctx->in_flight)) 980 if (atomic_dec_and_test(&ctx->in_flight)) {
972 complete(&ctx->done); 981 ctx->done = 1;
982 wake_up(&mdev->misc_wait);
983 kref_put(&ctx->kref, &bm_aio_ctx_destroy);
984 }
973} 985}
974 986
975static void bm_page_io_async(struct bm_aio_ctx *ctx, int page_nr, int rw) __must_hold(local) 987static void bm_page_io_async(struct bm_aio_ctx *ctx, int page_nr, int rw) __must_hold(local)
976{ 988{
977 struct bio *bio = bio_alloc_drbd(GFP_KERNEL); 989 struct bio *bio = bio_alloc_drbd(GFP_NOIO);
978 struct drbd_conf *mdev = ctx->mdev; 990 struct drbd_conf *mdev = ctx->mdev;
979 struct drbd_bitmap *b = mdev->bitmap; 991 struct drbd_bitmap *b = mdev->bitmap;
980 struct page *page; 992 struct page *page;
@@ -1032,12 +1044,7 @@ static void bm_page_io_async(struct bm_aio_ctx *ctx, int page_nr, int rw) __must
1032 */ 1044 */
1033static int bm_rw(struct drbd_conf *mdev, int rw, unsigned flags, unsigned lazy_writeout_upper_idx) __must_hold(local) 1045static int bm_rw(struct drbd_conf *mdev, int rw, unsigned flags, unsigned lazy_writeout_upper_idx) __must_hold(local)
1034{ 1046{
1035 struct bm_aio_ctx ctx = { 1047 struct bm_aio_ctx *ctx;
1036 .mdev = mdev,
1037 .in_flight = ATOMIC_INIT(1),
1038 .done = COMPLETION_INITIALIZER_ONSTACK(ctx.done),
1039 .flags = flags,
1040 };
1041 struct drbd_bitmap *b = mdev->bitmap; 1048 struct drbd_bitmap *b = mdev->bitmap;
1042 int num_pages, i, count = 0; 1049 int num_pages, i, count = 0;
1043 unsigned long now; 1050 unsigned long now;
@@ -1052,7 +1059,27 @@ static int bm_rw(struct drbd_conf *mdev, int rw, unsigned flags, unsigned lazy_w
1052 * For lazy writeout, we don't care for ongoing changes to the bitmap, 1059 * For lazy writeout, we don't care for ongoing changes to the bitmap,
1053 * as we submit copies of pages anyways. 1060 * as we submit copies of pages anyways.
1054 */ 1061 */
1055 if (!ctx.flags) 1062
1063 ctx = kmalloc(sizeof(struct bm_aio_ctx), GFP_NOIO);
1064 if (!ctx)
1065 return -ENOMEM;
1066
1067 *ctx = (struct bm_aio_ctx) {
1068 .mdev = mdev,
1069 .in_flight = ATOMIC_INIT(1),
1070 .done = 0,
1071 .flags = flags,
1072 .error = 0,
1073 .kref = { ATOMIC_INIT(2) },
1074 };
1075
1076 if (!get_ldev_if_state(mdev, D_ATTACHING)) { /* put is in bm_aio_ctx_destroy() */
1077 dev_err(DEV, "ASSERT FAILED: get_ldev_if_state() == 1 in bm_rw()\n");
1078 err = -ENODEV;
1079 goto out;
1080 }
1081
1082 if (!ctx->flags)
1056 WARN_ON(!(BM_LOCKED_MASK & b->bm_flags)); 1083 WARN_ON(!(BM_LOCKED_MASK & b->bm_flags));
1057 1084
1058 num_pages = b->bm_number_of_pages; 1085 num_pages = b->bm_number_of_pages;
@@ -1081,32 +1108,40 @@ static int bm_rw(struct drbd_conf *mdev, int rw, unsigned flags, unsigned lazy_w
1081 continue; 1108 continue;
1082 } 1109 }
1083 } 1110 }
1084 atomic_inc(&ctx.in_flight); 1111 atomic_inc(&ctx->in_flight);
1085 bm_page_io_async(&ctx, i, rw); 1112 bm_page_io_async(ctx, i, rw);
1086 ++count; 1113 ++count;
1087 cond_resched(); 1114 cond_resched();
1088 } 1115 }
1089 1116
1090 /* 1117 /*
1091 * We initialize ctx.in_flight to one to make sure bm_async_io_complete 1118 * We initialize ctx->in_flight to one to make sure bm_async_io_complete
1092 * will not complete() early, and decrement / test it here. If there 1119 * will not set ctx->done early, and decrement / test it here. If there
1093 * are still some bios in flight, we need to wait for them here. 1120 * are still some bios in flight, we need to wait for them here.
1121 * If all IO is done already (or nothing had been submitted), there is
1122 * no need to wait. Still, we need to put the kref associated with the
1123 * "in_flight reached zero, all done" event.
1094 */ 1124 */
1095 if (!atomic_dec_and_test(&ctx.in_flight)) 1125 if (!atomic_dec_and_test(&ctx->in_flight))
1096 wait_for_completion(&ctx.done); 1126 wait_until_done_or_disk_failure(mdev, &ctx->done);
1127 else
1128 kref_put(&ctx->kref, &bm_aio_ctx_destroy);
1097 1129
1098 /* summary for global bitmap IO */ 1130 /* summary for global bitmap IO */
1099 if (flags == 0) 1131 if (flags == 0)
1100 dev_info(DEV, "bitmap %s of %u pages took %lu jiffies\n", 1132 dev_info(DEV, "bitmap %s of %u pages took %lu jiffies\n",
1101 rw == WRITE ? "WRITE" : "READ", 1133 rw == WRITE ? "WRITE" : "READ",
1102 count, jiffies - now); 1134 count, jiffies - now);
1103 1135
1104 if (ctx.error) { 1136 if (ctx->error) {
1105 dev_alert(DEV, "we had at least one MD IO ERROR during bitmap IO\n"); 1137 dev_alert(DEV, "we had at least one MD IO ERROR during bitmap IO\n");
1106 drbd_chk_io_error(mdev, 1, true); 1138 drbd_chk_io_error(mdev, 1, true);
1107 err = -EIO; /* ctx.error ? */ 1139 err = -EIO; /* ctx->error ? */
1108 } 1140 }
1109 1141
1142 if (atomic_read(&ctx->in_flight))
1143 err = -EIO; /* Disk failed during IO... */
1144
1110 now = jiffies; 1145 now = jiffies;
1111 if (rw == WRITE) { 1146 if (rw == WRITE) {
1112 drbd_md_flush(mdev); 1147 drbd_md_flush(mdev);
@@ -1121,6 +1156,8 @@ static int bm_rw(struct drbd_conf *mdev, int rw, unsigned flags, unsigned lazy_w
1121 dev_info(DEV, "%s (%lu bits) marked out-of-sync by on disk bit-map.\n", 1156 dev_info(DEV, "%s (%lu bits) marked out-of-sync by on disk bit-map.\n",
1122 ppsize(ppb, now << (BM_BLOCK_SHIFT-10)), now); 1157 ppsize(ppb, now << (BM_BLOCK_SHIFT-10)), now);
1123 1158
1159out:
1160 kref_put(&ctx->kref, &bm_aio_ctx_destroy);
1124 return err; 1161 return err;
1125} 1162}
1126 1163
@@ -1177,28 +1214,46 @@ int drbd_bm_write_hinted(struct drbd_conf *mdev) __must_hold(local)
1177 */ 1214 */
1178int drbd_bm_write_page(struct drbd_conf *mdev, unsigned int idx) __must_hold(local) 1215int drbd_bm_write_page(struct drbd_conf *mdev, unsigned int idx) __must_hold(local)
1179{ 1216{
1180 struct bm_aio_ctx ctx = { 1217 struct bm_aio_ctx *ctx;
1218 int err;
1219
1220 if (bm_test_page_unchanged(mdev->bitmap->bm_pages[idx])) {
1221 dynamic_dev_dbg(DEV, "skipped bm page write for idx %u\n", idx);
1222 return 0;
1223 }
1224
1225 ctx = kmalloc(sizeof(struct bm_aio_ctx), GFP_NOIO);
1226 if (!ctx)
1227 return -ENOMEM;
1228
1229 *ctx = (struct bm_aio_ctx) {
1181 .mdev = mdev, 1230 .mdev = mdev,
1182 .in_flight = ATOMIC_INIT(1), 1231 .in_flight = ATOMIC_INIT(1),
1183 .done = COMPLETION_INITIALIZER_ONSTACK(ctx.done), 1232 .done = 0,
1184 .flags = BM_AIO_COPY_PAGES, 1233 .flags = BM_AIO_COPY_PAGES,
1234 .error = 0,
1235 .kref = { ATOMIC_INIT(2) },
1185 }; 1236 };
1186 1237
1187 if (bm_test_page_unchanged(mdev->bitmap->bm_pages[idx])) { 1238 if (!get_ldev_if_state(mdev, D_ATTACHING)) { /* put is in bm_aio_ctx_destroy() */
1188 dynamic_dev_dbg(DEV, "skipped bm page write for idx %u\n", idx); 1239 dev_err(DEV, "ASSERT FAILED: get_ldev_if_state() == 1 in drbd_bm_write_page()\n");
1189 return 0; 1240 err = -ENODEV;
1241 goto out;
1190 } 1242 }
1191 1243
1192 bm_page_io_async(&ctx, idx, WRITE_SYNC); 1244 bm_page_io_async(ctx, idx, WRITE_SYNC);
1193 wait_for_completion(&ctx.done); 1245 wait_until_done_or_disk_failure(mdev, &ctx->done);
1194 1246
1195 if (ctx.error) 1247 if (ctx->error)
1196 drbd_chk_io_error(mdev, 1, true); 1248 drbd_chk_io_error(mdev, 1, true);
1197 /* that should force detach, so the in memory bitmap will be 1249 /* that should force detach, so the in memory bitmap will be
1198 * gone in a moment as well. */ 1250 * gone in a moment as well. */
1199 1251
1200 mdev->bm_writ_cnt++; 1252 mdev->bm_writ_cnt++;
1201 return ctx.error; 1253 err = atomic_read(&ctx->in_flight) ? -EIO : ctx->error;
1254 out:
1255 kref_put(&ctx->kref, &bm_aio_ctx_destroy);
1256 return err;
1202} 1257}
1203 1258
1204/* NOTE 1259/* NOTE