From: NeilBrown Add some missing data_offset additions and some le_to_cpu convertions and fix a few other little mistakes. Signed-off-by: Neil Brown Signed-off-by: Andrew Morton --- 25-akpm/drivers/md/md.c | 31 +++++++++++-------------------- 25-akpm/drivers/md/multipath.c | 2 ++ 25-akpm/drivers/md/raid10.c | 1 + 25-akpm/include/linux/raid/md.h | 2 +- 25-akpm/include/linux/raid/md_p.h | 4 ++-- 5 files changed, 17 insertions(+), 23 deletions(-) diff -puN drivers/md/md.c~md-fixes-to-make-version-1-superblocks-work-in-md-driver drivers/md/md.c --- 25/drivers/md/md.c~md-fixes-to-make-version-1-superblocks-work-in-md-driver Wed Oct 20 16:01:57 2004 +++ 25-akpm/drivers/md/md.c Wed Oct 20 16:01:58 2004 @@ -791,7 +791,7 @@ static unsigned int calc_sb_1_csum(struc { 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; @@ -806,7 +806,7 @@ static unsigned int calc_sb_1_csum(struc 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) @@ -828,7 +828,7 @@ static int super_1_load(mdk_rdev_t *rdev 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; @@ -861,6 +861,11 @@ static int super_1_load(mdk_rdev_t *rdev 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); @@ -905,7 +910,6 @@ static int super_1_validate(mddev_t *mdd 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; @@ -914,7 +918,7 @@ static int super_1_validate(mddev_t *mdd 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); @@ -982,7 +986,7 @@ static void super_1_sync(mddev_t *mddev, 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; idev_roles[max_dev] = cpu_to_le16(0xfffe); @@ -1477,17 +1481,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) || @@ -1497,8 +1490,6 @@ static int analyze_sbs(mddev_t * mddev) mdname(mddev)); return 0; -abort: - return 1; } int mdp_major = 0; @@ -2023,7 +2014,7 @@ static int get_array_info(mddev_t * mdde 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 -puN drivers/md/multipath.c~md-fixes-to-make-version-1-superblocks-work-in-md-driver drivers/md/multipath.c --- 25/drivers/md/multipath.c~md-fixes-to-make-version-1-superblocks-work-in-md-driver Wed Oct 20 16:01:57 2004 +++ 25-akpm/drivers/md/multipath.c Wed Oct 20 16:01:58 2004 @@ -209,6 +209,7 @@ static int multipath_make_request (reque 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; @@ -428,6 +429,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 -puN drivers/md/raid10.c~md-fixes-to-make-version-1-superblocks-work-in-md-driver drivers/md/raid10.c --- 25/drivers/md/raid10.c~md-fixes-to-make-version-1-superblocks-work-in-md-driver Wed Oct 20 16:01:57 2004 +++ 25-akpm/drivers/md/raid10.c Wed Oct 20 16:01:58 2004 @@ -1149,6 +1149,7 @@ static void sync_request_write(mddev_t * 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 -puN include/linux/raid/md.h~md-fixes-to-make-version-1-superblocks-work-in-md-driver include/linux/raid/md.h --- 25/include/linux/raid/md.h~md-fixes-to-make-version-1-superblocks-work-in-md-driver Wed Oct 20 16:01:57 2004 +++ 25-akpm/include/linux/raid/md.h Wed Oct 20 16:01:58 2004 @@ -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 -puN include/linux/raid/md_p.h~md-fixes-to-make-version-1-superblocks-work-in-md-driver include/linux/raid/md_p.h --- 25/include/linux/raid/md_p.h~md-fixes-to-make-version-1-superblocks-work-in-md-driver Wed Oct 20 16:01:58 2004 +++ 25-akpm/include/linux/raid/md_p.h Wed Oct 20 16:01:58 2004 @@ -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 _