diff options
Diffstat (limited to 'drivers/block/drbd/drbd_worker.c')
-rw-r--r-- | drivers/block/drbd/drbd_worker.c | 22 |
1 files changed, 13 insertions, 9 deletions
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); |
394 | fail: | 394 | defer: |
395 | put_ldev(mdev); | 395 | put_ldev(mdev); |
396 | return 2; | 396 | return -EAGAIN; |
397 | } | 397 | } |
398 | 398 | ||
399 | void resync_timer_fn(unsigned long data) | 399 | void 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); |