[PATCH] md: always honour md bitmap being read from disk
authorNeilBrown <neilb@cse.unsw.edu.au>
Thu, 4 Aug 2005 19:53:33 +0000 (12:53 -0700)
committerLinus Torvalds <torvalds@g5.osdl.org>
Thu, 4 Aug 2005 20:00:54 +0000 (13:00 -0700)
The code currently will ignore the bitmap if the array seem to be in-sync.
This is wrong if the array is degraded, and probably wrong anyway.  If the
bitmap says some chunks are not in in-sync, and the superblock says everything
IS in sync, then something is clearly wrong, and it is safer to trust the
bitmap.

Signed-off-by: Neil Brown <neilb@cse.unsw.edu.au>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
drivers/md/bitmap.c

index 70bca955e0de86c4003cdb919885518d4243b2d3..09d32db06d20002b2b8f8e7502d7b72be8c16189 100644 (file)
@@ -818,8 +818,7 @@ int bitmap_unplug(struct bitmap *bitmap)
        return 0;
 }
 
-static void bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset,
-       unsigned long sectors, int in_sync);
+static void bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset);
 /* * bitmap_init_from_disk -- called at bitmap_create time to initialize
  * the in-memory bitmap from the on-disk bitmap -- also, sets up the
  * memory mapping of the bitmap file
@@ -828,7 +827,7 @@ static void bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset,
  *   previously kicked from the array, we mark all the bits as
  *   1's in order to cause a full resync.
  */
-static int bitmap_init_from_disk(struct bitmap *bitmap, int in_sync)
+static int bitmap_init_from_disk(struct bitmap *bitmap)
 {
        unsigned long i, chunks, index, oldindex, bit;
        struct page *page = NULL, *oldpage = NULL;
@@ -929,8 +928,7 @@ static int bitmap_init_from_disk(struct bitmap *bitmap, int in_sync)
                }
                if (test_bit(bit, page_address(page))) {
                        /* if the disk bit is set, set the memory bit */
-                       bitmap_set_memory_bits(bitmap,
-                                       i << CHUNK_BLOCK_SHIFT(bitmap), 1, in_sync);
+                       bitmap_set_memory_bits(bitmap, i << CHUNK_BLOCK_SHIFT(bitmap));
                        bit_cnt++;
                }
        }
@@ -1426,35 +1424,30 @@ void bitmap_close_sync(struct bitmap *bitmap)
        }
 }
 
-static void bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset,
-                                  unsigned long sectors, int in_sync)
+static void bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset)
 {
        /* For each chunk covered by any of these sectors, set the
-        * counter to 1 and set resync_needed unless in_sync.  They should all
+        * counter to 1 and set resync_needed.  They should all
         * be 0 at this point
         */
-       while (sectors) {
-               int secs;
-               bitmap_counter_t *bmc;
-               spin_lock_irq(&bitmap->lock);
-               bmc = bitmap_get_counter(bitmap, offset, &secs, 1);
-               if (!bmc) {
-                       spin_unlock_irq(&bitmap->lock);
-                       return;
-               }
-               if (! *bmc) {
-                       struct page *page;
-                       *bmc = 1 | (in_sync? 0 : NEEDED_MASK);
-                       bitmap_count_page(bitmap, offset, 1);
-                       page = filemap_get_page(bitmap, offset >> CHUNK_BLOCK_SHIFT(bitmap));
-                       set_page_attr(bitmap, page, BITMAP_PAGE_CLEAN);
-               }
+
+       int secs;
+       bitmap_counter_t *bmc;
+       spin_lock_irq(&bitmap->lock);
+       bmc = bitmap_get_counter(bitmap, offset, &secs, 1);
+       if (!bmc) {
                spin_unlock_irq(&bitmap->lock);
-               if (sectors > secs)
-                       sectors -= secs;
-               else
-                       sectors = 0;
+               return;
        }
+       if (! *bmc) {
+               struct page *page;
+               *bmc = 1 | NEEDED_MASK;
+               bitmap_count_page(bitmap, offset, 1);
+               page = filemap_get_page(bitmap, offset >> CHUNK_BLOCK_SHIFT(bitmap));
+               set_page_attr(bitmap, page, BITMAP_PAGE_CLEAN);
+       }
+       spin_unlock_irq(&bitmap->lock);
+
 }
 
 /*
@@ -1565,7 +1558,8 @@ int bitmap_create(mddev_t *mddev)
 
        /* now that we have some pages available, initialize the in-memory
         * bitmap from the on-disk bitmap */
-       err = bitmap_init_from_disk(bitmap, mddev->recovery_cp == MaxSector);
+       err = bitmap_init_from_disk(bitmap);
+
        if (err)
                return err;