Skip to content

Commit

Permalink
md/bitmap: separate out loading a bitmap from initialising the struct…
Browse files Browse the repository at this point in the history
…ures.

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>
  • Loading branch information
NeilBrown committed Jul 26, 2010
1 parent e384e58 commit 69e51b4
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 23 deletions.
69 changes: 48 additions & 21 deletions drivers/md/bitmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand All @@ -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)
Expand Down
1 change: 1 addition & 0 deletions drivers/md/bitmap.h
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,7 @@ struct bitmap {

/* these are used only by md/bitmap */
int bitmap_create(mddev_t *mddev);
int bitmap_load(mddev_t *mddev);
void bitmap_flush(mddev_t *mddev);
void bitmap_destroy(mddev_t *mddev);

Expand Down
13 changes: 11 additions & 2 deletions drivers/md/md.c
Original file line number Diff line number Diff line change
Expand Up @@ -4594,7 +4594,11 @@ static int do_md_run(mddev_t *mddev)
err = md_run(mddev);
if (err)
goto out;

err = bitmap_load(mddev);
if (err) {
bitmap_destroy(mddev);
goto out;
}
set_capacity(mddev->gendisk, mddev->array_sectors);
revalidate_disk(mddev->gendisk);
kobject_uevent(&disk_to_dev(mddev->gendisk)->kobj, KOBJ_CHANGE);
Expand Down Expand Up @@ -5382,8 +5386,11 @@ static int set_bitmap_file(mddev_t *mddev, int fd)
err = 0;
if (mddev->pers) {
mddev->pers->quiesce(mddev, 1);
if (fd >= 0)
if (fd >= 0) {
err = bitmap_create(mddev);
if (!err)
err = bitmap_load(mddev);
}
if (fd < 0 || err) {
bitmap_destroy(mddev);
fd = -1; /* make sure to put the file */
Expand Down Expand Up @@ -5632,6 +5639,8 @@ static int update_array_info(mddev_t *mddev, mdu_array_info_t *info)
mddev->bitmap_info.default_offset;
mddev->pers->quiesce(mddev, 1);
rv = bitmap_create(mddev);
if (!rv)
rv = bitmap_load(mddev);
if (rv)
bitmap_destroy(mddev);
mddev->pers->quiesce(mddev, 0);
Expand Down

0 comments on commit 69e51b4

Please sign in to comment.