aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/block/drbd/drbd_actlog.c12
-rw-r--r--drivers/block/drbd/drbd_receiver.c46
-rw-r--r--drivers/block/drbd/drbd_worker.c22
3 files changed, 30 insertions, 50 deletions
diff --git a/drivers/block/drbd/drbd_actlog.c b/drivers/block/drbd/drbd_actlog.c
index b895470e53d..ac04ef97eac 100644
--- a/drivers/block/drbd/drbd_actlog.c
+++ b/drivers/block/drbd/drbd_actlog.c
@@ -1119,7 +1119,7 @@ static int _is_in_al(struct drbd_conf *mdev, unsigned int enr)
1119 * @mdev: DRBD device. 1119 * @mdev: DRBD device.
1120 * @sector: The sector number. 1120 * @sector: The sector number.
1121 * 1121 *
1122 * This functions sleeps on al_wait. Returns 1 on success, 0 if interrupted. 1122 * This functions sleeps on al_wait. Returns 0 on success, -EINTR if interrupted.
1123 */ 1123 */
1124int drbd_rs_begin_io(struct drbd_conf *mdev, sector_t sector) 1124int drbd_rs_begin_io(struct drbd_conf *mdev, sector_t sector)
1125{ 1125{
@@ -1130,10 +1130,10 @@ int drbd_rs_begin_io(struct drbd_conf *mdev, sector_t sector)
1130 sig = wait_event_interruptible(mdev->al_wait, 1130 sig = wait_event_interruptible(mdev->al_wait,
1131 (bm_ext = _bme_get(mdev, enr))); 1131 (bm_ext = _bme_get(mdev, enr)));
1132 if (sig) 1132 if (sig)
1133 return 0; 1133 return -EINTR;
1134 1134
1135 if (test_bit(BME_LOCKED, &bm_ext->flags)) 1135 if (test_bit(BME_LOCKED, &bm_ext->flags))
1136 return 1; 1136 return 0;
1137 1137
1138 for (i = 0; i < AL_EXT_PER_BM_SECT; i++) { 1138 for (i = 0; i < AL_EXT_PER_BM_SECT; i++) {
1139 sig = wait_event_interruptible(mdev->al_wait, 1139 sig = wait_event_interruptible(mdev->al_wait,
@@ -1146,13 +1146,11 @@ int drbd_rs_begin_io(struct drbd_conf *mdev, sector_t sector)
1146 wake_up(&mdev->al_wait); 1146 wake_up(&mdev->al_wait);
1147 } 1147 }
1148 spin_unlock_irq(&mdev->al_lock); 1148 spin_unlock_irq(&mdev->al_lock);
1149 return 0; 1149 return -EINTR;
1150 } 1150 }
1151 } 1151 }
1152
1153 set_bit(BME_LOCKED, &bm_ext->flags); 1152 set_bit(BME_LOCKED, &bm_ext->flags);
1154 1153 return 0;
1155 return 1;
1156} 1154}
1157 1155
1158/** 1156/**
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 2f9320be490..346aed98027 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -2068,21 +2068,12 @@ static int receive_DataRequest(struct drbd_conf *mdev, struct p_header *h)
2068 case P_DATA_REQUEST: 2068 case P_DATA_REQUEST:
2069 e->w.cb = w_e_end_data_req; 2069 e->w.cb = w_e_end_data_req;
2070 fault_type = DRBD_FAULT_DT_RD; 2070 fault_type = DRBD_FAULT_DT_RD;
2071 break; 2071 /* application IO, don't drbd_rs_begin_io */
2072 goto submit;
2073
2072 case P_RS_DATA_REQUEST: 2074 case P_RS_DATA_REQUEST:
2073 e->w.cb = w_e_end_rsdata_req; 2075 e->w.cb = w_e_end_rsdata_req;
2074 fault_type = DRBD_FAULT_RS_RD; 2076 fault_type = DRBD_FAULT_RS_RD;
2075 /* Eventually this should become asynchronously. Currently it
2076 * blocks the whole receiver just to delay the reading of a
2077 * resync data block.
2078 * the drbd_work_queue mechanism is made for this...
2079 */
2080 if (!drbd_rs_begin_io(mdev, sector)) {
2081 /* we have been interrupted,
2082 * probably connection lost! */
2083 D_ASSERT(signal_pending(current));
2084 goto out_free_e;
2085 }
2086 break; 2077 break;
2087 2078
2088 case P_OV_REPLY: 2079 case P_OV_REPLY:
@@ -2108,13 +2099,8 @@ static int receive_DataRequest(struct drbd_conf *mdev, struct p_header *h)
2108 } else if (h->command == P_OV_REPLY) { 2099 } else if (h->command == P_OV_REPLY) {
2109 e->w.cb = w_e_end_ov_reply; 2100 e->w.cb = w_e_end_ov_reply;
2110 dec_rs_pending(mdev); 2101 dec_rs_pending(mdev);
2111 break; 2102 /* drbd_rs_begin_io done when we sent this request */
2112 } 2103 goto submit;
2113
2114 if (!drbd_rs_begin_io(mdev, sector)) {
2115 /* we have been interrupted, probably connection lost! */
2116 D_ASSERT(signal_pending(current));
2117 goto out_free_e;
2118 } 2104 }
2119 break; 2105 break;
2120 2106
@@ -2133,31 +2119,23 @@ static int receive_DataRequest(struct drbd_conf *mdev, struct p_header *h)
2133 } 2119 }
2134 e->w.cb = w_e_end_ov_req; 2120 e->w.cb = w_e_end_ov_req;
2135 fault_type = DRBD_FAULT_RS_RD; 2121 fault_type = DRBD_FAULT_RS_RD;
2136 /* Eventually this should become asynchronous. Currently it
2137 * blocks the whole receiver just to delay the reading of a
2138 * resync data block.
2139 * the drbd_work_queue mechanism is made for this...
2140 */
2141 if (!drbd_rs_begin_io(mdev, sector)) {
2142 /* we have been interrupted,
2143 * probably connection lost! */
2144 D_ASSERT(signal_pending(current));
2145 goto out_free_e;
2146 }
2147 break; 2122 break;
2148 2123
2149
2150 default: 2124 default:
2151 dev_err(DEV, "unexpected command (%s) in receive_DataRequest\n", 2125 dev_err(DEV, "unexpected command (%s) in receive_DataRequest\n",
2152 cmdname(h->command)); 2126 cmdname(h->command));
2153 fault_type = DRBD_FAULT_MAX; 2127 fault_type = DRBD_FAULT_MAX;
2128 goto out_free_e;
2154 } 2129 }
2155 2130
2156 spin_lock_irq(&mdev->req_lock); 2131 if (drbd_rs_begin_io(mdev, e->sector))
2157 list_add(&e->w.list, &mdev->read_ee); 2132 goto out_free_e;
2158 spin_unlock_irq(&mdev->req_lock);
2159 2133
2134submit:
2160 inc_unacked(mdev); 2135 inc_unacked(mdev);
2136 spin_lock_irq(&mdev->req_lock);
2137 list_add_tail(&e->w.list, &mdev->read_ee);
2138 spin_unlock_irq(&mdev->req_lock);
2161 2139
2162 if (drbd_submit_ee(mdev, e, READ, fault_type) == 0) 2140 if (drbd_submit_ee(mdev, e, READ, fault_type) == 0)
2163 return TRUE; 2141 return TRUE;
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c
index 53b74254b1c..f5d779b4d68 100644
--- a/drivers/block/drbd/drbd_worker.c
+++ b/drivers/block/drbd/drbd_worker.c
@@ -374,26 +374,26 @@ static int read_for_csum(struct drbd_conf *mdev, sector_t sector, int size)
374 struct drbd_epoch_entry *e; 374 struct drbd_epoch_entry *e;
375 375
376 if (!get_ldev(mdev)) 376 if (!get_ldev(mdev))
377 return 0; 377 return -EIO;
378 378
379 /* GFP_TRY, because if there is no memory available right now, this may 379 /* GFP_TRY, because if there is no memory available right now, this may
380 * be rescheduled for later. It is "only" background resync, after all. */ 380 * be rescheduled for later. It is "only" background resync, after all. */
381 e = drbd_alloc_ee(mdev, DRBD_MAGIC+0xbeef, sector, size, GFP_TRY); 381 e = drbd_alloc_ee(mdev, DRBD_MAGIC+0xbeef, sector, size, GFP_TRY);
382 if (!e) 382 if (!e)
383 goto fail; 383 goto defer;
384 384
385 e->w.cb = w_e_send_csum;
385 spin_lock_irq(&mdev->req_lock); 386 spin_lock_irq(&mdev->req_lock);
386 list_add(&e->w.list, &mdev->read_ee); 387 list_add(&e->w.list, &mdev->read_ee);
387 spin_unlock_irq(&mdev->req_lock); 388 spin_unlock_irq(&mdev->req_lock);
388 389
389 e->w.cb = w_e_send_csum;
390 if (drbd_submit_ee(mdev, e, READ, DRBD_FAULT_RS_RD) == 0) 390 if (drbd_submit_ee(mdev, e, READ, DRBD_FAULT_RS_RD) == 0)
391 return 1; 391 return 0;
392 392
393 drbd_free_ee(mdev, e); 393 drbd_free_ee(mdev, e);
394fail: 394defer:
395 put_ldev(mdev); 395 put_ldev(mdev);
396 return 2; 396 return -EAGAIN;
397} 397}
398 398
399void resync_timer_fn(unsigned long data) 399void resync_timer_fn(unsigned long data)
@@ -649,15 +649,19 @@ next_sector:
649 size = (capacity-sector)<<9; 649 size = (capacity-sector)<<9;
650 if (mdev->agreed_pro_version >= 89 && mdev->csums_tfm) { 650 if (mdev->agreed_pro_version >= 89 && mdev->csums_tfm) {
651 switch (read_for_csum(mdev, sector, size)) { 651 switch (read_for_csum(mdev, sector, size)) {
652 case 0: /* Disk failure*/ 652 case -EIO: /* Disk failure */
653 put_ldev(mdev); 653 put_ldev(mdev);
654 return 0; 654 return 0;
655 case 2: /* Allocation failed */ 655 case -EAGAIN: /* allocation failed, or ldev busy */
656 drbd_rs_complete_io(mdev, sector); 656 drbd_rs_complete_io(mdev, sector);
657 mdev->bm_resync_fo = BM_SECT_TO_BIT(sector); 657 mdev->bm_resync_fo = BM_SECT_TO_BIT(sector);
658 i = rollback_i; 658 i = rollback_i;
659 goto requeue; 659 goto requeue;
660 /* case 1: everything ok */ 660 case 0:
661 /* everything ok */
662 break;
663 default:
664 BUG();
661 } 665 }
662 } else { 666 } else {
663 inc_rs_pending(mdev); 667 inc_rs_pending(mdev);