width = ti->len; if (sector_div(width, stripes)) {
ti->error = "Target length not divisible by number of stripes"; return -EINVAL;
}
tmp_len = width; if (sector_div(tmp_len, chunk_size)) {
ti->error = "Target length not divisible by chunk size"; return -EINVAL;
}
/* * Do we have enough arguments for that many stripes ?
*/ if (argc != (2 + 2 * stripes)) {
ti->error = "Not enough destinations specified"; return -EINVAL;
}
sc = kmalloc(struct_size(sc, stripe, stripes), GFP_KERNEL); if (!sc) {
ti->error = "Memory allocation for striped context failed"; return -ENOMEM;
}
INIT_WORK(&sc->trigger_event, trigger_event);
/* Set pointer to dm target; used in trigger_event */
sc->ti = ti;
sc->stripes = stripes;
sc->stripe_width = width;
switch (type) { case STATUSTYPE_INFO:
DMEMIT("%d ", sc->stripes); for (i = 0; i < sc->stripes; i++)
DMEMIT("%s ", sc->stripe[i].dev->name);
DMEMIT("1 "); for (i = 0; i < sc->stripes; i++)
DMEMIT("%c", atomic_read(&(sc->stripe[i].error_count)) ? 'D' : 'A'); break;
case STATUSTYPE_TABLE:
DMEMIT("%d %llu", sc->stripes,
(unsignedlonglong)sc->chunk_size); for (i = 0; i < sc->stripes; i++)
DMEMIT(" %s %llu", sc->stripe[i].dev->name,
(unsignedlonglong)sc->stripe[i].physical_start); break;
case STATUSTYPE_IMA:
DMEMIT_TARGET_NAME_VERSION(ti->type);
DMEMIT(",stripes=%d,chunk_size=%llu", sc->stripes,
(unsignedlonglong)sc->chunk_size);
for (i = 0; i < sc->stripes; i++) {
DMEMIT(",stripe_%d_device_name=%s", i, sc->stripe[i].dev->name);
DMEMIT(",stripe_%d_physical_start=%llu", i,
(unsignedlonglong)sc->stripe[i].physical_start);
DMEMIT(",stripe_%d_status=%c", i,
atomic_read(&(sc->stripe[i].error_count)) ? 'D' : 'A');
}
DMEMIT(";"); break;
}
}
if (!*error) return DM_ENDIO_DONE; /* I/O complete */
if (bio->bi_opf & REQ_RAHEAD) return DM_ENDIO_DONE;
if (*error == BLK_STS_NOTSUPP) return DM_ENDIO_DONE;
format_dev_t(major_minor, bio_dev(bio));
/* * Test to see which stripe drive triggered the event * and increment error count for all stripes on that device. * If the error count for a given device exceeds the threshold * value we will no longer trigger any further events.
*/ for (i = 0; i < sc->stripes; i++) if (!strcmp(sc->stripe[i].dev->name, major_minor)) {
atomic_inc(&(sc->stripe[i].error_count)); if (atomic_read(&(sc->stripe[i].error_count)) <
DM_IO_ERROR_THRESHOLD)
queue_work(dm_stripe_wq, &sc->trigger_event);
}
return DM_ENDIO_DONE;
}
staticint stripe_iterate_devices(struct dm_target *ti,
iterate_devices_callout_fn fn, void *data)
{ struct stripe_c *sc = ti->private; int ret = 0; unsignedint i = 0;
do {
ret = fn(ti, sc->stripe[i].dev,
sc->stripe[i].physical_start,
sc->stripe_width, data);
} while (!ret && ++i < sc->stripes);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.