diff options
Diffstat (limited to 'drivers/md/bitmap.c')
-rw-r--r-- | drivers/md/bitmap.c | 69 |
1 files changed, 48 insertions, 21 deletions
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c index 93765261c36..1ba1e122e94 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) |