mirror of
git://sourceware.org/git/lvm2.git
synced 2025-03-10 16:58:47 +03:00
Use a proper CRC calculation.
This commit is contained in:
parent
f4a7ce7c49
commit
8a51c23765
@ -28,11 +28,12 @@ static void *label_pool = NULL;
|
|||||||
struct label_ondisk
|
struct label_ondisk
|
||||||
{
|
{
|
||||||
uint32_t magic;
|
uint32_t magic;
|
||||||
uint32_t checksum;
|
uint32_t crc;
|
||||||
uint16_t datalen;
|
uint16_t datalen;
|
||||||
|
uint16_t pad;
|
||||||
|
|
||||||
char disk_type[32];
|
|
||||||
uint32_t version[3];
|
uint32_t version[3];
|
||||||
|
char disk_type[32];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct filter_private
|
struct filter_private
|
||||||
@ -44,29 +45,45 @@ struct filter_private
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* Calculate checksum */
|
/* CRC32 code taken from Linux kernel */
|
||||||
static uint32_t calc_checksum(struct label *label)
|
static int crc32( int initial, char * s, int length )
|
||||||
{
|
{
|
||||||
uint32_t csum = 0;
|
/* indices */
|
||||||
int i;
|
int perByte;
|
||||||
|
int perBit;
|
||||||
|
|
||||||
csum += label->magic;
|
/* crc polynomial for Ethernet */
|
||||||
csum += label->version[0];
|
const unsigned long poly = 0xedb88320;
|
||||||
csum += label->version[1];
|
|
||||||
csum += label->version[2];
|
|
||||||
csum += label->datalen;
|
|
||||||
|
|
||||||
for (i=0; i<label->datalen; i++)
|
/* crc value - carry over */
|
||||||
{
|
unsigned long crc_value = initial;
|
||||||
csum += label->data[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i=0; i<strlen(label->disk_type); i++)
|
for ( perByte = 0; perByte < length; perByte ++ ) {
|
||||||
{
|
unsigned char c;
|
||||||
csum += label->disk_type[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
return csum;
|
c = *(s++);
|
||||||
|
for ( perBit = 0; perBit < 8; perBit++ ) {
|
||||||
|
crc_value = (crc_value>>1)^
|
||||||
|
(((crc_value^c)&0x01)?poly:0);
|
||||||
|
c >>= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return crc_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Calculate crc */
|
||||||
|
static uint32_t calc_crc(struct label *label)
|
||||||
|
{
|
||||||
|
uint32_t crcval = 0xffffffff;
|
||||||
|
|
||||||
|
crcval = crc32(crcval, (char *)&label->magic, sizeof(label->magic));
|
||||||
|
crcval = crc32(crcval, (char *)&label->datalen, sizeof(label->datalen));
|
||||||
|
crcval = crc32(crcval, (char *)label->disk_type, strlen(label->disk_type));
|
||||||
|
crcval = crc32(crcval, (char *)&label->version, sizeof(label->version));
|
||||||
|
crcval = crc32(crcval, (char *)label->data, label->datalen);
|
||||||
|
|
||||||
|
return crcval;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read a label off disk - the data area is allocated
|
/* Read a label off disk - the data area is allocated
|
||||||
@ -131,25 +148,24 @@ int label_read(struct device *dev, struct label *label)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* Copy and convert endianness */
|
/* Copy and convert endianness */
|
||||||
|
strncpy(incore.disk_type, ondisk->disk_type, sizeof(incore.disk_type));
|
||||||
incore.magic = xlate32(ondisk->magic);
|
incore.magic = xlate32(ondisk->magic);
|
||||||
incore.version[0] = xlate32(ondisk->version[0]);
|
incore.version[0] = xlate32(ondisk->version[0]);
|
||||||
incore.version[1] = xlate32(ondisk->version[1]);
|
incore.version[1] = xlate32(ondisk->version[1]);
|
||||||
incore.version[2] = xlate32(ondisk->version[2]);
|
incore.version[2] = xlate32(ondisk->version[2]);
|
||||||
for (i=0; i<strlen(ondisk->disk_type)+1; i++)
|
|
||||||
incore.disk_type[i] = ondisk->disk_type[i];
|
|
||||||
incore.checksum = xlate32(ondisk->checksum);
|
|
||||||
incore.datalen = xlate16(ondisk->datalen);
|
incore.datalen = xlate16(ondisk->datalen);
|
||||||
incore.data = block + sizeof(struct label_ondisk);
|
incore.data = block + sizeof(struct label_ondisk);
|
||||||
|
incore.crc = xlate32(ondisk->crc);
|
||||||
|
|
||||||
/* Make sure datalen is a sensible size too */
|
/* Make sure datalen is a sensible size too */
|
||||||
if (incore.datalen > sectsize)
|
if (incore.datalen > sectsize)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* Check Checksum */
|
/* Check Crc */
|
||||||
if (incore.checksum != calc_checksum(&incore))
|
if (incore.crc != calc_crc(&incore))
|
||||||
{
|
{
|
||||||
log_error("Checksum %d on device %s does not match. got %x, expected %x",
|
log_error("Crc %d on device %s does not match. got %x, expected %x",
|
||||||
iter, dev_name(dev), incore.checksum, calc_checksum(&incore));
|
iter, dev_name(dev), incore.crc, calc_crc(&incore));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -183,7 +199,6 @@ int label_write(struct device *dev, struct label *label)
|
|||||||
char *block;
|
char *block;
|
||||||
struct label_ondisk *ondisk;
|
struct label_ondisk *ondisk;
|
||||||
int status1, status2;
|
int status1, status2;
|
||||||
int i;
|
|
||||||
|
|
||||||
if (!dev_get_size(dev, &size))
|
if (!dev_get_size(dev, &size))
|
||||||
return 0;
|
return 0;
|
||||||
@ -204,21 +219,20 @@ int label_write(struct device *dev, struct label *label)
|
|||||||
stack;
|
stack;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ondisk = (struct label_ondisk *)block;
|
ondisk = (struct label_ondisk *)block;
|
||||||
|
|
||||||
/* Make into ondisk format */
|
/* Make sure the label has the right magic number in it */
|
||||||
label->magic = LABEL_MAGIC;
|
label->magic = LABEL_MAGIC;
|
||||||
ondisk->magic = xlate32(LABEL_MAGIC);
|
|
||||||
|
|
||||||
|
/* Make into ondisk format */
|
||||||
|
ondisk->magic = xlate32(LABEL_MAGIC);
|
||||||
ondisk->version[0] = xlate32(label->version[0]);
|
ondisk->version[0] = xlate32(label->version[0]);
|
||||||
ondisk->version[1] = xlate32(label->version[1]);
|
ondisk->version[1] = xlate32(label->version[1]);
|
||||||
ondisk->version[2] = xlate32(label->version[2]);
|
ondisk->version[2] = xlate32(label->version[2]);
|
||||||
for (i=0; i<strlen(label->disk_type)+1; i++)
|
|
||||||
ondisk->disk_type[i] = label->disk_type[i];
|
|
||||||
ondisk->datalen = xlate16(label->datalen);
|
ondisk->datalen = xlate16(label->datalen);
|
||||||
ondisk->checksum = xlate32(calc_checksum(label));
|
strncpy(ondisk->disk_type, label->disk_type, sizeof(ondisk->disk_type));
|
||||||
memcpy(block+sizeof(struct label_ondisk), label->data, label->datalen);
|
memcpy(block+sizeof(struct label_ondisk), label->data, label->datalen);
|
||||||
|
ondisk->crc = xlate32(calc_crc(label));
|
||||||
|
|
||||||
/* Write metadata to disk */
|
/* Write metadata to disk */
|
||||||
if (!dev_open(dev, O_RDWR))
|
if (!dev_open(dev, O_RDWR))
|
||||||
@ -408,7 +422,7 @@ int labels_match(struct device *dev)
|
|||||||
if (label_pool == NULL)
|
if (label_pool == NULL)
|
||||||
label_pool = pool_create(512);
|
label_pool = pool_create(512);
|
||||||
|
|
||||||
/* ALlocate some space for the blocks we are going to read in */
|
/* Allocate some space for the blocks we are going to read in */
|
||||||
block1 = pool_alloc(label_pool, sectsize);
|
block1 = pool_alloc(label_pool, sectsize);
|
||||||
if (!block1)
|
if (!block1)
|
||||||
{
|
{
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
struct label
|
struct label
|
||||||
{
|
{
|
||||||
uint32_t magic;
|
uint32_t magic;
|
||||||
uint32_t checksum;
|
uint32_t crc;
|
||||||
uint16_t datalen;
|
uint16_t datalen;
|
||||||
|
|
||||||
char disk_type[32];
|
char disk_type[32];
|
||||||
|
Loading…
x
Reference in New Issue
Block a user