aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md
diff options
context:
space:
mode:
authorJonathan Brassow <jbrassow@redhat.com>2011-01-13 17:14:34 -0500
committerNeilBrown <neilb@suse.de>2011-01-13 17:14:34 -0500
commita6ff7e089c7fca813c956ccbed824087e89a3a49 (patch)
tree6537f72a2431c30601736676e9b1f89a7f1fe52e /drivers/md
parentccebd4c4159462c96397ae9af9c667bb394d7b70 (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.c6
-rw-r--r--drivers/md/md.c10
-rw-r--r--drivers/md/md.h6
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)
264static int write_sb_page(struct bitmap *bitmap, struct page *page, int wait) 264static 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;