1
0
mirror of git://sourceware.org/git/lvm2.git synced 2024-12-21 13:34:40 +03:00

Write the location of both labels in the labels so we can check them. I don't do

much with this ATM (apart from check that they all match up).
Use a different CRC routine.
This commit is contained in:
Patrick Caulfield 2001-12-14 13:15:15 +00:00
parent 6b4657e81f
commit 515df8784a
2 changed files with 54 additions and 33 deletions

View File

@ -32,6 +32,8 @@ struct label_ondisk
{ {
uint32_t magic; uint32_t magic;
uint32_t crc; uint32_t crc;
uint64_t label1_loc;
uint64_t label2_loc;
uint16_t datalen; uint16_t datalen;
uint16_t pad; uint16_t pad;
@ -48,33 +50,25 @@ struct filter_private
}; };
/* CRC32 code taken from Linux kernel */ /* Calculate CRC32 of a buffer */
static int crc32( int initial, char * s, int length ) static uint32_t crc32(uint32_t initial, const unsigned char *databuf, size_t datalen)
{ {
/* indices */ uint32_t idx, crc = initial;
int perByte; static const u_int crctab[] = {
int perBit; 0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac,
0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c,
0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c
};
/* crc polynomial for Ethernet */ for (idx = 0; idx < datalen; idx++) {
const unsigned long poly = 0xedb88320; crc ^= *databuf++;
crc = (crc >> 4) ^ crctab[crc & 0xf];
/* crc value - carry over */ crc = (crc >> 4) ^ crctab[crc & 0xf];
unsigned long crc_value = initial; }
return crc;
for ( perByte = 0; perByte < length; perByte ++ ) {
unsigned char c;
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 */ /* Calculate crc */
static uint32_t calc_crc(struct label *label) static uint32_t calc_crc(struct label *label)
{ {
@ -89,6 +83,13 @@ static uint32_t calc_crc(struct label *label)
return crcval; return crcval;
} }
/* Calculate the locations we should find the labels in */
static inline void get_label_locations(uint64_t size, uint32_t sectsize, long *first, long *second)
{
*first = sectsize;
*second = size*BLOCK_SIZE - sectsize;
}
/* Read a label off disk - the data area is allocated /* Read a label off disk - the data area is allocated
from the pool in label->pool and should be freed by from the pool in label->pool and should be freed by
the caller */ the caller */
@ -100,6 +101,7 @@ int label_read(struct device *dev, struct label *label)
struct label_ondisk *ondisk; struct label_ondisk *ondisk;
int status; int status;
int iter; int iter;
long offset[2];
if (!dev_get_size(dev, &size)) if (!dev_get_size(dev, &size))
return 0; return 0;
@ -120,15 +122,12 @@ int label_read(struct device *dev, struct label *label)
return 0; return 0;
} }
ondisk = (struct label_ondisk *)block; ondisk = (struct label_ondisk *)block;
get_label_locations(size, sectsize, &offset[0], &offset[1]);
/* If the first label is bad then use the second */ /* If the first label is bad then use the second */
for (iter = 0; iter <= 1; iter++) for (iter = 0; iter <= 1; iter++)
{ {
if (iter == 0) status = dev_read(dev, offset[iter], sectsize, block);
status = dev_read(dev, sectsize, sectsize, block);
else
status = dev_read(dev, size*BLOCK_SIZE - sectsize, sectsize, block);
if (status) if (status)
{ {
struct label incore; struct label incore;
@ -156,6 +155,8 @@ int label_read(struct device *dev, struct label *label)
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]);
incore.label1_loc = xlate64(ondisk->label1_loc);
incore.label2_loc = xlate64(ondisk->label2_loc);
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); incore.crc = xlate32(ondisk->crc);
@ -172,6 +173,14 @@ int label_read(struct device *dev, struct label *label)
continue; continue;
} }
/* Check label locations match our view of the device */
if (incore.label1_loc != offset[0])
log_error("Label 1 location is wrong in label %d - check block size of the device\n",
iter);
if (incore.label2_loc != offset[1])
log_error("Label 2 location is wrong in label %d - the size of the device must have changed\n",
iter);
/* Copy to user's data area */ /* Copy to user's data area */
*label = incore; *label = incore;
label->data = pool_alloc(label_pool, incore.datalen); label->data = pool_alloc(label_pool, incore.datalen);
@ -202,6 +211,7 @@ 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;
long offset[2];
if (!dev_get_size(dev, &size)) if (!dev_get_size(dev, &size))
return 0; return 0;
@ -226,12 +236,18 @@ int label_write(struct device *dev, struct label *label)
/* Make sure the label has the right magic number in it */ /* Make sure the label has the right magic number in it */
label->magic = LABEL_MAGIC; label->magic = LABEL_MAGIC;
label->label1_loc = offset[0];
label->label2_loc = offset[1];
get_label_locations(size, sectsize, &offset[0], &offset[1]);
/* Make into ondisk format */ /* Make into ondisk format */
ondisk->magic = xlate32(LABEL_MAGIC); 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]);
ondisk->label1_loc = xlate64(offset[0]);
ondisk->label2_loc = xlate64(offset[1]);
ondisk->datalen = xlate16(label->datalen); ondisk->datalen = xlate16(label->datalen);
strncpy(ondisk->disk_type, label->disk_type, sizeof(ondisk->disk_type)); 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);
@ -244,13 +260,13 @@ int label_write(struct device *dev, struct label *label)
return 0; return 0;
} }
status1 = dev_write(dev, sectsize, sizeof(struct label_ondisk) + label->datalen, block); status1 = dev_write(dev, offset[0], sizeof(struct label_ondisk) + label->datalen, block);
if (!status1) if (!status1)
log_error("Error writing label 1\n"); log_error("Error writing label 1\n");
/* Write another at the end of the device */ /* Write another at the end of the device */
status2 = dev_write(dev, size*BLOCK_SIZE - sectsize, sizeof(struct label_ondisk) + label->datalen, block); status2 = dev_write(dev, offset[1], sizeof(struct label_ondisk) + label->datalen, block);
if (!status1) if (!status2)
log_error("Error writing label 2\n"); log_error("Error writing label 2\n");
pool_free(label_pool, block); pool_free(label_pool, block);
@ -419,6 +435,7 @@ int labels_match(struct device *dev)
struct label_ondisk *ondisk1; struct label_ondisk *ondisk1;
struct label_ondisk *ondisk2; struct label_ondisk *ondisk2;
int status = 0; int status = 0;
long offset[2];
if (!dev_get_size(dev, &size)) if (!dev_get_size(dev, &size))
return 0; return 0;
@ -447,14 +464,16 @@ int labels_match(struct device *dev)
ondisk1 = (struct label_ondisk *)block1; ondisk1 = (struct label_ondisk *)block1;
ondisk2 = (struct label_ondisk *)block2; ondisk2 = (struct label_ondisk *)block2;
get_label_locations(size, sectsize, &offset[0], &offset[1]);
/* Fetch em */ /* Fetch em */
if (!dev_open(dev, O_RDONLY)) if (!dev_open(dev, O_RDONLY))
goto finish; goto finish;
if (!dev_read(dev, sectsize, sectsize, block1)) if (!dev_read(dev, offset[0], sectsize, block1))
goto finish; goto finish;
if (!dev_read(dev, size*BLOCK_SIZE - sectsize, sectsize, block2)) if (!dev_read(dev, offset[1], sectsize, block2))
goto finish; goto finish;
dev_close(dev); dev_close(dev);

View File

@ -8,6 +8,8 @@ struct label
{ {
uint32_t magic; uint32_t magic;
uint32_t crc; uint32_t crc;
uint64_t label1_loc;
uint64_t label2_loc;
uint16_t datalen; uint16_t datalen;
char disk_type[32]; char disk_type[32];