Reduce the number of metadata updates done by ddf.
1/ track if there are any actual updates pending, and only write metadata when we have changed something. 2/ when writing null virtual-configs, write full blocks, not just the first 4 bytes. This will allow O_DIRECT writes in a subsequent patch.
This commit is contained in:
parent
48561b0142
commit
18a2f463fd
50
super-ddf.c
50
super-ddf.c
|
@ -402,6 +402,7 @@ struct ddf_super {
|
||||||
int pdsize, vdsize;
|
int pdsize, vdsize;
|
||||||
int max_part, mppe, conf_rec_len;
|
int max_part, mppe, conf_rec_len;
|
||||||
int currentdev;
|
int currentdev;
|
||||||
|
int updates_pending;
|
||||||
struct vcl {
|
struct vcl {
|
||||||
struct vcl *next;
|
struct vcl *next;
|
||||||
__u64 *lba_offset; /* location in 'conf' of
|
__u64 *lba_offset; /* location in 'conf' of
|
||||||
|
@ -1590,6 +1591,7 @@ static int init_super_ddf(struct supertype *st,
|
||||||
memset(&vd->entries[i], 0xff, sizeof(struct virtual_entry));
|
memset(&vd->entries[i], 0xff, sizeof(struct virtual_entry));
|
||||||
|
|
||||||
st->sb = ddf;
|
st->sb = ddf;
|
||||||
|
ddf->updates_pending = 1;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1852,6 +1854,7 @@ static int init_super_ddf_bvd(struct supertype *st,
|
||||||
vcl->next = ddf->conflist;
|
vcl->next = ddf->conflist;
|
||||||
ddf->conflist = vcl;
|
ddf->conflist = vcl;
|
||||||
ddf->currentconf = vcl;
|
ddf->currentconf = vcl;
|
||||||
|
ddf->updates_pending = 1;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1943,6 +1946,7 @@ static void add_to_super_ddf_bvd(struct supertype *st,
|
||||||
|
|
||||||
ddf->phys->entries[dl->pdnum].type &= ~__cpu_to_be16(DDF_Global_Spare);
|
ddf->phys->entries[dl->pdnum].type &= ~__cpu_to_be16(DDF_Global_Spare);
|
||||||
ddf->phys->entries[dl->pdnum].type |= __cpu_to_be16(DDF_Active_in_VD);
|
ddf->phys->entries[dl->pdnum].type |= __cpu_to_be16(DDF_Active_in_VD);
|
||||||
|
ddf->updates_pending = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* add a device to a container, either while creating it or while
|
/* add a device to a container, either while creating it or while
|
||||||
|
@ -2021,6 +2025,7 @@ static void add_to_super_ddf(struct supertype *st,
|
||||||
|
|
||||||
dd->size = size >> 9;
|
dd->size = size >> 9;
|
||||||
ddf->dlist = dd;
|
ddf->dlist = dd;
|
||||||
|
ddf->updates_pending = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -2030,6 +2035,9 @@ static void add_to_super_ddf(struct supertype *st,
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef MDASSEMBLE
|
#ifndef MDASSEMBLE
|
||||||
|
|
||||||
|
static unsigned char null_conf[4096];
|
||||||
|
|
||||||
static int __write_init_super_ddf(struct supertype *st, int do_close)
|
static int __write_init_super_ddf(struct supertype *st, int do_close)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -2100,9 +2108,14 @@ static int __write_init_super_ddf(struct supertype *st, int do_close)
|
||||||
c->conf.crc = calc_crc(&c->conf, conf_size);
|
c->conf.crc = calc_crc(&c->conf, conf_size);
|
||||||
write(fd, &c->conf, conf_size);
|
write(fd, &c->conf, conf_size);
|
||||||
} else {
|
} else {
|
||||||
__u32 sig = 0xffffffff;
|
if (null_conf[0] != 0xff)
|
||||||
write(fd, &sig, 4);
|
memset(null_conf, 0xff, sizeof(null_conf));
|
||||||
lseek64(fd, conf_size-4, SEEK_CUR);
|
int togo = conf_size;
|
||||||
|
while (togo > sizeof(null_conf)) {
|
||||||
|
write(fd, null_conf, sizeof(null_conf));
|
||||||
|
togo -= sizeof(null_conf);
|
||||||
|
}
|
||||||
|
write(fd, null_conf, togo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
d->disk.crc = calc_crc(&d->disk, 512);
|
d->disk.crc = calc_crc(&d->disk, 512);
|
||||||
|
@ -2632,10 +2645,15 @@ static void ddf_set_array_state(struct active_array *a, int consistent)
|
||||||
{
|
{
|
||||||
struct ddf_super *ddf = a->container->sb;
|
struct ddf_super *ddf = a->container->sb;
|
||||||
int inst = a->info.container_member;
|
int inst = a->info.container_member;
|
||||||
|
int old = ddf->virt->entries[inst].state;
|
||||||
if (consistent)
|
if (consistent)
|
||||||
ddf->virt->entries[inst].state &= ~DDF_state_inconsistent;
|
ddf->virt->entries[inst].state &= ~DDF_state_inconsistent;
|
||||||
else
|
else
|
||||||
ddf->virt->entries[inst].state |= DDF_state_inconsistent;
|
ddf->virt->entries[inst].state |= DDF_state_inconsistent;
|
||||||
|
if (old != ddf->virt->entries[inst].state)
|
||||||
|
ddf->updates_pending = 1;
|
||||||
|
|
||||||
|
old = ddf->virt->entries[inst].init_state;
|
||||||
ddf->virt->entries[inst].init_state &= ~DDF_initstate_mask;
|
ddf->virt->entries[inst].init_state &= ~DDF_initstate_mask;
|
||||||
if (a->resync_start == ~0ULL)
|
if (a->resync_start == ~0ULL)
|
||||||
ddf->virt->entries[inst].init_state |= DDF_init_full;
|
ddf->virt->entries[inst].init_state |= DDF_init_full;
|
||||||
|
@ -2643,8 +2661,10 @@ static void ddf_set_array_state(struct active_array *a, int consistent)
|
||||||
ddf->virt->entries[inst].init_state |= DDF_init_not;
|
ddf->virt->entries[inst].init_state |= DDF_init_not;
|
||||||
else
|
else
|
||||||
ddf->virt->entries[inst].init_state |= DDF_init_quick;
|
ddf->virt->entries[inst].init_state |= DDF_init_quick;
|
||||||
|
if (old != ddf->virt->entries[inst].init_state)
|
||||||
|
ddf->updates_pending = 1;
|
||||||
|
|
||||||
printf("ddf mark %s %llu\n", consistent?"clean":"dirty",
|
printf("ddf mark %d %s %llu\n", inst, consistent?"clean":"dirty",
|
||||||
a->resync_start);
|
a->resync_start);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2685,12 +2705,15 @@ static void ddf_set_disk(struct active_array *a, int n, int state)
|
||||||
/* FIXME */
|
/* FIXME */
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
int old = ddf->phys->entries[pd].state;
|
||||||
if (state & DS_FAULTY)
|
if (state & DS_FAULTY)
|
||||||
ddf->phys->entries[pd].state |= __cpu_to_be16(DDF_Failed);
|
ddf->phys->entries[pd].state |= __cpu_to_be16(DDF_Failed);
|
||||||
if (state & DS_INSYNC) {
|
if (state & DS_INSYNC) {
|
||||||
ddf->phys->entries[pd].state |= __cpu_to_be16(DDF_Online);
|
ddf->phys->entries[pd].state |= __cpu_to_be16(DDF_Online);
|
||||||
ddf->phys->entries[pd].state &= __cpu_to_be16(~DDF_Rebuilding);
|
ddf->phys->entries[pd].state &= __cpu_to_be16(~DDF_Rebuilding);
|
||||||
}
|
}
|
||||||
|
if (old != ddf->phys->entries[pd].state)
|
||||||
|
ddf->updates_pending = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(stderr, "ddf: set_disk %d to %x\n", n, state);
|
fprintf(stderr, "ddf: set_disk %d to %x\n", n, state);
|
||||||
|
@ -2736,9 +2759,15 @@ static void ddf_set_disk(struct active_array *a, int n, int state)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ddf->virt->entries[inst].state =
|
if (ddf->virt->entries[inst].state !=
|
||||||
(ddf->virt->entries[inst].state & ~DDF_state_mask)
|
((ddf->virt->entries[inst].state & ~DDF_state_mask)
|
||||||
| state;
|
| state)) {
|
||||||
|
|
||||||
|
ddf->virt->entries[inst].state =
|
||||||
|
(ddf->virt->entries[inst].state & ~DDF_state_mask)
|
||||||
|
| state;
|
||||||
|
ddf->updates_pending = 1;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2752,6 +2781,10 @@ static void ddf_sync_metadata(struct supertype *st)
|
||||||
* but ddf is sufficiently weird that it probably always
|
* but ddf is sufficiently weird that it probably always
|
||||||
* changes global data ....
|
* changes global data ....
|
||||||
*/
|
*/
|
||||||
|
struct ddf_super *ddf = st->sb;
|
||||||
|
if (!ddf->updates_pending)
|
||||||
|
return;
|
||||||
|
ddf->updates_pending = 0;
|
||||||
__write_init_super_ddf(st, 0);
|
__write_init_super_ddf(st, 0);
|
||||||
fprintf(stderr, "ddf: sync_metadata\n");
|
fprintf(stderr, "ddf: sync_metadata\n");
|
||||||
}
|
}
|
||||||
|
@ -2814,6 +2847,7 @@ static void ddf_process_update(struct supertype *st,
|
||||||
ddf->phys->entries[ent] = pd->entries[0];
|
ddf->phys->entries[ent] = pd->entries[0];
|
||||||
ddf->phys->used_pdes = __cpu_to_be16(1 +
|
ddf->phys->used_pdes = __cpu_to_be16(1 +
|
||||||
__be16_to_cpu(ddf->phys->used_pdes));
|
__be16_to_cpu(ddf->phys->used_pdes));
|
||||||
|
ddf->updates_pending = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DDF_VIRT_RECORDS_MAGIC:
|
case DDF_VIRT_RECORDS_MAGIC:
|
||||||
|
@ -2831,6 +2865,7 @@ static void ddf_process_update(struct supertype *st,
|
||||||
ddf->virt->entries[ent] = vd->entries[0];
|
ddf->virt->entries[ent] = vd->entries[0];
|
||||||
ddf->virt->populated_vdes = __cpu_to_be16(1 +
|
ddf->virt->populated_vdes = __cpu_to_be16(1 +
|
||||||
__be16_to_cpu(ddf->virt->populated_vdes));
|
__be16_to_cpu(ddf->virt->populated_vdes));
|
||||||
|
ddf->updates_pending = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DDF_VD_CONF_MAGIC:
|
case DDF_VD_CONF_MAGIC:
|
||||||
|
@ -2895,6 +2930,7 @@ static void ddf_process_update(struct supertype *st,
|
||||||
DDF_Active_in_VD);
|
DDF_Active_in_VD);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ddf->updates_pending = 1;
|
||||||
break;
|
break;
|
||||||
case DDF_SPARE_ASSIGN_MAGIC:
|
case DDF_SPARE_ASSIGN_MAGIC:
|
||||||
default: break;
|
default: break;
|
||||||
|
|
Loading…
Reference in New Issue