On alpha systems, the kernel computed checksum, csum_partial(), and user space computed checksum are different. As a consequence, the kernel MD driver aborts detection of MD superblock. This means running mdadm --assemble -f or -U summaries will not always work. I have been wondering... Should MD driver use csum_partial() at all? The attached patch includes the checksum function found in mdadm code. If the architecture dependent checksum validation fails, at least try the common function (only for 0.90 superblock format). Regards, Mike T.
--- a/drivers/md/md.c 2004-06-16 00:19:03.000000000 -0500 +++ b/drivers/md/md.c 2004-07-12 18:18:31.000000000 -0500 @@ -439,6 +439,22 @@ return csum; } +static unsigned int calc_sb_csum_common(mdp_super_t *super) +{ + unsigned int disk_csum = super->sb_csum; + unsigned long long newcsum = 0; + unsigned int csum; + int i; + unsigned int *superc = (int*) super; + super->sb_csum = 0; + + for (i=0; i<MD_SB_BYTES/4; i++) + newcsum+= superc[i]; + csum = (newcsum& 0xffffffff) + (newcsum>>32); + super->sb_csum = disk_csum; + return csum; +} + /* * Handle superblock details. * We want to be able to handle multiple superblock formats @@ -522,10 +538,15 @@ goto abort; if (calc_sb_csum(sb) != sb->sb_csum) { + printk(KERN_WARNING "md: First attemp to validate checksum on %s failed." + " Trying the common method...\n", + b); + if (calc_sb_csum_common(sb) != sb->sb_csum) { printk(KERN_WARNING "md: invalid superblock checksum on %s\n", b); goto abort; } + } rdev->preferred_minor = sb->md_minor; rdev->data_offset = 0;