bitmap_create returns bitmap pointer
This is done to have multiple bitmaps open at the same time. Signed-off-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
This commit is contained in:
+36
-24
@@ -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)
|
|||||||
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 @@ re_read:
|
|||||||
|
|
||||||
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 @@ out:
|
|||||||
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 @@ out_no_sb:
|
|||||||
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)
|
|||||||
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)
|
|||||||
* 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)
|
|||||||
|
|
||||||
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)
|
|||||||
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)
|
|||||||
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,13 +2080,18 @@ 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)
|
||||||
|
|||||||
+1
-1
@@ -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);
|
||||||
|
|||||||
+19
-6
@@ -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,9 +6045,13 @@ 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);
|
||||||
@@ -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)
|
|||||||
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);
|
||||||
|
|||||||
Reference in New Issue
Block a user