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)
{
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;
......
......@@ -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;
......
......@@ -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);
}
......
......@@ -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);
......
......@@ -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
......
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