diff options
| author | Neil Brown <neilb@cse.unsw.edu.au> | 2004-10-25 04:13:38 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2004-10-25 04:13:38 -0700 |
| commit | 512c3373155cec986eb381e0c078f0e61d103eba (patch) | |
| tree | 5b2e97d75c1195bedce9ed1a32316d1868175849 | |
| parent | 2353acb9e6df9cd00de4cf157c4ded00102ff7ab (diff) | |
[PATCH] md: fixes to make version-1 superblocks work in md driver
Add some missing data_offset additions and some le_to_cpu convertions and fix
a few other little mistakes.
Signed-off-by: Neil Brown <neilb@cse.unsw.edu.au>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
| -rw-r--r-- | drivers/md/md.c | 31 | ||||
| -rw-r--r-- | drivers/md/multipath.c | 2 | ||||
| -rw-r--r-- | drivers/md/raid10.c | 1 | ||||
| -rw-r--r-- | include/linux/raid/md.h | 2 | ||||
| -rw-r--r-- | include/linux/raid/md_p.h | 4 |
5 files changed, 17 insertions, 23 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c index c8e7a5cb3b32..d3950b9edd48 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -748,7 +748,7 @@ static unsigned int calc_sb_1_csum(struct mdp_superblock_1 * sb) { unsigned int disk_csum, csum; unsigned long long newcsum; - int size = 256 + sb->max_dev*2; + int size = 256 + le32_to_cpu(sb->max_dev)*2; unsigned int *isuper = (unsigned int*)sb; int i; @@ -763,7 +763,7 @@ static unsigned int calc_sb_1_csum(struct mdp_superblock_1 * sb) csum = (newcsum & 0xffffffff) + (newcsum >> 32); sb->sb_csum = disk_csum; - return csum; + return cpu_to_le32(csum); } static int super_1_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version) @@ -785,7 +785,7 @@ static int super_1_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version) case 0: sb_offset = rdev->bdev->bd_inode->i_size >> 9; sb_offset -= 8*2; - sb_offset &= ~(4*2); + sb_offset &= ~(4*2-1); /* convert from sectors to K */ sb_offset /= 2; break; @@ -818,6 +818,11 @@ static int super_1_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version) bdevname(rdev->bdev,b)); return -EINVAL; } + if (le64_to_cpu(sb->data_size) < 10) { + printk("md: data_size too small on %s\n", + bdevname(rdev->bdev,b)); + return -EINVAL; + } rdev->preferred_minor = 0xffff; rdev->data_offset = le64_to_cpu(sb->data_offset); @@ -862,7 +867,6 @@ static int super_1_validate(mddev_t *mddev, mdk_rdev_t *rdev) if (mddev->raid_disks == 0) { mddev->major_version = 1; - mddev->minor_version = 0; mddev->patch_version = 0; mddev->persistent = 1; mddev->chunk_size = le32_to_cpu(sb->chunksize) << 9; @@ -871,7 +875,7 @@ static int super_1_validate(mddev_t *mddev, mdk_rdev_t *rdev) mddev->level = le32_to_cpu(sb->level); mddev->layout = le32_to_cpu(sb->layout); mddev->raid_disks = le32_to_cpu(sb->raid_disks); - mddev->size = (u32)le64_to_cpu(sb->size); + mddev->size = le64_to_cpu(sb->size)/2; mddev->events = le64_to_cpu(sb->events); mddev->recovery_cp = le64_to_cpu(sb->resync_offset); @@ -939,7 +943,7 @@ static void super_1_sync(mddev_t *mddev, mdk_rdev_t *rdev) if (rdev2->desc_nr > max_dev) max_dev = rdev2->desc_nr; - sb->max_dev = max_dev; + sb->max_dev = cpu_to_le32(max_dev); for (i=0; i<max_dev;i++) sb->dev_roles[max_dev] = cpu_to_le16(0xfffe); @@ -1434,17 +1438,6 @@ static int analyze_sbs(mddev_t * mddev) } - /* - * Check if we can support this RAID array - */ - if (mddev->major_version != MD_MAJOR_VERSION || - mddev->minor_version > MD_MINOR_VERSION) { - printk(KERN_ALERT - "md: %s: unsupported raid array version %d.%d.%d\n", - mdname(mddev), mddev->major_version, - mddev->minor_version, mddev->patch_version); - goto abort; - } if ((mddev->recovery_cp != MaxSector) && ((mddev->level == 1) || @@ -1454,8 +1447,6 @@ static int analyze_sbs(mddev_t * mddev) mdname(mddev)); return 0; -abort: - return 1; } int mdp_major = 0; @@ -1978,7 +1969,7 @@ static int get_array_info(mddev_t * mddev, void __user * arg) info.major_version = mddev->major_version; info.minor_version = mddev->minor_version; - info.patch_version = 1; + info.patch_version = MD_PATCHLEVEL_VERSION; info.ctime = mddev->ctime; info.level = mddev->level; info.size = mddev->size; diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c index 2877e8bdfc31..cbce9d22093e 100644 --- a/drivers/md/multipath.c +++ b/drivers/md/multipath.c @@ -190,6 +190,7 @@ static int multipath_make_request (request_queue_t *q, struct bio * bio) multipath = conf->multipaths + mp_bh->path; mp_bh->bio = *bio; + mp_bh->bio.bi_sector += multipath->rdev->data_offset; mp_bh->bio.bi_bdev = multipath->rdev->bdev; mp_bh->bio.bi_rw |= (1 << BIO_RW_FAILFAST); mp_bh->bio.bi_end_io = multipath_end_request; @@ -410,6 +411,7 @@ static void multipathd (mddev_t *mddev) bdevname(bio->bi_bdev,b), (unsigned long long)bio->bi_sector); *bio = *(mp_bh->master_bio); + bio->bi_sector += conf->multipaths[mp_bh->path].rdev->data_offset; bio->bi_bdev = conf->multipaths[mp_bh->path].rdev->bdev; bio->bi_rw |= (1 << BIO_RW_FAILFAST); bio->bi_end_io = multipath_end_request; diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 10f850affa27..9596358572e3 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -1149,6 +1149,7 @@ static void sync_request_write(mddev_t *mddev, r10bio_t *r10_bio) atomic_inc(&r10_bio->remaining); md_sync_acct(conf->mirrors[d].rdev->bdev, tbio->bi_size >> 9); + tbio->bi_sector += conf->mirrors[d].rdev->data_offset; generic_make_request(tbio); } diff --git a/include/linux/raid/md.h b/include/linux/raid/md.h index fad5699f5b7c..a6a67d102bfa 100644 --- a/include/linux/raid/md.h +++ b/include/linux/raid/md.h @@ -60,7 +60,7 @@ */ #define MD_MAJOR_VERSION 0 #define MD_MINOR_VERSION 90 -#define MD_PATCHLEVEL_VERSION 0 +#define MD_PATCHLEVEL_VERSION 1 extern int register_md_personality (int p_num, mdk_personality_t *p); extern int unregister_md_personality (int p_num); diff --git a/include/linux/raid/md_p.h b/include/linux/raid/md_p.h index 022b607bf9d8..8ba95d67329f 100644 --- a/include/linux/raid/md_p.h +++ b/include/linux/raid/md_p.h @@ -197,7 +197,7 @@ struct mdp_superblock_1 { __u32 chunksize; /* in 512byte sectors */ __u32 raid_disks; - __u8 pad1[128-92]; /* set to 0 when written */ + __u8 pad1[128-96]; /* set to 0 when written */ /* constant this-device information - 64 bytes */ __u64 data_offset; /* sector start of data, often 0 */ @@ -215,7 +215,7 @@ struct mdp_superblock_1 { __u64 resync_offset; /* data before this offset (from data_offset) known to be in sync */ __u32 sb_csum; /* checksum upto devs[max_dev] */ __u32 max_dev; /* size of devs[] array to consider */ - __u8 pad3[64-40]; /* set to 0 when writing */ + __u8 pad3[64-32]; /* set to 0 when writing */ /* device state information. Indexed by dev_number. * 2 bytes per device |
