소스 검색

Merge branch 'for-jens' of git://git.drbd.org/linux-drbd into for-linus

Jens Axboe 13 년 전
부모
커밋
6d407cfaf5
2개의 변경된 파일51개의 추가작업 그리고 26개의 파일을 삭제
  1. 9 2
      drivers/block/drbd/drbd_bitmap.c
  2. 42 24
      drivers/block/drbd/drbd_req.c

+ 9 - 2
drivers/block/drbd/drbd_bitmap.c

@@ -1475,10 +1475,17 @@ void _drbd_bm_set_bits(struct drbd_conf *mdev, const unsigned long s, const unsi
 		first_word = 0;
 		first_word = 0;
 		spin_lock_irq(&b->bm_lock);
 		spin_lock_irq(&b->bm_lock);
 	}
 	}
-
 	/* last page (respectively only page, for first page == last page) */
 	/* last page (respectively only page, for first page == last page) */
 	last_word = MLPP(el >> LN2_BPL);
 	last_word = MLPP(el >> LN2_BPL);
-	bm_set_full_words_within_one_page(mdev->bitmap, last_page, first_word, last_word);
+
+	/* consider bitmap->bm_bits = 32768, bitmap->bm_number_of_pages = 1. (or multiples).
+	 * ==> e = 32767, el = 32768, last_page = 2,
+	 * and now last_word = 0.
+	 * We do not want to touch last_page in this case,
+	 * as we did not allocate it, it is not present in bitmap->bm_pages.
+	 */
+	if (last_word)
+		bm_set_full_words_within_one_page(mdev->bitmap, last_page, first_word, last_word);
 
 
 	/* possibly trailing bits.
 	/* possibly trailing bits.
 	 * example: (e & 63) == 63, el will be e+1.
 	 * example: (e & 63) == 63, el will be e+1.

+ 42 - 24
drivers/block/drbd/drbd_req.c

@@ -472,12 +472,17 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what,
 		req->rq_state |= RQ_LOCAL_COMPLETED;
 		req->rq_state |= RQ_LOCAL_COMPLETED;
 		req->rq_state &= ~RQ_LOCAL_PENDING;
 		req->rq_state &= ~RQ_LOCAL_PENDING;
 
 
-		D_ASSERT(!(req->rq_state & RQ_NET_MASK));
+		if (req->rq_state & RQ_LOCAL_ABORTED) {
+			_req_may_be_done(req, m);
+			break;
+		}
 
 
 		__drbd_chk_io_error(mdev, false);
 		__drbd_chk_io_error(mdev, false);
 
 
 	goto_queue_for_net_read:
 	goto_queue_for_net_read:
 
 
+		D_ASSERT(!(req->rq_state & RQ_NET_MASK));
+
 		/* no point in retrying if there is no good remote data,
 		/* no point in retrying if there is no good remote data,
 		 * or we have no connection. */
 		 * or we have no connection. */
 		if (mdev->state.pdsk != D_UP_TO_DATE) {
 		if (mdev->state.pdsk != D_UP_TO_DATE) {
@@ -765,6 +770,40 @@ static int drbd_may_do_local_read(struct drbd_conf *mdev, sector_t sector, int s
 	return 0 == drbd_bm_count_bits(mdev, sbnr, ebnr);
 	return 0 == drbd_bm_count_bits(mdev, sbnr, ebnr);
 }
 }
 
 
+static void maybe_pull_ahead(struct drbd_conf *mdev)
+{
+	int congested = 0;
+
+	/* If I don't even have good local storage, we can not reasonably try
+	 * to pull ahead of the peer. We also need the local reference to make
+	 * sure mdev->act_log is there.
+	 * Note: caller has to make sure that net_conf is there.
+	 */
+	if (!get_ldev_if_state(mdev, D_UP_TO_DATE))
+		return;
+
+	if (mdev->net_conf->cong_fill &&
+	    atomic_read(&mdev->ap_in_flight) >= mdev->net_conf->cong_fill) {
+		dev_info(DEV, "Congestion-fill threshold reached\n");
+		congested = 1;
+	}
+
+	if (mdev->act_log->used >= mdev->net_conf->cong_extents) {
+		dev_info(DEV, "Congestion-extents threshold reached\n");
+		congested = 1;
+	}
+
+	if (congested) {
+		queue_barrier(mdev); /* last barrier, after mirrored writes */
+
+		if (mdev->net_conf->on_congestion == OC_PULL_AHEAD)
+			_drbd_set_state(_NS(mdev, conn, C_AHEAD), 0, NULL);
+		else  /*mdev->net_conf->on_congestion == OC_DISCONNECT */
+			_drbd_set_state(_NS(mdev, conn, C_DISCONNECTING), 0, NULL);
+	}
+	put_ldev(mdev);
+}
+
 static int drbd_make_request_common(struct drbd_conf *mdev, struct bio *bio, unsigned long start_time)
 static int drbd_make_request_common(struct drbd_conf *mdev, struct bio *bio, unsigned long start_time)
 {
 {
 	const int rw = bio_rw(bio);
 	const int rw = bio_rw(bio);
@@ -972,29 +1011,8 @@ allocate_barrier:
 		_req_mod(req, queue_for_send_oos);
 		_req_mod(req, queue_for_send_oos);
 
 
 	if (remote &&
 	if (remote &&
-	    mdev->net_conf->on_congestion != OC_BLOCK && mdev->agreed_pro_version >= 96) {
-		int congested = 0;
-
-		if (mdev->net_conf->cong_fill &&
-		    atomic_read(&mdev->ap_in_flight) >= mdev->net_conf->cong_fill) {
-			dev_info(DEV, "Congestion-fill threshold reached\n");
-			congested = 1;
-		}
-
-		if (mdev->act_log->used >= mdev->net_conf->cong_extents) {
-			dev_info(DEV, "Congestion-extents threshold reached\n");
-			congested = 1;
-		}
-
-		if (congested) {
-			queue_barrier(mdev); /* last barrier, after mirrored writes */
-
-			if (mdev->net_conf->on_congestion == OC_PULL_AHEAD)
-				_drbd_set_state(_NS(mdev, conn, C_AHEAD), 0, NULL);
-			else  /*mdev->net_conf->on_congestion == OC_DISCONNECT */
-				_drbd_set_state(_NS(mdev, conn, C_DISCONNECTING), 0, NULL);
-		}
-	}
+	    mdev->net_conf->on_congestion != OC_BLOCK && mdev->agreed_pro_version >= 96)
+		maybe_pull_ahead(mdev);
 
 
 	spin_unlock_irq(&mdev->req_lock);
 	spin_unlock_irq(&mdev->req_lock);
 	kfree(b); /* if someone else has beaten us to it... */
 	kfree(b); /* if someone else has beaten us to it... */