diff options
author | Alexander Motin <mav@FreeBSD.org> | 2013-09-14 10:12:28 +0000 |
---|---|---|
committer | Alexander Motin <mav@FreeBSD.org> | 2013-09-14 10:12:28 +0000 |
commit | dbae60e066a034301bc1aa7fe9f90c7033b706f6 (patch) | |
tree | e39f811583afebadce292d4fb85e0effc8801f6f /sys/geom | |
parent | 2c012207afcaef53978168968c77a0bb3e6c05a3 (diff) | |
download | src-test2-dbae60e066a034301bc1aa7fe9f90c7033b706f6.tar.gz src-test2-dbae60e066a034301bc1aa7fe9f90c7033b706f6.zip |
Notes
Diffstat (limited to 'sys/geom')
-rw-r--r-- | sys/geom/zero/g_zero.c | 32 |
1 files changed, 28 insertions, 4 deletions
diff --git a/sys/geom/zero/g_zero.c b/sys/geom/zero/g_zero.c index 1c2c54f37a05..311db54402b9 100644 --- a/sys/geom/zero/g_zero.c +++ b/sys/geom/zero/g_zero.c @@ -41,16 +41,37 @@ __FBSDID("$FreeBSD$"); #define G_ZERO_CLASS_NAME "ZERO" +static int g_zero_clear_sysctl(SYSCTL_HANDLER_ARGS); + SYSCTL_DECL(_kern_geom); static SYSCTL_NODE(_kern_geom, OID_AUTO, zero, CTLFLAG_RW, 0, "GEOM_ZERO stuff"); static int g_zero_clear = 1; -SYSCTL_INT(_kern_geom_zero, OID_AUTO, clear, CTLFLAG_RW, &g_zero_clear, 0, - "Clear read data buffer"); +SYSCTL_PROC(_kern_geom_zero, OID_AUTO, clear, CTLTYPE_INT|CTLFLAG_RW, + &g_zero_clear, 0, g_zero_clear_sysctl, "I", "Clear read data buffer"); static int g_zero_byte = 0; SYSCTL_INT(_kern_geom_zero, OID_AUTO, byte, CTLFLAG_RW, &g_zero_byte, 0, "Byte (octet) value to clear the buffers with"); +static struct g_provider *gpp; + +static int +g_zero_clear_sysctl(SYSCTL_HANDLER_ARGS) +{ + int error; + + error = sysctl_handle_int(oidp, &g_zero_clear, 0, req); + if (error != 0 || req->newptr == NULL) + return (error); + if (gpp == NULL) + return (ENXIO); + if (g_zero_clear) + gpp->flags &= ~G_PF_ACCEPT_UNMAPPED; + else + gpp->flags |= G_PF_ACCEPT_UNMAPPED; + return (0); +} + static void g_zero_start(struct bio *bp) { @@ -58,7 +79,7 @@ g_zero_start(struct bio *bp) switch (bp->bio_cmd) { case BIO_READ: - if (g_zero_clear) + if (g_zero_clear && (bp->bio_flags & BIO_UNMAPPED) == 0) memset(bp->bio_data, g_zero_byte, bp->bio_length); /* FALLTHROUGH */ case BIO_DELETE: @@ -84,7 +105,9 @@ g_zero_init(struct g_class *mp) gp = g_new_geomf(mp, "gzero"); gp->start = g_zero_start; gp->access = g_std_access; - pp = g_new_providerf(gp, "%s", gp->name); + gpp = pp = g_new_providerf(gp, "%s", gp->name); + if (!g_zero_clear) + pp->flags |= G_PF_ACCEPT_UNMAPPED; pp->mediasize = 1152921504606846976LLU; pp->sectorsize = 512; g_error_provider(pp, 0); @@ -104,6 +127,7 @@ g_zero_destroy_geom(struct gctl_req *req __unused, struct g_class *mp __unused, return (0); if (pp->acr > 0 || pp->acw > 0 || pp->ace > 0) return (EBUSY); + gpp = NULL; g_wither_geom(gp, ENXIO); return (0); } |