diff options
author | Jonathan Brassow <jbrassow@redhat.com> | 2011-01-13 17:14:34 -0500 |
---|---|---|
committer | NeilBrown <neilb@suse.de> | 2011-01-13 17:14:34 -0500 |
commit | a6ff7e089c7fca813c956ccbed824087e89a3a49 (patch) | |
tree | 6537f72a2431c30601736676e9b1f89a7f1fe52e /drivers/md | |
parent | ccebd4c4159462c96397ae9af9c667bb394d7b70 (diff) |
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: NeilBrown <neilb@suse.de>
Diffstat (limited to 'drivers/md')
-rw-r--r-- | drivers/md/bitmap.c | 6 | ||||
-rw-r--r-- | drivers/md/md.c | 10 | ||||
-rw-r--r-- | drivers/md/md.h | 6 |
3 files changed, 17 insertions, 5 deletions
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c index 1977765ff964..6cf587196b99 100644 --- a/drivers/md/bitmap.c +++ b/drivers/md/bitmap.c | |||
@@ -264,14 +264,18 @@ static mdk_rdev_t *next_active_rdev(mdk_rdev_t *rdev, mddev_t *mddev) | |||
264 | static int write_sb_page(struct bitmap *bitmap, struct page *page, int wait) | 264 | static int write_sb_page(struct bitmap *bitmap, struct page *page, int wait) |
265 | { | 265 | { |
266 | mdk_rdev_t *rdev = NULL; | 266 | mdk_rdev_t *rdev = NULL; |
267 | struct block_device *bdev; | ||
267 | mddev_t *mddev = bitmap->mddev; | 268 | mddev_t *mddev = bitmap->mddev; |
268 | 269 | ||
269 | while ((rdev = next_active_rdev(rdev, mddev)) != NULL) { | 270 | while ((rdev = next_active_rdev(rdev, mddev)) != NULL) { |
270 | int size = PAGE_SIZE; | 271 | int size = PAGE_SIZE; |
271 | loff_t offset = mddev->bitmap_info.offset; | 272 | loff_t offset = mddev->bitmap_info.offset; |
273 | |||
274 | bdev = (rdev->meta_bdev) ? rdev->meta_bdev : rdev->bdev; | ||
275 | |||
272 | if (page->index == bitmap->file_pages-1) | 276 | if (page->index == bitmap->file_pages-1) |
273 | size = roundup(bitmap->last_page_size, | 277 | size = roundup(bitmap->last_page_size, |
274 | bdev_logical_block_size(rdev->bdev)); | 278 | bdev_logical_block_size(bdev)); |
275 | /* Just make sure we aren't corrupting data or | 279 | /* Just make sure we aren't corrupting data or |
276 | * metadata | 280 | * metadata |
277 | */ | 281 | */ |
diff --git a/drivers/md/md.c b/drivers/md/md.c index 0bc10cc4b961..b98a85fd10b6 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -765,7 +765,7 @@ void md_super_write(mddev_t *mddev, mdk_rdev_t *rdev, | |||
765 | */ | 765 | */ |
766 | struct bio *bio = bio_alloc_mddev(GFP_NOIO, 1, mddev); | 766 | struct bio *bio = bio_alloc_mddev(GFP_NOIO, 1, mddev); |
767 | 767 | ||
768 | bio->bi_bdev = rdev->bdev; | 768 | bio->bi_bdev = rdev->meta_bdev ? rdev->meta_bdev : rdev->bdev; |
769 | bio->bi_sector = sector; | 769 | bio->bi_sector = sector; |
770 | bio_add_page(bio, page, size, 0); | 770 | bio_add_page(bio, page, size, 0); |
771 | bio->bi_private = rdev; | 771 | bio->bi_private = rdev; |
@@ -803,7 +803,8 @@ int sync_page_io(mdk_rdev_t *rdev, sector_t sector, int size, | |||
803 | 803 | ||
804 | rw |= REQ_SYNC | REQ_UNPLUG; | 804 | rw |= REQ_SYNC | REQ_UNPLUG; |
805 | 805 | ||
806 | bio->bi_bdev = rdev->bdev; | 806 | bio->bi_bdev = (metadata_op && rdev->meta_bdev) ? |
807 | rdev->meta_bdev : rdev->bdev; | ||
807 | if (metadata_op) | 808 | if (metadata_op) |
808 | bio->bi_sector = sector + rdev->sb_start; | 809 | bio->bi_sector = sector + rdev->sb_start; |
809 | else | 810 | else |
@@ -4435,7 +4436,9 @@ int md_run(mddev_t *mddev) | |||
4435 | * We don't want the data to overlap the metadata, | 4436 | * We don't want the data to overlap the metadata, |
4436 | * Internal Bitmap issues have been handled elsewhere. | 4437 | * Internal Bitmap issues have been handled elsewhere. |
4437 | */ | 4438 | */ |
4438 | if (rdev->data_offset < rdev->sb_start) { | 4439 | if (rdev->meta_bdev) { |
4440 | /* Nothing to check */; | ||
4441 | } else if (rdev->data_offset < rdev->sb_start) { | ||
4439 | if (mddev->dev_sectors && | 4442 | if (mddev->dev_sectors && |
4440 | rdev->data_offset + mddev->dev_sectors | 4443 | rdev->data_offset + mddev->dev_sectors |
4441 | > rdev->sb_start) { | 4444 | > rdev->sb_start) { |
@@ -5532,7 +5535,6 @@ static int update_size(mddev_t *mddev, sector_t num_sectors) | |||
5532 | * sb_start or, if that is <data_offset, it must fit before the size | 5535 | * sb_start or, if that is <data_offset, it must fit before the size |
5533 | * of each device. If num_sectors is zero, we find the largest size | 5536 | * of each device. If num_sectors is zero, we find the largest size |
5534 | * that fits. | 5537 | * that fits. |
5535 | |||
5536 | */ | 5538 | */ |
5537 | if (mddev->sync_thread) | 5539 | if (mddev->sync_thread) |
5538 | return -EBUSY; | 5540 | return -EBUSY; |
diff --git a/drivers/md/md.h b/drivers/md/md.h index 7e4f358a26a6..eec517ced31a 100644 --- a/drivers/md/md.h +++ b/drivers/md/md.h | |||
@@ -60,6 +60,12 @@ struct mdk_rdev_s | |||
60 | mddev_t *mddev; /* RAID array if running */ | 60 | mddev_t *mddev; /* RAID array if running */ |
61 | int last_events; /* IO event timestamp */ | 61 | int last_events; /* IO event timestamp */ |
62 | 62 | ||
63 | /* | ||
64 | * If meta_bdev is non-NULL, it means that a separate device is | ||
65 | * being used to store the metadata (superblock/bitmap) which | ||
66 | * would otherwise be contained on the same device as the data (bdev). | ||
67 | */ | ||
68 | struct block_device *meta_bdev; | ||
63 | struct block_device *bdev; /* block device handle */ | 69 | struct block_device *bdev; /* block device handle */ |
64 | 70 | ||
65 | struct page *sb_page; | 71 | struct page *sb_page; |