raid1: Add a field array_frozen to indicate whether raid in freeze state.
authormajianpeng <majianpeng@gmail.com>
Thu, 14 Nov 2013 04:16:18 +0000 (15:16 +1100)
committerNeilBrown <neilb@suse.de>
Tue, 19 Nov 2013 04:19:18 +0000 (15:19 +1100)
Because the following patch will rewrite the content between normal IO
and resync IO. So we used a parameter to indicate whether raid is in freeze
array.

Signed-off-by: Jianpeng Ma <majianpeng@gmail.com>
Signed-off-by: NeilBrown <neilb@suse.de>
drivers/md/raid1.c
drivers/md/raid1.h

index aacf6bf352d87978a15633b05a0d51d3579ce16d..729db21dc8298021b840fb8a7ef984abec1f5827 100644 (file)
@@ -829,6 +829,7 @@ static void raise_barrier(struct r1conf *conf)
 
        /* Now wait for all pending IO to complete */
        wait_event_lock_irq(conf->wait_barrier,
+                           !conf->array_frozen &&
                            !conf->nr_pending && conf->barrier < RESYNC_DEPTH,
                            conf->resync_lock);
 
@@ -860,10 +861,11 @@ static void wait_barrier(struct r1conf *conf)
                 * count down.
                 */
                wait_event_lock_irq(conf->wait_barrier,
-                                   !conf->barrier ||
+                                   !conf->array_frozen &&
+                                   (!conf->barrier ||
                                    (conf->nr_pending &&
                                     current->bio_list &&
-                                    !bio_list_empty(current->bio_list)),
+                                    !bio_list_empty(current->bio_list))),
                                    conf->resync_lock);
                conf->nr_waiting--;
        }
@@ -884,8 +886,7 @@ static void freeze_array(struct r1conf *conf, int extra)
 {
        /* stop syncio and normal IO and wait for everything to
         * go quite.
-        * We increment barrier and nr_waiting, and then
-        * wait until nr_pending match nr_queued+extra
+        * We wait until nr_pending match nr_queued+extra
         * This is called in the context of one normal IO request
         * that has failed. Thus any sync request that might be pending
         * will be blocked by nr_pending, and we need to wait for
@@ -895,8 +896,7 @@ static void freeze_array(struct r1conf *conf, int extra)
         * we continue.
         */
        spin_lock_irq(&conf->resync_lock);
-       conf->barrier++;
-       conf->nr_waiting++;
+       conf->array_frozen = 1;
        wait_event_lock_irq_cmd(conf->wait_barrier,
                                conf->nr_pending == conf->nr_queued+extra,
                                conf->resync_lock,
@@ -907,8 +907,7 @@ static void unfreeze_array(struct r1conf *conf)
 {
        /* reverse the effect of the freeze */
        spin_lock_irq(&conf->resync_lock);
-       conf->barrier--;
-       conf->nr_waiting--;
+       conf->array_frozen = 0;
        wake_up(&conf->wait_barrier);
        spin_unlock_irq(&conf->resync_lock);
 }
index 0ff3715fb7eba5ec4fed61a9922276b07b363aff..331a98a231b4e3a3dff585055655f065c0f68de9 100644 (file)
@@ -65,6 +65,7 @@ struct r1conf {
        int                     nr_waiting;
        int                     nr_queued;
        int                     barrier;
+       int                     array_frozen;
 
        /* Set to 1 if a full sync is needed, (fresh device added).
         * Cleared when a sync completes.