diff --git a/sbin/geom/class/nop/geom_nop.c b/sbin/geom/class/nop/geom_nop.c index cd4f6af19f48..a5edfdeeb357 100644 --- a/sbin/geom/class/nop/geom_nop.c +++ b/sbin/geom/class/nop/geom_nop.c @@ -40,6 +40,7 @@ uint32_t version = G_NOP_VERSION; static intmax_t failprob = 0; static intmax_t offset = 0; +static intmax_t secsize = 0; static intmax_t size = 0; struct g_command class_commands[] = { @@ -48,6 +49,7 @@ struct g_command class_commands[] = { { 'f', "failprob", &failprob, G_TYPE_NUMBER }, { 'o', "offset", &offset, G_TYPE_NUMBER }, { 's', "size", &size, G_TYPE_NUMBER }, + { 'S', "secsize", &secsize, G_TYPE_NUMBER }, G_OPT_SENTINEL } }, @@ -71,7 +73,7 @@ void usage(const char *name) { - fprintf(stderr, "usage: %s create [-v] [-f failprob] [-o offset] [-s size] [dev2 [...]]\n", name); + fprintf(stderr, "usage: %s create [-v] [-f failprob] [-o offset] [-s size] [-S secsize] [dev2 [...]]\n", name); fprintf(stderr, " %s configure [-v] [-f failprob] [prov2 [...]]\n", name); fprintf(stderr, " %s destroy [-fv] [prov2 [...]]\n", name); } diff --git a/sbin/geom/class/nop/gnop.8 b/sbin/geom/class/nop/gnop.8 index 54cad18965ba..5ff7e07f7880 100644 --- a/sbin/geom/class/nop/gnop.8 +++ b/sbin/geom/class/nop/gnop.8 @@ -37,6 +37,7 @@ .Op Fl f Ar failprob .Op Fl o Ar offset .Op Fl s Ar size +.Op Fl S Ar secsize .Ar dev1 .Op Ar dev2 Op Ar ... .Nm @@ -109,6 +110,8 @@ Specifies failure probability in percentage. Where to begin on the original provider. .It Fl s Ar size Size of the transparent provider. +.It Fl S Ar secsize +Sector size of the transparent provider. .It Fl v Be more verbose. .El diff --git a/sys/geom/nop/g_nop.c b/sys/geom/nop/g_nop.c index 88283eef3d21..c9e53ea58738 100644 --- a/sys/geom/nop/g_nop.c +++ b/sys/geom/nop/g_nop.c @@ -121,7 +121,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, - u_int failprob, off_t offset, off_t size) + u_int failprob, off_t offset, off_t size, u_int secsize) { struct g_nop_softc *sc; struct g_geom *gp; @@ -154,6 +154,12 @@ g_nop_create(struct gctl_req *req, struct g_class *mp, struct g_provider *pp, gctl_error(req, "Invalid size for provider %s.", pp->name); return (EINVAL); } + if (secsize == 0) + secsize = pp->sectorsize; + else if ((secsize % pp->sectorsize) != 0) { + gctl_error(req, "Invalid secsize for provider %s.", pp->name); + 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) { @@ -183,7 +189,7 @@ g_nop_create(struct gctl_req *req, struct g_class *mp, struct g_provider *pp, goto fail; } newpp->mediasize = size; - newpp->sectorsize = pp->sectorsize; + newpp->sectorsize = secsize; cp = g_new_consumer(gp); if (cp == NULL) { @@ -253,7 +259,7 @@ static void g_nop_ctl_create(struct gctl_req *req, struct g_class *mp) { struct g_provider *pp; - intmax_t *failprob, *offset, *size; + intmax_t *failprob, *offset, *secsize, *size; const char *name; char param[16]; int i, *nargs; @@ -296,6 +302,15 @@ g_nop_ctl_create(struct gctl_req *req, struct g_class *mp) gctl_error(req, "Invalid '%s' argument", "size"); return; } + secsize = gctl_get_paraml(req, "secsize", sizeof(*secsize)); + if (secsize == NULL) { + gctl_error(req, "No '%s' argument", "secsize"); + return; + } + if (*secsize < 0) { + gctl_error(req, "Invalid '%s' argument", "secsize"); + return; + } for (i = 0; i < *nargs; i++) { snprintf(param, sizeof(param), "arg%d", i); @@ -313,7 +328,7 @@ g_nop_ctl_create(struct gctl_req *req, struct g_class *mp) return; } if (g_nop_create(req, mp, pp, (u_int)*failprob, (off_t)*offset, - (off_t)*size) != 0) { + (off_t)*size, (u_int)*secsize) != 0) { return; } } diff --git a/sys/geom/nop/g_nop.h b/sys/geom/nop/g_nop.h index cb9f38d40427..378c3eff490f 100644 --- a/sys/geom/nop/g_nop.h +++ b/sys/geom/nop/g_nop.h @@ -30,7 +30,7 @@ #define _G_NOP_H_ #define G_NOP_CLASS_NAME "NOP" -#define G_NOP_VERSION 2 +#define G_NOP_VERSION 3 #define G_NOP_SUFFIX ".nop" #ifdef _KERNEL