drbd: don't count sendpage()d pages only referenced by tcp as in use
[deliverable/linux.git] / drivers / block / drbd / drbd_worker.c
index 99c937acb47151b3de1173c6e34e41fdf43c522d..01743193f321c7d69c02520cbdc95934f2899b04 100644 (file)
@@ -395,25 +395,22 @@ defer:
 
 void resync_timer_fn(unsigned long data)
 {
-       unsigned long flags;
        struct drbd_conf *mdev = (struct drbd_conf *) data;
        int queue;
 
-       spin_lock_irqsave(&mdev->req_lock, flags);
-
-       if (likely(!test_and_clear_bit(STOP_SYNC_TIMER, &mdev->flags))) {
-               queue = 1;
-               if (mdev->state.conn == C_VERIFY_S)
-                       mdev->resync_work.cb = w_make_ov_request;
-               else
-                       mdev->resync_work.cb = w_make_resync_request;
-       } else {
+       queue = 1;
+       switch (mdev->state.conn) {
+       case C_VERIFY_S:
+               mdev->resync_work.cb = w_make_ov_request;
+               break;
+       case C_SYNC_TARGET:
+               mdev->resync_work.cb = w_make_resync_request;
+               break;
+       default:
                queue = 0;
                mdev->resync_work.cb = w_resync_inactive;
        }
 
-       spin_unlock_irqrestore(&mdev->req_lock, flags);
-
        /* harmless race: list_empty outside data.work.q_lock */
        if (list_empty(&mdev->resync_work.list) && queue)
                drbd_queue_work(&mdev->data.work, &mdev->resync_work);
@@ -917,9 +914,13 @@ static void move_to_net_ee_or_free(struct drbd_conf *mdev, struct drbd_epoch_ent
 {
        if (drbd_ee_has_active_page(e)) {
                /* This might happen if sendpage() has not finished */
+               int i = DIV_ROUND_UP(e->size, PAGE_SIZE);
+               atomic_add(i, &mdev->pp_in_use_by_net);
+               atomic_sub(i, &mdev->pp_in_use);
                spin_lock_irq(&mdev->req_lock);
                list_add_tail(&e->w.list, &mdev->net_ee);
                spin_unlock_irq(&mdev->req_lock);
+               wake_up(&drbd_pp_wait);
        } else
                drbd_free_ee(mdev, e);
 }
@@ -1052,7 +1053,9 @@ int w_e_end_csum_rs_req(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
                        ok = drbd_send_ack(mdev, P_RS_IS_IN_SYNC, e);
                } else {
                        inc_rs_pending(mdev);
-                       e->block_id = ID_SYNCER;
+                       e->block_id = ID_SYNCER; /* By setting block_id, digest pointer becomes invalid! */
+                       e->flags &= ~EE_HAS_DIGEST; /* This e no longer has a digest pointer */
+                       kfree(di);
                        ok = drbd_send_block(mdev, P_RS_DATA_REPLY, e);
                }
        } else {
@@ -1202,7 +1205,7 @@ int w_send_barrier(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
         * dec_ap_pending will be done in got_BarrierAck
         * or (on connection loss) in w_clear_epoch.  */
        ok = _drbd_send_cmd(mdev, mdev->data.socket, P_BARRIER,
-                               (struct p_header *)p, sizeof(*p), 0);
+                               (struct p_header80 *)p, sizeof(*p), 0);
        drbd_put_data_sock(mdev);
 
        return ok;
@@ -1271,7 +1274,7 @@ int w_restart_disk_io(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
 {
        struct drbd_request *req = container_of(w, struct drbd_request, w);
 
-       if (bio_data_dir(req->master_bio) == WRITE)
+       if (bio_data_dir(req->master_bio) == WRITE && req->rq_state & RQ_IN_ACT_LOG)
                drbd_al_begin_io(mdev, req->sector);
        /* Calling drbd_al_begin_io() out of the worker might deadlocks
           theoretically. Practically it can not deadlock, since this is
This page took 0.047853 seconds and 5 git commands to generate.