DDF: factor out writing super block to single disk
Factor out single disk from __write_init_super_ddf to a new function _write_super_to_disk. Use this function in store_super_ddf. Signed-off-by: NeilBrown <neilb@suse.de>
This commit is contained in:
parent
8e9387ac9f
commit
9bf3870442
112
super-ddf.c
112
super-ddf.c
|
@ -2864,70 +2864,72 @@ out:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int _write_super_to_disk(struct ddf_super *ddf, struct dl *d)
|
||||||
|
{
|
||||||
|
unsigned long long size;
|
||||||
|
int fd = d->fd;
|
||||||
|
if (fd < 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* We need to fill in the primary, (secondary) and workspace
|
||||||
|
* lba's in the headers, set their checksums,
|
||||||
|
* Also checksum phys, virt....
|
||||||
|
*
|
||||||
|
* Then write everything out, finally the anchor is written.
|
||||||
|
*/
|
||||||
|
get_dev_size(fd, NULL, &size);
|
||||||
|
size /= 512;
|
||||||
|
if (d->workspace_lba != 0)
|
||||||
|
ddf->anchor.workspace_lba = d->workspace_lba;
|
||||||
|
else
|
||||||
|
ddf->anchor.workspace_lba =
|
||||||
|
__cpu_to_be64(size - 32*1024*2);
|
||||||
|
if (d->primary_lba != 0)
|
||||||
|
ddf->anchor.primary_lba = d->primary_lba;
|
||||||
|
else
|
||||||
|
ddf->anchor.primary_lba =
|
||||||
|
__cpu_to_be64(size - 16*1024*2);
|
||||||
|
if (d->secondary_lba != 0)
|
||||||
|
ddf->anchor.secondary_lba = d->secondary_lba;
|
||||||
|
else
|
||||||
|
ddf->anchor.secondary_lba =
|
||||||
|
__cpu_to_be64(size - 32*1024*2);
|
||||||
|
ddf->anchor.seq = ddf->active->seq;
|
||||||
|
memcpy(&ddf->primary, &ddf->anchor, 512);
|
||||||
|
memcpy(&ddf->secondary, &ddf->anchor, 512);
|
||||||
|
|
||||||
|
ddf->anchor.openflag = 0xFF; /* 'open' means nothing */
|
||||||
|
ddf->anchor.seq = 0xFFFFFFFF; /* no sequencing in anchor */
|
||||||
|
ddf->anchor.crc = calc_crc(&ddf->anchor, 512);
|
||||||
|
|
||||||
|
if (!__write_ddf_structure(d, ddf, DDF_HEADER_PRIMARY))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!__write_ddf_structure(d, ddf, DDF_HEADER_SECONDARY))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
lseek64(fd, (size-1)*512, SEEK_SET);
|
||||||
|
if (write(fd, &ddf->anchor, 512) < 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static int __write_init_super_ddf(struct supertype *st)
|
static int __write_init_super_ddf(struct supertype *st)
|
||||||
{
|
{
|
||||||
struct ddf_super *ddf = st->sb;
|
struct ddf_super *ddf = st->sb;
|
||||||
struct dl *d;
|
struct dl *d;
|
||||||
int attempts = 0;
|
int attempts = 0;
|
||||||
int successes = 0;
|
int successes = 0;
|
||||||
unsigned long long size;
|
|
||||||
__u32 seq;
|
|
||||||
|
|
||||||
pr_state(ddf, __func__);
|
pr_state(ddf, __func__);
|
||||||
|
|
||||||
seq = ddf->active->seq;
|
|
||||||
|
|
||||||
/* try to write updated metadata,
|
/* try to write updated metadata,
|
||||||
* if we catch a failure move on to the next disk
|
* if we catch a failure move on to the next disk
|
||||||
*/
|
*/
|
||||||
for (d = ddf->dlist; d; d=d->next) {
|
for (d = ddf->dlist; d; d=d->next) {
|
||||||
int fd = d->fd;
|
|
||||||
|
|
||||||
if (fd < 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
attempts++;
|
attempts++;
|
||||||
/* We need to fill in the primary, (secondary) and workspace
|
successes += _write_super_to_disk(ddf, d);
|
||||||
* lba's in the headers, set their checksums,
|
|
||||||
* Also checksum phys, virt....
|
|
||||||
*
|
|
||||||
* Then write everything out, finally the anchor is written.
|
|
||||||
*/
|
|
||||||
get_dev_size(fd, NULL, &size);
|
|
||||||
size /= 512;
|
|
||||||
if (d->workspace_lba != 0)
|
|
||||||
ddf->anchor.workspace_lba = d->workspace_lba;
|
|
||||||
else
|
|
||||||
ddf->anchor.workspace_lba =
|
|
||||||
__cpu_to_be64(size - 32*1024*2);
|
|
||||||
if (d->primary_lba != 0)
|
|
||||||
ddf->anchor.primary_lba = d->primary_lba;
|
|
||||||
else
|
|
||||||
ddf->anchor.primary_lba =
|
|
||||||
__cpu_to_be64(size - 16*1024*2);
|
|
||||||
if (d->secondary_lba != 0)
|
|
||||||
ddf->anchor.secondary_lba = d->secondary_lba;
|
|
||||||
else
|
|
||||||
ddf->anchor.secondary_lba =
|
|
||||||
__cpu_to_be64(size - 32*1024*2);
|
|
||||||
ddf->anchor.seq = seq;
|
|
||||||
memcpy(&ddf->primary, &ddf->anchor, 512);
|
|
||||||
memcpy(&ddf->secondary, &ddf->anchor, 512);
|
|
||||||
|
|
||||||
ddf->anchor.openflag = 0xFF; /* 'open' means nothing */
|
|
||||||
ddf->anchor.seq = 0xFFFFFFFF; /* no sequencing in anchor */
|
|
||||||
ddf->anchor.crc = calc_crc(&ddf->anchor, 512);
|
|
||||||
|
|
||||||
if (!__write_ddf_structure(d, ddf, DDF_HEADER_PRIMARY))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!__write_ddf_structure(d, ddf, DDF_HEADER_SECONDARY))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
lseek64(fd, (size-1)*512, SEEK_SET);
|
|
||||||
if (write(fd, &ddf->anchor, 512) < 0)
|
|
||||||
continue;
|
|
||||||
successes++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return attempts != successes;
|
return attempts != successes;
|
||||||
|
@ -3729,17 +3731,9 @@ static int store_super_ddf(struct supertype *st, int fd)
|
||||||
(int)minor(sta.st_rdev));
|
(int)minor(sta.st_rdev));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
For DDF, writing to just one disk makes no sense.
|
|
||||||
We would run the risk of writing inconsistent meta data
|
|
||||||
to the devices. So just call __write_init_super_ddf and
|
|
||||||
write to all devices, including this one.
|
|
||||||
Use the fd passed to this function, just in case dl->fd
|
|
||||||
is invalid.
|
|
||||||
*/
|
|
||||||
ofd = dl->fd;
|
ofd = dl->fd;
|
||||||
dl->fd = fd;
|
dl->fd = fd;
|
||||||
ret = __write_init_super_ddf(st);
|
ret = (_write_super_to_disk(ddf, dl) != 1);
|
||||||
dl->fd = ofd;
|
dl->fd = ofd;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue