Commit 512c3373 authored by Neil Brown's avatar Neil Brown Committed by Linus Torvalds

[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: default avatarNeil Brown <neilb@cse.unsw.edu.au>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 2353acb9
...@@ -748,7 +748,7 @@ static unsigned int calc_sb_1_csum(struct mdp_superblock_1 * sb) ...@@ -748,7 +748,7 @@ static unsigned int calc_sb_1_csum(struct mdp_superblock_1 * sb)
{ {
unsigned int disk_csum, csum; unsigned int disk_csum, csum;
unsigned long long newcsum; 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; unsigned int *isuper = (unsigned int*)sb;
int i; int i;
...@@ -763,7 +763,7 @@ static unsigned int calc_sb_1_csum(struct mdp_superblock_1 * sb) ...@@ -763,7 +763,7 @@ static unsigned int calc_sb_1_csum(struct mdp_superblock_1 * sb)
csum = (newcsum & 0xffffffff) + (newcsum >> 32); csum = (newcsum & 0xffffffff) + (newcsum >> 32);
sb->sb_csum = disk_csum; 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) 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) ...@@ -785,7 +785,7 @@ static int super_1_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version)
case 0: case 0:
sb_offset = rdev->bdev->bd_inode->i_size >> 9; sb_offset = rdev->bdev->bd_inode->i_size >> 9;
sb_offset -= 8*2; sb_offset -= 8*2;
sb_offset &= ~(4*2); sb_offset &= ~(4*2-1);
/* convert from sectors to K */ /* convert from sectors to K */
sb_offset /= 2; sb_offset /= 2;
break; break;
...@@ -818,6 +818,11 @@ static int super_1_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version) ...@@ -818,6 +818,11 @@ static int super_1_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version)
bdevname(rdev->bdev,b)); bdevname(rdev->bdev,b));
return -EINVAL; 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->preferred_minor = 0xffff;
rdev->data_offset = le64_to_cpu(sb->data_offset); 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) ...@@ -862,7 +867,6 @@ static int super_1_validate(mddev_t *mddev, mdk_rdev_t *rdev)
if (mddev->raid_disks == 0) { if (mddev->raid_disks == 0) {
mddev->major_version = 1; mddev->major_version = 1;
mddev->minor_version = 0;
mddev->patch_version = 0; mddev->patch_version = 0;
mddev->persistent = 1; mddev->persistent = 1;
mddev->chunk_size = le32_to_cpu(sb->chunksize) << 9; 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) ...@@ -871,7 +875,7 @@ static int super_1_validate(mddev_t *mddev, mdk_rdev_t *rdev)
mddev->level = le32_to_cpu(sb->level); mddev->level = le32_to_cpu(sb->level);
mddev->layout = le32_to_cpu(sb->layout); mddev->layout = le32_to_cpu(sb->layout);
mddev->raid_disks = le32_to_cpu(sb->raid_disks); 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->events = le64_to_cpu(sb->events);
mddev->recovery_cp = le64_to_cpu(sb->resync_offset); 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) ...@@ -939,7 +943,7 @@ static void super_1_sync(mddev_t *mddev, mdk_rdev_t *rdev)
if (rdev2->desc_nr > max_dev) if (rdev2->desc_nr > max_dev)
max_dev = rdev2->desc_nr; 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++) for (i=0; i<max_dev;i++)
sb->dev_roles[max_dev] = cpu_to_le16(0xfffe); sb->dev_roles[max_dev] = cpu_to_le16(0xfffe);
...@@ -1434,17 +1438,6 @@ static int analyze_sbs(mddev_t * mddev) ...@@ -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) && if ((mddev->recovery_cp != MaxSector) &&
((mddev->level == 1) || ((mddev->level == 1) ||
...@@ -1454,8 +1447,6 @@ static int analyze_sbs(mddev_t * mddev) ...@@ -1454,8 +1447,6 @@ static int analyze_sbs(mddev_t * mddev)
mdname(mddev)); mdname(mddev));
return 0; return 0;
abort:
return 1;
} }
int mdp_major = 0; int mdp_major = 0;
...@@ -1978,7 +1969,7 @@ static int get_array_info(mddev_t * mddev, void __user * arg) ...@@ -1978,7 +1969,7 @@ static int get_array_info(mddev_t * mddev, void __user * arg)
info.major_version = mddev->major_version; info.major_version = mddev->major_version;
info.minor_version = mddev->minor_version; info.minor_version = mddev->minor_version;
info.patch_version = 1; info.patch_version = MD_PATCHLEVEL_VERSION;
info.ctime = mddev->ctime; info.ctime = mddev->ctime;
info.level = mddev->level; info.level = mddev->level;
info.size = mddev->size; info.size = mddev->size;
......
...@@ -190,6 +190,7 @@ static int multipath_make_request (request_queue_t *q, struct bio * bio) ...@@ -190,6 +190,7 @@ static int multipath_make_request (request_queue_t *q, struct bio * bio)
multipath = conf->multipaths + mp_bh->path; multipath = conf->multipaths + mp_bh->path;
mp_bh->bio = *bio; 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_bdev = multipath->rdev->bdev;
mp_bh->bio.bi_rw |= (1 << BIO_RW_FAILFAST); mp_bh->bio.bi_rw |= (1 << BIO_RW_FAILFAST);
mp_bh->bio.bi_end_io = multipath_end_request; mp_bh->bio.bi_end_io = multipath_end_request;
...@@ -410,6 +411,7 @@ static void multipathd (mddev_t *mddev) ...@@ -410,6 +411,7 @@ static void multipathd (mddev_t *mddev)
bdevname(bio->bi_bdev,b), bdevname(bio->bi_bdev,b),
(unsigned long long)bio->bi_sector); (unsigned long long)bio->bi_sector);
*bio = *(mp_bh->master_bio); *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_bdev = conf->multipaths[mp_bh->path].rdev->bdev;
bio->bi_rw |= (1 << BIO_RW_FAILFAST); bio->bi_rw |= (1 << BIO_RW_FAILFAST);
bio->bi_end_io = multipath_end_request; bio->bi_end_io = multipath_end_request;
......
...@@ -1149,6 +1149,7 @@ static void sync_request_write(mddev_t *mddev, r10bio_t *r10_bio) ...@@ -1149,6 +1149,7 @@ static void sync_request_write(mddev_t *mddev, r10bio_t *r10_bio)
atomic_inc(&r10_bio->remaining); atomic_inc(&r10_bio->remaining);
md_sync_acct(conf->mirrors[d].rdev->bdev, tbio->bi_size >> 9); 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); generic_make_request(tbio);
} }
......
...@@ -60,7 +60,7 @@ ...@@ -60,7 +60,7 @@
*/ */
#define MD_MAJOR_VERSION 0 #define MD_MAJOR_VERSION 0
#define MD_MINOR_VERSION 90 #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 register_md_personality (int p_num, mdk_personality_t *p);
extern int unregister_md_personality (int p_num); extern int unregister_md_personality (int p_num);
......
...@@ -197,7 +197,7 @@ struct mdp_superblock_1 { ...@@ -197,7 +197,7 @@ struct mdp_superblock_1 {
__u32 chunksize; /* in 512byte sectors */ __u32 chunksize; /* in 512byte sectors */
__u32 raid_disks; __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 */ /* constant this-device information - 64 bytes */
__u64 data_offset; /* sector start of data, often 0 */ __u64 data_offset; /* sector start of data, often 0 */
...@@ -215,7 +215,7 @@ struct mdp_superblock_1 { ...@@ -215,7 +215,7 @@ struct mdp_superblock_1 {
__u64 resync_offset; /* data before this offset (from data_offset) known to be in sync */ __u64 resync_offset; /* data before this offset (from data_offset) known to be in sync */
__u32 sb_csum; /* checksum upto devs[max_dev] */ __u32 sb_csum; /* checksum upto devs[max_dev] */
__u32 max_dev; /* size of devs[] array to consider */ __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. /* device state information. Indexed by dev_number.
* 2 bytes per device * 2 bytes per device
......
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