return 0;
}
+static int raid1_verify_csum(blkid_probe pr, off_t off,
+ const struct mdp1_super_block *mdp1)
+{
+ size_t csummed_size = sizeof(struct mdp1_super_block)
+ + le32_to_cpu(mdp1->max_dev) * sizeof(mdp1->dev_roles[0]);
+ unsigned char *csummed = blkid_probe_get_buffer(pr, off, csummed_size);
+ if (!csummed)
+ return 1;
+
+ memset(csummed + offsetof(struct mdp1_super_block, sb_csum), 0,
+ sizeof(mdp1->sb_csum));
+
+ uint64_t csum = 0;
+
+ while (csummed_size >= 4) {
+ csum += le32_to_cpu(*(uint32_t *) csummed);
+ csummed_size -= 4;
+ csummed += 4;
+ }
+ if (csummed_size == 2)
+ csum += le16_to_cpu(*(uint16_t *) csummed);
+
+ csum = (csum >> 32) + (uint32_t) csum;
+ return blkid_probe_verify_csum(pr, csum, le32_to_cpu(mdp1->sb_csum));
+}
+
static int probe_raid1(blkid_probe pr, off_t off)
{
struct mdp1_super_block *mdp1;
return 1;
if (le64_to_cpu(mdp1->super_offset) != (uint64_t) off >> 9)
return 1;
+ if (!raid1_verify_csum(pr, off, mdp1))
+ return 1;
if (blkid_probe_set_uuid(pr, (unsigned char *) mdp1->set_uuid) != 0)
return 1;
if (blkid_probe_set_uuid_as(pr,