summaryrefslogtreecommitdiff
path: root/drivers/md/bitmap.c
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2010-06-01 19:37:35 +1000
committerNeilBrown <neilb@suse.de>2010-07-26 13:21:34 +1000
commit69e51b449d383e97b1b9f890f8378c96e9e17346 (patch)
tree650123fa4f08e8fa7f348a4ca875c59c129e5d84 /drivers/md/bitmap.c
parente384e58549a2e9a83071ad80280c1a9053cfd84c (diff)
md/bitmap: separate out loading a bitmap from initialising the structures.
dm makes this distinction between ->ctr and ->resume, so we need to too. Also get the new bitmap_load to clear out the bitmap first, as this is most consistent with the dm suspend/resume approach Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'drivers/md/bitmap.c')
-rw-r--r--drivers/md/bitmap.c69
1 files changed, 48 insertions, 21 deletions
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c
index 93765261c363..1ba1e122e948 100644
--- a/drivers/md/bitmap.c
+++ b/drivers/md/bitmap.c
@@ -1681,7 +1681,6 @@ int bitmap_create(mddev_t *mddev)
unsigned long pages;
struct file *file = mddev->bitmap_info.file;
int err;
- sector_t start;
struct sysfs_dirent *bm = NULL;
BUILD_BUG_ON(sizeof(bitmap_super_t) != 256);
@@ -1763,13 +1762,40 @@ int bitmap_create(mddev_t *mddev)
if (!bitmap->bp)
goto error;
- /* now that we have some pages available, initialize the in-memory
- * bitmap from the on-disk bitmap */
- start = 0;
- if (mddev->degraded == 0
- || bitmap->events_cleared == mddev->events)
- /* no need to keep dirty bits to optimise a re-add of a missing device */
- start = mddev->recovery_cp;
+ printk(KERN_INFO "created bitmap (%lu pages) for device %s\n",
+ pages, bmname(bitmap));
+
+ mddev->bitmap = bitmap;
+
+
+ return (bitmap->flags & BITMAP_WRITE_ERROR) ? -EIO : 0;
+
+ error:
+ bitmap_free(bitmap);
+ return err;
+}
+
+int bitmap_load(mddev_t *mddev)
+{
+ int err = 0;
+ sector_t sector = 0;
+ struct bitmap *bitmap = mddev->bitmap;
+
+ if (!bitmap)
+ goto out;
+
+ /* Clear out old bitmap info first: Either there is none, or we
+ * are resuming after someone else has possibly changed things,
+ * so we should forget old cached info.
+ * All chunks should be clean, but some might need_sync.
+ */
+ while (sector < mddev->resync_max_sectors) {
+ int blocks;
+ bitmap_start_sync(bitmap, sector, &blocks, 0);
+ sector += blocks;
+ }
+ bitmap_close_sync(bitmap);
+
if (mddev->bitmap_info.log) {
unsigned long i;
struct dm_dirty_log *log = mddev->bitmap_info.log;
@@ -1778,29 +1804,30 @@ int bitmap_create(mddev_t *mddev)
bitmap_set_memory_bits(bitmap,
(sector_t)i << CHUNK_BLOCK_SHIFT(bitmap),
1);
- err = 0;
- } else
- err = bitmap_init_from_disk(bitmap, start);
+ } else {
+ sector_t start = 0;
+ if (mddev->degraded == 0
+ || bitmap->events_cleared == mddev->events)
+ /* no need to keep dirty bits to optimise a
+ * re-add of a missing device */
+ start = mddev->recovery_cp;
+ err = bitmap_init_from_disk(bitmap, start);
+ }
if (err)
- goto error;
-
- printk(KERN_INFO "created bitmap (%lu pages) for device %s\n",
- pages, bmname(bitmap));
-
- mddev->bitmap = bitmap;
+ goto out;
mddev->thread->timeout = mddev->bitmap_info.daemon_sleep;
md_wakeup_thread(mddev->thread);
bitmap_update_sb(bitmap);
- return (bitmap->flags & BITMAP_WRITE_ERROR) ? -EIO : 0;
-
- error:
- bitmap_free(bitmap);
+ if (bitmap->flags & BITMAP_WRITE_ERROR)
+ err = -EIO;
+out:
return err;
}
+EXPORT_SYMBOL_GPL(bitmap_load);
static ssize_t
location_show(mddev_t *mddev, char *page)