diff options
author | trasz <trasz@FreeBSD.org> | 2015-10-18 15:02:07 +0000 |
---|---|---|
committer | trasz <trasz@FreeBSD.org> | 2015-10-18 15:02:07 +0000 |
commit | d6b9751caa717b8d02a00cafb7977c10b0b24cac (patch) | |
tree | 6434c089b638829b51031f7231aec39cf56d7e45 /sys/geom/nop | |
parent | 669694f0678ab1c67d085d94eba43fcd56be66ef (diff) | |
download | FreeBSD-src-d6b9751caa717b8d02a00cafb7977c10b0b24cac.zip FreeBSD-src-d6b9751caa717b8d02a00cafb7977c10b0b24cac.tar.gz |
MFC r287827:
Add a way to specify stripesize and stripeoffset to gnop(8). This makes
it possible to "simulate" 4K media, to eg test alignment handling.
Sponsored by: The FreeBSD Foundation
Diffstat (limited to 'sys/geom/nop')
-rw-r--r-- | sys/geom/nop/g_nop.c | 42 | ||||
-rw-r--r-- | sys/geom/nop/g_nop.h | 2 |
2 files changed, 41 insertions, 3 deletions
diff --git a/sys/geom/nop/g_nop.c b/sys/geom/nop/g_nop.c index bd72d78..837f3f4 100644 --- a/sys/geom/nop/g_nop.c +++ b/sys/geom/nop/g_nop.c @@ -162,7 +162,7 @@ g_nop_access(struct g_provider *pp, int dr, int dw, int de) static int g_nop_create(struct gctl_req *req, struct g_class *mp, struct g_provider *pp, int ioerror, u_int rfailprob, u_int wfailprob, off_t offset, off_t size, - u_int secsize) + u_int secsize, u_int stripesize, u_int stripeoffset) { struct g_nop_softc *sc; struct g_geom *gp; @@ -208,6 +208,18 @@ g_nop_create(struct gctl_req *req, struct g_class *mp, struct g_provider *pp, return (EINVAL); } size -= size % secsize; + if ((stripesize % pp->sectorsize) != 0) { + gctl_error(req, "Invalid stripesize for provider %s.", pp->name); + return (EINVAL); + } + if ((stripeoffset % pp->sectorsize) != 0) { + gctl_error(req, "Invalid stripeoffset for provider %s.", pp->name); + return (EINVAL); + } + if (stripesize != 0 && stripeoffset >= stripesize) { + gctl_error(req, "stripeoffset is too big."); + return (EINVAL); + } snprintf(name, sizeof(name), "%s%s", pp->name, G_NOP_SUFFIX); LIST_FOREACH(gp, &mp->geom, geom) { if (strcmp(gp->name, name) == 0) { @@ -219,6 +231,8 @@ g_nop_create(struct gctl_req *req, struct g_class *mp, struct g_provider *pp, sc = g_malloc(sizeof(*sc), M_WAITOK | M_ZERO); sc->sc_offset = offset; sc->sc_explicitsize = explicitsize; + sc->sc_stripesize = stripesize; + sc->sc_stripeoffset = stripeoffset; sc->sc_error = ioerror; sc->sc_rfailprob = rfailprob; sc->sc_wfailprob = wfailprob; @@ -238,6 +252,8 @@ g_nop_create(struct gctl_req *req, struct g_class *mp, struct g_provider *pp, newpp->flags |= G_PF_DIRECT_SEND | G_PF_DIRECT_RECEIVE; newpp->mediasize = size; newpp->sectorsize = secsize; + newpp->stripesize = stripesize; + newpp->stripeoffset = stripeoffset; cp = g_new_consumer(gp); cp->flags |= G_CF_DIRECT_SEND | G_CF_DIRECT_RECEIVE; @@ -304,7 +320,8 @@ static void g_nop_ctl_create(struct gctl_req *req, struct g_class *mp) { struct g_provider *pp; - intmax_t *error, *rfailprob, *wfailprob, *offset, *secsize, *size; + intmax_t *error, *rfailprob, *wfailprob, *offset, *secsize, *size, + *stripesize, *stripeoffset; const char *name; char param[16]; int i, *nargs; @@ -370,6 +387,24 @@ g_nop_ctl_create(struct gctl_req *req, struct g_class *mp) gctl_error(req, "Invalid '%s' argument", "secsize"); return; } + stripesize = gctl_get_paraml(req, "stripesize", sizeof(*stripesize)); + if (stripesize == NULL) { + gctl_error(req, "No '%s' argument", "stripesize"); + return; + } + if (*stripesize < 0) { + gctl_error(req, "Invalid '%s' argument", "stripesize"); + return; + } + stripeoffset = gctl_get_paraml(req, "stripeoffset", sizeof(*stripeoffset)); + if (stripeoffset == NULL) { + gctl_error(req, "No '%s' argument", "stripeoffset"); + return; + } + if (*stripeoffset < 0) { + gctl_error(req, "Invalid '%s' argument", "stripeoffset"); + return; + } for (i = 0; i < *nargs; i++) { snprintf(param, sizeof(param), "arg%d", i); @@ -390,7 +425,8 @@ g_nop_ctl_create(struct gctl_req *req, struct g_class *mp) *error == -1 ? EIO : (int)*error, *rfailprob == -1 ? 0 : (u_int)*rfailprob, *wfailprob == -1 ? 0 : (u_int)*wfailprob, - (off_t)*offset, (off_t)*size, (u_int)*secsize) != 0) { + (off_t)*offset, (off_t)*size, (u_int)*secsize, + (u_int)*stripesize, (u_int)*stripeoffset) != 0) { return; } } diff --git a/sys/geom/nop/g_nop.h b/sys/geom/nop/g_nop.h index 3e37c05..b5e954a 100644 --- a/sys/geom/nop/g_nop.h +++ b/sys/geom/nop/g_nop.h @@ -59,6 +59,8 @@ struct g_nop_softc { int sc_error; off_t sc_offset; off_t sc_explicitsize; + off_t sc_stripesize; + off_t sc_stripeoffset; u_int sc_rfailprob; u_int sc_wfailprob; uintmax_t sc_reads; |