Commit f9209a32 authored by Goldwyn Rodrigues's avatar Goldwyn Rodrigues

bitmap_create returns bitmap pointer

This is done to have multiple bitmaps open at the same time.
Signed-off-by: default avatarGoldwyn Rodrigues <rgoldwyn@suse.com>
parent 96ae923a
...@@ -553,7 +553,6 @@ static int bitmap_read_sb(struct bitmap *bitmap) ...@@ -553,7 +553,6 @@ static int bitmap_read_sb(struct bitmap *bitmap)
unsigned long sectors_reserved = 0; unsigned long sectors_reserved = 0;
int err = -EINVAL; int err = -EINVAL;
struct page *sb_page; struct page *sb_page;
int cluster_setup_done = 0;
if (!bitmap->storage.file && !bitmap->mddev->bitmap_info.offset) { if (!bitmap->storage.file && !bitmap->mddev->bitmap_info.offset) {
chunksize = 128 * 1024 * 1024; chunksize = 128 * 1024 * 1024;
...@@ -570,6 +569,18 @@ static int bitmap_read_sb(struct bitmap *bitmap) ...@@ -570,6 +569,18 @@ static int bitmap_read_sb(struct bitmap *bitmap)
bitmap->storage.sb_page = sb_page; bitmap->storage.sb_page = sb_page;
re_read: re_read:
/* If cluster_slot is set, the cluster is setup */
if (bitmap->cluster_slot >= 0) {
long long bm_blocks;
bm_blocks = bitmap->mddev->resync_max_sectors / (bitmap->mddev->bitmap_info.chunksize >> 9);
bm_blocks = bm_blocks << 3;
bm_blocks = DIV_ROUND_UP(bm_blocks, 4096);
bitmap->mddev->bitmap_info.offset += bitmap->cluster_slot * (bm_blocks << 3);
pr_info("%s:%d bm slot: %d offset: %llu\n", __func__, __LINE__,
bitmap->cluster_slot, (unsigned long long)bitmap->mddev->bitmap_info.offset);
}
if (bitmap->storage.file) { if (bitmap->storage.file) {
loff_t isize = i_size_read(bitmap->storage.file->f_mapping->host); loff_t isize = i_size_read(bitmap->storage.file->f_mapping->host);
int bytes = isize > PAGE_SIZE ? PAGE_SIZE : isize; int bytes = isize > PAGE_SIZE ? PAGE_SIZE : isize;
...@@ -650,14 +661,9 @@ static int bitmap_read_sb(struct bitmap *bitmap) ...@@ -650,14 +661,9 @@ static int bitmap_read_sb(struct bitmap *bitmap)
out: out:
kunmap_atomic(sb); kunmap_atomic(sb);
if (nodes && !cluster_setup_done) { /* Assiging chunksize is required for "re_read" */
sector_t bm_blocks; bitmap->mddev->bitmap_info.chunksize = chunksize;
if (nodes && (bitmap->cluster_slot < 0)) {
bm_blocks = sector_div(bitmap->mddev->resync_max_sectors, (chunksize >> 9));
bm_blocks = bm_blocks << 3;
/* We have bitmap supers at 4k boundaries, hence this
* is hardcoded */
bm_blocks = DIV_ROUND_UP(bm_blocks, 4096);
err = md_setup_cluster(bitmap->mddev, nodes); err = md_setup_cluster(bitmap->mddev, nodes);
if (err) { if (err) {
pr_err("%s: Could not setup cluster service (%d)\n", pr_err("%s: Could not setup cluster service (%d)\n",
...@@ -665,12 +671,9 @@ static int bitmap_read_sb(struct bitmap *bitmap) ...@@ -665,12 +671,9 @@ static int bitmap_read_sb(struct bitmap *bitmap)
goto out_no_sb; goto out_no_sb;
} }
bitmap->cluster_slot = md_cluster_ops->slot_number(bitmap->mddev); bitmap->cluster_slot = md_cluster_ops->slot_number(bitmap->mddev);
bitmap->mddev->bitmap_info.offset +=
bitmap->cluster_slot * (bm_blocks << 3);
pr_info("%s:%d bm slot: %d offset: %llu\n", __func__, __LINE__, pr_info("%s:%d bm slot: %d offset: %llu\n", __func__, __LINE__,
bitmap->cluster_slot, bitmap->cluster_slot,
(unsigned long long)bitmap->mddev->bitmap_info.offset); (unsigned long long)bitmap->mddev->bitmap_info.offset);
cluster_setup_done = 1;
goto re_read; goto re_read;
} }
...@@ -687,7 +690,7 @@ static int bitmap_read_sb(struct bitmap *bitmap) ...@@ -687,7 +690,7 @@ static int bitmap_read_sb(struct bitmap *bitmap)
bitmap->mddev->bitmap_info.space = sectors_reserved; bitmap->mddev->bitmap_info.space = sectors_reserved;
if (err) { if (err) {
bitmap_print_sb(bitmap); bitmap_print_sb(bitmap);
if (cluster_setup_done) if (bitmap->cluster_slot < 0)
md_cluster_stop(bitmap->mddev); md_cluster_stop(bitmap->mddev);
} }
return err; return err;
...@@ -1639,7 +1642,8 @@ static void bitmap_free(struct bitmap *bitmap) ...@@ -1639,7 +1642,8 @@ static void bitmap_free(struct bitmap *bitmap)
if (!bitmap) /* there was no bitmap */ if (!bitmap) /* there was no bitmap */
return; return;
if (mddev_is_clustered(bitmap->mddev) && bitmap->mddev->cluster_info) if (mddev_is_clustered(bitmap->mddev) && bitmap->mddev->cluster_info &&
bitmap->cluster_slot == md_cluster_ops->slot_number(bitmap->mddev))
md_cluster_stop(bitmap->mddev); md_cluster_stop(bitmap->mddev);
/* Shouldn't be needed - but just in case.... */ /* Shouldn't be needed - but just in case.... */
...@@ -1687,7 +1691,7 @@ void bitmap_destroy(struct mddev *mddev) ...@@ -1687,7 +1691,7 @@ void bitmap_destroy(struct mddev *mddev)
* initialize the bitmap structure * initialize the bitmap structure
* if this returns an error, bitmap_destroy must be called to do clean up * if this returns an error, bitmap_destroy must be called to do clean up
*/ */
int bitmap_create(struct mddev *mddev) struct bitmap *bitmap_create(struct mddev *mddev, int slot)
{ {
struct bitmap *bitmap; struct bitmap *bitmap;
sector_t blocks = mddev->resync_max_sectors; sector_t blocks = mddev->resync_max_sectors;
...@@ -1701,7 +1705,7 @@ int bitmap_create(struct mddev *mddev) ...@@ -1701,7 +1705,7 @@ int bitmap_create(struct mddev *mddev)
bitmap = kzalloc(sizeof(*bitmap), GFP_KERNEL); bitmap = kzalloc(sizeof(*bitmap), GFP_KERNEL);
if (!bitmap) if (!bitmap)
return -ENOMEM; return ERR_PTR(-ENOMEM);
spin_lock_init(&bitmap->counts.lock); spin_lock_init(&bitmap->counts.lock);
atomic_set(&bitmap->pending_writes, 0); atomic_set(&bitmap->pending_writes, 0);
...@@ -1710,6 +1714,7 @@ int bitmap_create(struct mddev *mddev) ...@@ -1710,6 +1714,7 @@ int bitmap_create(struct mddev *mddev)
init_waitqueue_head(&bitmap->behind_wait); init_waitqueue_head(&bitmap->behind_wait);
bitmap->mddev = mddev; bitmap->mddev = mddev;
bitmap->cluster_slot = slot;
if (mddev->kobj.sd) if (mddev->kobj.sd)
bm = sysfs_get_dirent(mddev->kobj.sd, "bitmap"); bm = sysfs_get_dirent(mddev->kobj.sd, "bitmap");
...@@ -1757,12 +1762,14 @@ int bitmap_create(struct mddev *mddev) ...@@ -1757,12 +1762,14 @@ int bitmap_create(struct mddev *mddev)
printk(KERN_INFO "created bitmap (%lu pages) for device %s\n", printk(KERN_INFO "created bitmap (%lu pages) for device %s\n",
bitmap->counts.pages, bmname(bitmap)); bitmap->counts.pages, bmname(bitmap));
mddev->bitmap = bitmap; err = test_bit(BITMAP_WRITE_ERROR, &bitmap->flags) ? -EIO : 0;
return test_bit(BITMAP_WRITE_ERROR, &bitmap->flags) ? -EIO : 0; if (err)
goto error;
return bitmap;
error: error:
bitmap_free(bitmap); bitmap_free(bitmap);
return err; return ERR_PTR(err);
} }
int bitmap_load(struct mddev *mddev) int bitmap_load(struct mddev *mddev)
...@@ -2073,14 +2080,19 @@ location_store(struct mddev *mddev, const char *buf, size_t len) ...@@ -2073,14 +2080,19 @@ location_store(struct mddev *mddev, const char *buf, size_t len)
return -EINVAL; return -EINVAL;
mddev->bitmap_info.offset = offset; mddev->bitmap_info.offset = offset;
if (mddev->pers) { if (mddev->pers) {
struct bitmap *bitmap;
mddev->pers->quiesce(mddev, 1); mddev->pers->quiesce(mddev, 1);
rv = bitmap_create(mddev); bitmap = bitmap_create(mddev, -1);
if (!rv) if (IS_ERR(bitmap))
rv = PTR_ERR(bitmap);
else {
mddev->bitmap = bitmap;
rv = bitmap_load(mddev); rv = bitmap_load(mddev);
if (rv) { if (rv) {
bitmap_destroy(mddev); bitmap_destroy(mddev);
mddev->bitmap_info.offset = 0; mddev->bitmap_info.offset = 0;
} }
}
mddev->pers->quiesce(mddev, 0); mddev->pers->quiesce(mddev, 0);
if (rv) if (rv)
return rv; return rv;
......
...@@ -233,7 +233,7 @@ struct bitmap { ...@@ -233,7 +233,7 @@ struct bitmap {
/* the bitmap API */ /* the bitmap API */
/* these are used only by md/bitmap */ /* these are used only by md/bitmap */
int bitmap_create(struct mddev *mddev); struct bitmap *bitmap_create(struct mddev *mddev, int slot);
int bitmap_load(struct mddev *mddev); int bitmap_load(struct mddev *mddev);
void bitmap_flush(struct mddev *mddev); void bitmap_flush(struct mddev *mddev);
void bitmap_destroy(struct mddev *mddev); void bitmap_destroy(struct mddev *mddev);
......
...@@ -5076,10 +5076,16 @@ int md_run(struct mddev *mddev) ...@@ -5076,10 +5076,16 @@ int md_run(struct mddev *mddev)
} }
if (err == 0 && pers->sync_request && if (err == 0 && pers->sync_request &&
(mddev->bitmap_info.file || mddev->bitmap_info.offset)) { (mddev->bitmap_info.file || mddev->bitmap_info.offset)) {
err = bitmap_create(mddev); struct bitmap *bitmap;
if (err)
bitmap = bitmap_create(mddev, -1);
if (IS_ERR(bitmap)) {
err = PTR_ERR(bitmap);
printk(KERN_ERR "%s: failed to create bitmap (%d)\n", printk(KERN_ERR "%s: failed to create bitmap (%d)\n",
mdname(mddev), err); mdname(mddev), err);
} else
mddev->bitmap = bitmap;
} }
if (err) { if (err) {
mddev_detach(mddev); mddev_detach(mddev);
...@@ -6039,10 +6045,14 @@ static int set_bitmap_file(struct mddev *mddev, int fd) ...@@ -6039,10 +6045,14 @@ static int set_bitmap_file(struct mddev *mddev, int fd)
if (mddev->pers) { if (mddev->pers) {
mddev->pers->quiesce(mddev, 1); mddev->pers->quiesce(mddev, 1);
if (fd >= 0) { if (fd >= 0) {
err = bitmap_create(mddev); struct bitmap *bitmap;
if (!err)
bitmap = bitmap_create(mddev, -1);
if (!IS_ERR(bitmap)) {
mddev->bitmap = bitmap;
err = bitmap_load(mddev); err = bitmap_load(mddev);
} }
}
if (fd < 0 || err) { if (fd < 0 || err) {
bitmap_destroy(mddev); bitmap_destroy(mddev);
fd = -1; /* make sure to put the file */ fd = -1; /* make sure to put the file */
...@@ -6306,6 +6316,7 @@ static int update_array_info(struct mddev *mddev, mdu_array_info_t *info) ...@@ -6306,6 +6316,7 @@ static int update_array_info(struct mddev *mddev, mdu_array_info_t *info)
if (mddev->recovery || mddev->sync_thread) if (mddev->recovery || mddev->sync_thread)
return -EBUSY; return -EBUSY;
if (info->state & (1<<MD_SB_BITMAP_PRESENT)) { if (info->state & (1<<MD_SB_BITMAP_PRESENT)) {
struct bitmap *bitmap;
/* add the bitmap */ /* add the bitmap */
if (mddev->bitmap) if (mddev->bitmap)
return -EEXIST; return -EEXIST;
...@@ -6316,9 +6327,11 @@ static int update_array_info(struct mddev *mddev, mdu_array_info_t *info) ...@@ -6316,9 +6327,11 @@ static int update_array_info(struct mddev *mddev, mdu_array_info_t *info)
mddev->bitmap_info.space = mddev->bitmap_info.space =
mddev->bitmap_info.default_space; mddev->bitmap_info.default_space;
mddev->pers->quiesce(mddev, 1); mddev->pers->quiesce(mddev, 1);
rv = bitmap_create(mddev); bitmap = bitmap_create(mddev, -1);
if (!rv) if (!IS_ERR(bitmap)) {
mddev->bitmap = bitmap;
rv = bitmap_load(mddev); rv = bitmap_load(mddev);
}
if (rv) if (rv)
bitmap_destroy(mddev); bitmap_destroy(mddev);
mddev->pers->quiesce(mddev, 0); mddev->pers->quiesce(mddev, 0);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment