drbd: reduce code duplication when receiving data requests
also canonicalize the return values of read_for_csum and drbd_rs_begin_io to return -ESOMETHING, or 0 for success. Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com> Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
This commit is contained in:
parent
1d7734a0df
commit
80a40e439e
|
@ -1119,7 +1119,7 @@ static int _is_in_al(struct drbd_conf *mdev, unsigned int enr)
|
|||
* @mdev: DRBD device.
|
||||
* @sector: The sector number.
|
||||
*
|
||||
* This functions sleeps on al_wait. Returns 1 on success, 0 if interrupted.
|
||||
* This functions sleeps on al_wait. Returns 0 on success, -EINTR if interrupted.
|
||||
*/
|
||||
int drbd_rs_begin_io(struct drbd_conf *mdev, sector_t sector)
|
||||
{
|
||||
|
@ -1130,10 +1130,10 @@ int drbd_rs_begin_io(struct drbd_conf *mdev, sector_t sector)
|
|||
sig = wait_event_interruptible(mdev->al_wait,
|
||||
(bm_ext = _bme_get(mdev, enr)));
|
||||
if (sig)
|
||||
return 0;
|
||||
return -EINTR;
|
||||
|
||||
if (test_bit(BME_LOCKED, &bm_ext->flags))
|
||||
return 1;
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < AL_EXT_PER_BM_SECT; i++) {
|
||||
sig = wait_event_interruptible(mdev->al_wait,
|
||||
|
@ -1146,13 +1146,11 @@ int drbd_rs_begin_io(struct drbd_conf *mdev, sector_t sector)
|
|||
wake_up(&mdev->al_wait);
|
||||
}
|
||||
spin_unlock_irq(&mdev->al_lock);
|
||||
return 0;
|
||||
return -EINTR;
|
||||
}
|
||||
}
|
||||
|
||||
set_bit(BME_LOCKED, &bm_ext->flags);
|
||||
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -2068,21 +2068,12 @@ static int receive_DataRequest(struct drbd_conf *mdev, struct p_header *h)
|
|||
case P_DATA_REQUEST:
|
||||
e->w.cb = w_e_end_data_req;
|
||||
fault_type = DRBD_FAULT_DT_RD;
|
||||
break;
|
||||
/* application IO, don't drbd_rs_begin_io */
|
||||
goto submit;
|
||||
|
||||
case P_RS_DATA_REQUEST:
|
||||
e->w.cb = w_e_end_rsdata_req;
|
||||
fault_type = DRBD_FAULT_RS_RD;
|
||||
/* Eventually this should become asynchronously. Currently it
|
||||
* blocks the whole receiver just to delay the reading of a
|
||||
* resync data block.
|
||||
* the drbd_work_queue mechanism is made for this...
|
||||
*/
|
||||
if (!drbd_rs_begin_io(mdev, sector)) {
|
||||
/* we have been interrupted,
|
||||
* probably connection lost! */
|
||||
D_ASSERT(signal_pending(current));
|
||||
goto out_free_e;
|
||||
}
|
||||
break;
|
||||
|
||||
case P_OV_REPLY:
|
||||
|
@ -2108,13 +2099,8 @@ static int receive_DataRequest(struct drbd_conf *mdev, struct p_header *h)
|
|||
} else if (h->command == P_OV_REPLY) {
|
||||
e->w.cb = w_e_end_ov_reply;
|
||||
dec_rs_pending(mdev);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!drbd_rs_begin_io(mdev, sector)) {
|
||||
/* we have been interrupted, probably connection lost! */
|
||||
D_ASSERT(signal_pending(current));
|
||||
goto out_free_e;
|
||||
/* drbd_rs_begin_io done when we sent this request */
|
||||
goto submit;
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -2133,31 +2119,23 @@ static int receive_DataRequest(struct drbd_conf *mdev, struct p_header *h)
|
|||
}
|
||||
e->w.cb = w_e_end_ov_req;
|
||||
fault_type = DRBD_FAULT_RS_RD;
|
||||
/* Eventually this should become asynchronous. Currently it
|
||||
* blocks the whole receiver just to delay the reading of a
|
||||
* resync data block.
|
||||
* the drbd_work_queue mechanism is made for this...
|
||||
*/
|
||||
if (!drbd_rs_begin_io(mdev, sector)) {
|
||||
/* we have been interrupted,
|
||||
* probably connection lost! */
|
||||
D_ASSERT(signal_pending(current));
|
||||
goto out_free_e;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
dev_err(DEV, "unexpected command (%s) in receive_DataRequest\n",
|
||||
cmdname(h->command));
|
||||
fault_type = DRBD_FAULT_MAX;
|
||||
goto out_free_e;
|
||||
}
|
||||
|
||||
spin_lock_irq(&mdev->req_lock);
|
||||
list_add(&e->w.list, &mdev->read_ee);
|
||||
spin_unlock_irq(&mdev->req_lock);
|
||||
if (drbd_rs_begin_io(mdev, e->sector))
|
||||
goto out_free_e;
|
||||
|
||||
submit:
|
||||
inc_unacked(mdev);
|
||||
spin_lock_irq(&mdev->req_lock);
|
||||
list_add_tail(&e->w.list, &mdev->read_ee);
|
||||
spin_unlock_irq(&mdev->req_lock);
|
||||
|
||||
if (drbd_submit_ee(mdev, e, READ, fault_type) == 0)
|
||||
return TRUE;
|
||||
|
|
|
@ -374,26 +374,26 @@ static int read_for_csum(struct drbd_conf *mdev, sector_t sector, int size)
|
|||
struct drbd_epoch_entry *e;
|
||||
|
||||
if (!get_ldev(mdev))
|
||||
return 0;
|
||||
return -EIO;
|
||||
|
||||
/* GFP_TRY, because if there is no memory available right now, this may
|
||||
* be rescheduled for later. It is "only" background resync, after all. */
|
||||
e = drbd_alloc_ee(mdev, DRBD_MAGIC+0xbeef, sector, size, GFP_TRY);
|
||||
if (!e)
|
||||
goto fail;
|
||||
goto defer;
|
||||
|
||||
e->w.cb = w_e_send_csum;
|
||||
spin_lock_irq(&mdev->req_lock);
|
||||
list_add(&e->w.list, &mdev->read_ee);
|
||||
spin_unlock_irq(&mdev->req_lock);
|
||||
|
||||
e->w.cb = w_e_send_csum;
|
||||
if (drbd_submit_ee(mdev, e, READ, DRBD_FAULT_RS_RD) == 0)
|
||||
return 1;
|
||||
return 0;
|
||||
|
||||
drbd_free_ee(mdev, e);
|
||||
fail:
|
||||
defer:
|
||||
put_ldev(mdev);
|
||||
return 2;
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
void resync_timer_fn(unsigned long data)
|
||||
|
@ -649,15 +649,19 @@ next_sector:
|
|||
size = (capacity-sector)<<9;
|
||||
if (mdev->agreed_pro_version >= 89 && mdev->csums_tfm) {
|
||||
switch (read_for_csum(mdev, sector, size)) {
|
||||
case 0: /* Disk failure*/
|
||||
case -EIO: /* Disk failure */
|
||||
put_ldev(mdev);
|
||||
return 0;
|
||||
case 2: /* Allocation failed */
|
||||
case -EAGAIN: /* allocation failed, or ldev busy */
|
||||
drbd_rs_complete_io(mdev, sector);
|
||||
mdev->bm_resync_fo = BM_SECT_TO_BIT(sector);
|
||||
i = rollback_i;
|
||||
goto requeue;
|
||||
/* case 1: everything ok */
|
||||
case 0:
|
||||
/* everything ok */
|
||||
break;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
} else {
|
||||
inc_rs_pending(mdev);
|
||||
|
|
Loading…
Reference in New Issue