Commit a6ff7e08 authored by Jonathan Brassow's avatar Jonathan Brassow Committed by NeilBrown

md: separate meta and data devs

Allow the metadata to be on a separate device from the
data.

This doesn't mean the data and metadata will by on separate
physical devices - it simply gives device-mapper and userspace
tools more flexibility.
Signed-off-by: default avatarNeilBrown <neilb@suse.de>
parent ccebd4c4
...@@ -264,14 +264,18 @@ static mdk_rdev_t *next_active_rdev(mdk_rdev_t *rdev, mddev_t *mddev) ...@@ -264,14 +264,18 @@ static mdk_rdev_t *next_active_rdev(mdk_rdev_t *rdev, mddev_t *mddev)
static int write_sb_page(struct bitmap *bitmap, struct page *page, int wait) static int write_sb_page(struct bitmap *bitmap, struct page *page, int wait)
{ {
mdk_rdev_t *rdev = NULL; mdk_rdev_t *rdev = NULL;
struct block_device *bdev;
mddev_t *mddev = bitmap->mddev; mddev_t *mddev = bitmap->mddev;
while ((rdev = next_active_rdev(rdev, mddev)) != NULL) { while ((rdev = next_active_rdev(rdev, mddev)) != NULL) {
int size = PAGE_SIZE; int size = PAGE_SIZE;
loff_t offset = mddev->bitmap_info.offset; loff_t offset = mddev->bitmap_info.offset;
bdev = (rdev->meta_bdev) ? rdev->meta_bdev : rdev->bdev;
if (page->index == bitmap->file_pages-1) if (page->index == bitmap->file_pages-1)
size = roundup(bitmap->last_page_size, size = roundup(bitmap->last_page_size,
bdev_logical_block_size(rdev->bdev)); bdev_logical_block_size(bdev));
/* Just make sure we aren't corrupting data or /* Just make sure we aren't corrupting data or
* metadata * metadata
*/ */
......
...@@ -765,7 +765,7 @@ void md_super_write(mddev_t *mddev, mdk_rdev_t *rdev, ...@@ -765,7 +765,7 @@ void md_super_write(mddev_t *mddev, mdk_rdev_t *rdev,
*/ */
struct bio *bio = bio_alloc_mddev(GFP_NOIO, 1, mddev); struct bio *bio = bio_alloc_mddev(GFP_NOIO, 1, mddev);
bio->bi_bdev = rdev->bdev; bio->bi_bdev = rdev->meta_bdev ? rdev->meta_bdev : rdev->bdev;
bio->bi_sector = sector; bio->bi_sector = sector;
bio_add_page(bio, page, size, 0); bio_add_page(bio, page, size, 0);
bio->bi_private = rdev; bio->bi_private = rdev;
...@@ -803,7 +803,8 @@ int sync_page_io(mdk_rdev_t *rdev, sector_t sector, int size, ...@@ -803,7 +803,8 @@ int sync_page_io(mdk_rdev_t *rdev, sector_t sector, int size,
rw |= REQ_SYNC | REQ_UNPLUG; rw |= REQ_SYNC | REQ_UNPLUG;
bio->bi_bdev = rdev->bdev; bio->bi_bdev = (metadata_op && rdev->meta_bdev) ?
rdev->meta_bdev : rdev->bdev;
if (metadata_op) if (metadata_op)
bio->bi_sector = sector + rdev->sb_start; bio->bi_sector = sector + rdev->sb_start;
else else
...@@ -4435,7 +4436,9 @@ int md_run(mddev_t *mddev) ...@@ -4435,7 +4436,9 @@ int md_run(mddev_t *mddev)
* We don't want the data to overlap the metadata, * We don't want the data to overlap the metadata,
* Internal Bitmap issues have been handled elsewhere. * Internal Bitmap issues have been handled elsewhere.
*/ */
if (rdev->data_offset < rdev->sb_start) { if (rdev->meta_bdev) {
/* Nothing to check */;
} else if (rdev->data_offset < rdev->sb_start) {
if (mddev->dev_sectors && if (mddev->dev_sectors &&
rdev->data_offset + mddev->dev_sectors rdev->data_offset + mddev->dev_sectors
> rdev->sb_start) { > rdev->sb_start) {
...@@ -5532,7 +5535,6 @@ static int update_size(mddev_t *mddev, sector_t num_sectors) ...@@ -5532,7 +5535,6 @@ static int update_size(mddev_t *mddev, sector_t num_sectors)
* sb_start or, if that is <data_offset, it must fit before the size * sb_start or, if that is <data_offset, it must fit before the size
* of each device. If num_sectors is zero, we find the largest size * of each device. If num_sectors is zero, we find the largest size
* that fits. * that fits.
*/ */
if (mddev->sync_thread) if (mddev->sync_thread)
return -EBUSY; return -EBUSY;
......
...@@ -60,6 +60,12 @@ struct mdk_rdev_s ...@@ -60,6 +60,12 @@ struct mdk_rdev_s
mddev_t *mddev; /* RAID array if running */ mddev_t *mddev; /* RAID array if running */
int last_events; /* IO event timestamp */ int last_events; /* IO event timestamp */
/*
* If meta_bdev is non-NULL, it means that a separate device is
* being used to store the metadata (superblock/bitmap) which
* would otherwise be contained on the same device as the data (bdev).
*/
struct block_device *meta_bdev;
struct block_device *bdev; /* block device handle */ struct block_device *bdev; /* block device handle */
struct page *sb_page; struct page *sb_page;
......
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