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:
mwilck@arcor.de 2013-07-18 20:49:01 +02:00 committed by NeilBrown
parent 8e9387ac9f
commit 9bf3870442
1 changed files with 53 additions and 59 deletions

View File

@ -2864,70 +2864,72 @@ out:
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)
{
struct ddf_super *ddf = st->sb;
struct dl *d;
int attempts = 0;
int successes = 0;
unsigned long long size;
__u32 seq;
pr_state(ddf, __func__);
seq = ddf->active->seq;
/* try to write updated metadata,
* if we catch a failure move on to the next disk
*/
for (d = ddf->dlist; d; d=d->next) {
int fd = d->fd;
if (fd < 0)
continue;
attempts++;
/* 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 = 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++;
successes += _write_super_to_disk(ddf, d);
}
return attempts != successes;
@ -3729,17 +3731,9 @@ static int store_super_ddf(struct supertype *st, int fd)
(int)minor(sta.st_rdev));
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;
dl->fd = fd;
ret = __write_init_super_ddf(st);
ret = (_write_super_to_disk(ddf, dl) != 1);
dl->fd = ofd;
return ret;
}