aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block
diff options
context:
space:
mode:
authorPhilipp Reisner <philipp.reisner@linbit.com>2010-11-10 06:08:37 -0500
committerPhilipp Reisner <philipp.reisner@linbit.com>2011-03-10 05:35:06 -0500
commit3719094ec2dec411b3151f10048316d787e086f9 (patch)
tree4be7bd2bb31612e8210665b9e20985de7deb30e4 /drivers/block
parentab17b68f4579b460753a416b0afc4446381d876f (diff)
drbd: Starting with protocol 96 we can allow app-IO while receiving the bitmap
* C_STARTING_SYNC_S, C_STARTING_SYNC_T In these states the bitmap gets written to disk. Locking out of app-IO is done by using the drbd_queue_bitmap_io() and drbd_bitmap_io() functions these days. It is no longer necessary to lock out app-IO based on the connection state. App-IO that may come in after the BITMAP_IO flag got cleared before the state transition to C_SYNC_(SOURCE|TARGET) does not get mirrored, sets a bit in the local bitmap, that is already set, therefore changes nothing. * C_WF_BITMAP_S In this state we send updates (P_OUT_OF_SYNC packets). With that we make sure they have the same number of bits when going into the C_SYNC_(SOURCE|TARGET) connection state. * C_UNCONNECTED: The receiver starts, no need to lock out IO. * C_DISCONNECTING: in drbd_disconnect() we had a wait_event() to wait until ap_bio_cnt reaches 0. Removed that. * C_TIMEOUT, C_BROKEN_PIPE, C_NETWORK_FAILURE C_PROTOCOL_ERROR, C_TEAR_DOWN: Same as C_DISCONNECTING * C_WF_REPORT_PARAMS: IO still possible since that is still like C_WF_CONNECTION. And we do not need to send barriers in C_WF_BITMAP_S connection state. Allow concurrent accesses to the bitmap when receiving the bitmap. Everything gets ORed anyways. A drbd_free_tl_hash() is in after_state_chg_work(). At that point all the work items of the last connections must have been processed. Introduced a call to drbd_free_tl_hash() into drbd_free_mdev() for paranoia reasons. Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com> Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
Diffstat (limited to 'drivers/block')
-rw-r--r--drivers/block/drbd/drbd_int.h19
-rw-r--r--drivers/block/drbd/drbd_main.c1
-rw-r--r--drivers/block/drbd/drbd_receiver.c13
-rw-r--r--drivers/block/drbd/drbd_req.c37
4 files changed, 39 insertions, 31 deletions
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index 9a944604939f..38bbaba8bd89 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -2213,8 +2213,9 @@ static inline int drbd_get_max_buffers(struct drbd_conf *mdev)
2213 return mxb; 2213 return mxb;
2214} 2214}
2215 2215
2216static inline int drbd_state_is_stable(union drbd_state s) 2216static inline int drbd_state_is_stable(struct drbd_conf *mdev)
2217{ 2217{
2218 union drbd_state s = mdev->state;
2218 2219
2219 /* DO NOT add a default clause, we want the compiler to warn us 2220 /* DO NOT add a default clause, we want the compiler to warn us
2220 * for any newly introduced state we may have forgotten to add here */ 2221 * for any newly introduced state we may have forgotten to add here */
@@ -2233,11 +2234,7 @@ static inline int drbd_state_is_stable(union drbd_state s)
2233 case C_PAUSED_SYNC_T: 2234 case C_PAUSED_SYNC_T:
2234 case C_AHEAD: 2235 case C_AHEAD:
2235 case C_BEHIND: 2236 case C_BEHIND:
2236 /* maybe stable, look at the disk state */ 2237 /* transitional states, IO allowed */
2237 break;
2238
2239 /* no new io accepted during tansitional states
2240 * like handshake or teardown */
2241 case C_DISCONNECTING: 2238 case C_DISCONNECTING:
2242 case C_UNCONNECTED: 2239 case C_UNCONNECTED:
2243 case C_TIMEOUT: 2240 case C_TIMEOUT:
@@ -2248,7 +2245,15 @@ static inline int drbd_state_is_stable(union drbd_state s)
2248 case C_WF_REPORT_PARAMS: 2245 case C_WF_REPORT_PARAMS:
2249 case C_STARTING_SYNC_S: 2246 case C_STARTING_SYNC_S:
2250 case C_STARTING_SYNC_T: 2247 case C_STARTING_SYNC_T:
2248 break;
2249
2250 /* Allow IO in BM exchange states with new protocols */
2251 case C_WF_BITMAP_S: 2251 case C_WF_BITMAP_S:
2252 if (mdev->agreed_pro_version < 96)
2253 return 0;
2254 break;
2255
2256 /* no new io accepted in these states */
2252 case C_WF_BITMAP_T: 2257 case C_WF_BITMAP_T:
2253 case C_WF_SYNC_UUID: 2258 case C_WF_SYNC_UUID:
2254 case C_MASK: 2259 case C_MASK:
@@ -2297,7 +2302,7 @@ static inline int __inc_ap_bio_cond(struct drbd_conf *mdev)
2297 * to start during "stable" states. */ 2302 * to start during "stable" states. */
2298 2303
2299 /* no new io accepted when attaching or detaching the disk */ 2304 /* no new io accepted when attaching or detaching the disk */
2300 if (!drbd_state_is_stable(mdev->state)) 2305 if (!drbd_state_is_stable(mdev))
2301 return 0; 2306 return 0;
2302 2307
2303 /* since some older kernels don't have atomic_add_unless, 2308 /* since some older kernels don't have atomic_add_unless,
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 74a6d55259af..14afbd4e53a5 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -3334,6 +3334,7 @@ void drbd_free_mdev(struct drbd_conf *mdev)
3334 put_disk(mdev->vdisk); 3334 put_disk(mdev->vdisk);
3335 blk_cleanup_queue(mdev->rq_queue); 3335 blk_cleanup_queue(mdev->rq_queue);
3336 free_cpumask_var(mdev->cpu_mask); 3336 free_cpumask_var(mdev->cpu_mask);
3337 drbd_free_tl_hash(mdev);
3337 kfree(mdev); 3338 kfree(mdev);
3338} 3339}
3339 3340
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 0630a2e122d3..f4aba9f894ba 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -3468,9 +3468,7 @@ static int receive_bitmap(struct drbd_conf *mdev, enum drbd_packets cmd, unsigne
3468 int ok = FALSE; 3468 int ok = FALSE;
3469 struct p_header80 *h = &mdev->data.rbuf.header.h80; 3469 struct p_header80 *h = &mdev->data.rbuf.header.h80;
3470 3470
3471 wait_event(mdev->misc_wait, !atomic_read(&mdev->ap_bio_cnt)); 3471 /* drbd_bm_lock(mdev, "receive bitmap"); By intention no bm_lock */
3472
3473 drbd_bm_lock(mdev, "receive bitmap");
3474 3472
3475 /* maybe we should use some per thread scratch page, 3473 /* maybe we should use some per thread scratch page,
3476 * and allocate that during initial device creation? */ 3474 * and allocate that during initial device creation? */
@@ -3542,7 +3540,7 @@ static int receive_bitmap(struct drbd_conf *mdev, enum drbd_packets cmd, unsigne
3542 3540
3543 ok = TRUE; 3541 ok = TRUE;
3544 out: 3542 out:
3545 drbd_bm_unlock(mdev); 3543 /* drbd_bm_unlock(mdev); by intention no lock */
3546 if (ok && mdev->state.conn == C_WF_BITMAP_S) 3544 if (ok && mdev->state.conn == C_WF_BITMAP_S)
3547 drbd_start_resync(mdev, C_SYNC_SOURCE); 3545 drbd_start_resync(mdev, C_SYNC_SOURCE);
3548 free_page((unsigned long) buffer); 3546 free_page((unsigned long) buffer);
@@ -3804,13 +3802,6 @@ static void drbd_disconnect(struct drbd_conf *mdev)
3804 if (os.conn == C_DISCONNECTING) { 3802 if (os.conn == C_DISCONNECTING) {
3805 wait_event(mdev->net_cnt_wait, atomic_read(&mdev->net_cnt) == 0); 3803 wait_event(mdev->net_cnt_wait, atomic_read(&mdev->net_cnt) == 0);
3806 3804
3807 if (!is_susp(mdev->state)) {
3808 /* we must not free the tl_hash
3809 * while application io is still on the fly */
3810 wait_event(mdev->misc_wait, !atomic_read(&mdev->ap_bio_cnt));
3811 drbd_free_tl_hash(mdev);
3812 }
3813
3814 crypto_free_hash(mdev->cram_hmac_tfm); 3805 crypto_free_hash(mdev->cram_hmac_tfm);
3815 mdev->cram_hmac_tfm = NULL; 3806 mdev->cram_hmac_tfm = NULL;
3816 3807
diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c
index eff0fbf69dd4..4cb8247d83c9 100644
--- a/drivers/block/drbd/drbd_req.c
+++ b/drivers/block/drbd/drbd_req.c
@@ -142,7 +142,7 @@ static void _about_to_complete_local_write(struct drbd_conf *mdev,
142 142
143 /* before we can signal completion to the upper layers, 143 /* before we can signal completion to the upper layers,
144 * we may need to close the current epoch */ 144 * we may need to close the current epoch */
145 if (mdev->state.conn >= C_CONNECTED && mdev->state.conn < C_AHEAD && 145 if (mdev->state.conn >= C_WF_BITMAP_T && mdev->state.conn < C_AHEAD &&
146 req->epoch == mdev->newest_tle->br_number) 146 req->epoch == mdev->newest_tle->br_number)
147 queue_barrier(mdev); 147 queue_barrier(mdev);
148 148
@@ -757,6 +757,23 @@ static int drbd_may_do_local_read(struct drbd_conf *mdev, sector_t sector, int s
757 return 0 == drbd_bm_count_bits(mdev, sbnr, ebnr); 757 return 0 == drbd_bm_count_bits(mdev, sbnr, ebnr);
758} 758}
759 759
760static int drbd_should_do_remote(struct drbd_conf *mdev)
761{
762 union drbd_state s = mdev->state;
763
764 return s.pdsk == D_UP_TO_DATE ||
765 (s.pdsk >= D_INCONSISTENT &&
766 s.conn >= C_WF_BITMAP_T &&
767 s.conn < C_AHEAD);
768}
769static int drbd_should_send_oos(struct drbd_conf *mdev)
770{
771 union drbd_state s = mdev->state;
772
773 return s.pdsk >= D_INCONSISTENT &&
774 (s.conn == C_AHEAD || s.conn == C_WF_BITMAP_S);
775}
776
760static int drbd_make_request_common(struct drbd_conf *mdev, struct bio *bio, unsigned long start_time) 777static int drbd_make_request_common(struct drbd_conf *mdev, struct bio *bio, unsigned long start_time)
761{ 778{
762 const int rw = bio_rw(bio); 779 const int rw = bio_rw(bio);
@@ -828,12 +845,9 @@ static int drbd_make_request_common(struct drbd_conf *mdev, struct bio *bio, uns
828 drbd_al_begin_io(mdev, sector); 845 drbd_al_begin_io(mdev, sector);
829 } 846 }
830 847
831 remote = remote && (mdev->state.pdsk == D_UP_TO_DATE || 848 remote = remote && drbd_should_do_remote(mdev);
832 (mdev->state.pdsk >= D_INCONSISTENT && 849 send_oos = rw == WRITE && drbd_should_send_oos(mdev);
833 mdev->state.conn >= C_CONNECTED && 850 D_ASSERT(!(remote && send_oos));
834 mdev->state.conn < C_AHEAD));
835 send_oos = (rw == WRITE && mdev->state.conn == C_AHEAD &&
836 mdev->state.pdsk >= D_INCONSISTENT);
837 851
838 if (!(local || remote) && !is_susp(mdev->state)) { 852 if (!(local || remote) && !is_susp(mdev->state)) {
839 if (__ratelimit(&drbd_ratelimit_state)) 853 if (__ratelimit(&drbd_ratelimit_state))
@@ -873,12 +887,9 @@ allocate_barrier:
873 } 887 }
874 888
875 if (remote || send_oos) { 889 if (remote || send_oos) {
876 remote = (mdev->state.pdsk == D_UP_TO_DATE || 890 remote = drbd_should_do_remote(mdev);
877 (mdev->state.pdsk >= D_INCONSISTENT && 891 send_oos = rw == WRITE && drbd_should_send_oos(mdev);
878 mdev->state.conn >= C_CONNECTED && 892 D_ASSERT(!(remote && send_oos));
879 mdev->state.conn < C_AHEAD));
880 send_oos = (rw == WRITE && mdev->state.conn == C_AHEAD &&
881 mdev->state.pdsk >= D_INCONSISTENT);
882 893
883 if (!(remote || send_oos)) 894 if (!(remote || send_oos))
884 dev_warn(DEV, "lost connection while grabbing the req_lock!\n"); 895 dev_warn(DEV, "lost connection while grabbing the req_lock!\n");