From 5392c5a5b2299d8bbd0eba589423543a44bb516d Mon Sep 17 00:00:00 2001 From: trasz Date: Sun, 18 Oct 2015 15:02:07 +0000 Subject: [PATCH] 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 git-svn-id: svn://svn.freebsd.org/base/stable/10@289520 ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f --- sbin/geom/class/nop/geom_nop.c | 6 +++-- sbin/geom/class/nop/gnop.8 | 8 ++++++- sys/geom/nop/g_nop.c | 42 +++++++++++++++++++++++++++++++--- sys/geom/nop/g_nop.h | 2 ++ 4 files changed, 52 insertions(+), 6 deletions(-) diff --git a/sbin/geom/class/nop/geom_nop.c b/sbin/geom/class/nop/geom_nop.c index 25163ccf0..f05a5227b 100644 --- a/sbin/geom/class/nop/geom_nop.c +++ b/sbin/geom/class/nop/geom_nop.c @@ -43,14 +43,16 @@ struct g_command class_commands[] = { { { 'e', "error", "-1", G_TYPE_NUMBER }, { 'o', "offset", "0", G_TYPE_NUMBER }, + { 'p', "stripesize", "0", G_TYPE_NUMBER }, + { 'P', "stripeoffset", "0", G_TYPE_NUMBER }, { 'r', "rfailprob", "-1", G_TYPE_NUMBER }, { 's', "size", "0", G_TYPE_NUMBER }, { 'S', "secsize", "0", G_TYPE_NUMBER }, { 'w', "wfailprob", "-1", G_TYPE_NUMBER }, G_OPT_SENTINEL }, - "[-v] [-e error] [-o offset] [-r rfailprob] [-s size] " - "[-S secsize] [-w wfailprob] dev ..." + "[-v] [-e error] [-o offset] [-p stripesize] [-P stripeoffset] " + "[-r rfailprob] [-s size] [-S secsize] [-w wfailprob] dev ..." }, { "configure", G_FLAG_VERBOSE, NULL, { diff --git a/sbin/geom/class/nop/gnop.8 b/sbin/geom/class/nop/gnop.8 index 2bcbef30d..0103579ca 100644 --- a/sbin/geom/class/nop/gnop.8 +++ b/sbin/geom/class/nop/gnop.8 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd April 14, 2013 +.Dd September 15, 2015 .Dt GNOP 8 .Os .Sh NAME @@ -36,6 +36,8 @@ .Op Fl v .Op Fl e Ar error .Op Fl o Ar offset +.Op Fl p Ar stripesize +.Op Fl P Ar stripeoffset .Op Fl r Ar rfailprob .Op Fl s Ar size .Op Fl S Ar secsize @@ -115,6 +117,10 @@ Specifies the error number to return on failure. Force the removal of the specified provider. .It Fl o Ar offset Where to begin on the original provider. +.It Fl p Ar stripesize +Value of the stripesize property of the transparent provider. +.It Fl P Ar stripeoffset +Value of the stripeoffset property of the transparent provider. .It Fl r Ar rfailprob Specifies read failure probability in percent. .It Fl s Ar size diff --git a/sys/geom/nop/g_nop.c b/sys/geom/nop/g_nop.c index bd72d780a..837f3f4e3 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 3e37c05d9..b5e954ad6 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; -- 2.45.0