drbd: reduce code duplication when receiving data requests
authorLars Ellenberg <lars.ellenberg@linbit.com>
Wed, 11 Aug 2010 21:28:00 +0000 (23:28 +0200)
committerPhilipp Reisner <philipp.reisner@linbit.com>
Thu, 14 Oct 2010 16:38:19 +0000 (18:38 +0200)
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>
drivers/block/drbd/drbd_actlog.c
drivers/block/drbd/drbd_receiver.c
drivers/block/drbd/drbd_worker.c

index b895470..ac04ef9 100644 (file)
@@ -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;
 }
 
 /**
index 2f9320b..346aed9 100644 (file)
@@ -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;
index 53b7425..f5d779b 100644 (file)
@@ -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);