diff options
author | Philipp Reisner <philipp.reisner@linbit.com> | 2011-06-27 08:56:52 -0400 |
---|---|---|
committer | Philipp Reisner <philipp.reisner@linbit.com> | 2012-05-09 04:37:19 -0400 |
commit | d1f3779bbeae70b9552c9ac70d6ec8c4d3545615 (patch) | |
tree | 306089519ac84f24e0674de930931e21f3859d6a /drivers/block/drbd/drbd_bitmap.c | |
parent | b2057629ea96c33e4ae38102ecd0f27ed9a3c3ef (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.c | 84 |
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 | ||
896 | static 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 */ |
896 | static void bm_async_io_complete(struct bio *bio, int error) | 904 | static 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 | ||
943 | static void bm_page_io_async(struct bm_aio_ctx *ctx, int page_nr, int rw) __must_hold(local) | 953 | static 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 | */ |
1002 | static int bm_rw(struct drbd_conf *mdev, int rw, unsigned lazy_writeout_upper_idx) __must_hold(local) | 1012 | static 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 | */ |
1131 | int drbd_bm_write_page(struct drbd_conf *mdev, unsigned int idx) __must_hold(local) | 1153 | int 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 |