1565bc101SPawel Jakub Dawidek /*- 23728855aSPedro F. Giffuni * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 33728855aSPedro F. Giffuni * 4565bc101SPawel Jakub Dawidek * Copyright (c) 2005 Pawel Jakub Dawidek <pjd@FreeBSD.org> 5565bc101SPawel Jakub Dawidek * All rights reserved. 6565bc101SPawel Jakub Dawidek * 7565bc101SPawel Jakub Dawidek * Redistribution and use in source and binary forms, with or without 8565bc101SPawel Jakub Dawidek * modification, are permitted provided that the following conditions 9565bc101SPawel Jakub Dawidek * are met: 10565bc101SPawel Jakub Dawidek * 1. Redistributions of source code must retain the above copyright 11565bc101SPawel Jakub Dawidek * notice, this list of conditions and the following disclaimer. 12565bc101SPawel Jakub Dawidek * 2. Redistributions in binary form must reproduce the above copyright 13565bc101SPawel Jakub Dawidek * notice, this list of conditions and the following disclaimer in the 14565bc101SPawel Jakub Dawidek * documentation and/or other materials provided with the distribution. 15565bc101SPawel Jakub Dawidek * 16565bc101SPawel Jakub Dawidek * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND 17565bc101SPawel Jakub Dawidek * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18565bc101SPawel Jakub Dawidek * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19565bc101SPawel Jakub Dawidek * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 20565bc101SPawel Jakub Dawidek * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21565bc101SPawel Jakub Dawidek * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22565bc101SPawel Jakub Dawidek * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23565bc101SPawel Jakub Dawidek * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24565bc101SPawel Jakub Dawidek * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25565bc101SPawel Jakub Dawidek * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26565bc101SPawel Jakub Dawidek * SUCH DAMAGE. 27565bc101SPawel Jakub Dawidek */ 28565bc101SPawel Jakub Dawidek 29a1c10dcbSPawel Jakub Dawidek #include <sys/cdefs.h> 30a1c10dcbSPawel Jakub Dawidek __FBSDID("$FreeBSD$"); 31a1c10dcbSPawel Jakub Dawidek 32565bc101SPawel Jakub Dawidek #include <sys/param.h> 33565bc101SPawel Jakub Dawidek #include <sys/bio.h> 34565bc101SPawel Jakub Dawidek #include <sys/kernel.h> 35565bc101SPawel Jakub Dawidek #include <sys/limits.h> 36565bc101SPawel Jakub Dawidek #include <sys/malloc.h> 37565bc101SPawel Jakub Dawidek #include <sys/queue.h> 38565bc101SPawel Jakub Dawidek #include <sys/sysctl.h> 39565bc101SPawel Jakub Dawidek #include <sys/systm.h> 40565bc101SPawel Jakub Dawidek 41565bc101SPawel Jakub Dawidek #include <geom/geom.h> 42565bc101SPawel Jakub Dawidek 43565bc101SPawel Jakub Dawidek 44565bc101SPawel Jakub Dawidek #define G_ZERO_CLASS_NAME "ZERO" 45565bc101SPawel Jakub Dawidek 463843eba8SAlexander Motin static int g_zero_clear_sysctl(SYSCTL_HANDLER_ARGS); 473843eba8SAlexander Motin 48565bc101SPawel Jakub Dawidek SYSCTL_DECL(_kern_geom); 496472ac3dSEd Schouten static SYSCTL_NODE(_kern_geom, OID_AUTO, zero, CTLFLAG_RW, 0, 506472ac3dSEd Schouten "GEOM_ZERO stuff"); 5124e1fdcdSPawel Jakub Dawidek static int g_zero_clear = 1; 523843eba8SAlexander Motin SYSCTL_PROC(_kern_geom_zero, OID_AUTO, clear, CTLTYPE_INT|CTLFLAG_RW, 533843eba8SAlexander Motin &g_zero_clear, 0, g_zero_clear_sysctl, "I", "Clear read data buffer"); 5424e1fdcdSPawel Jakub Dawidek static int g_zero_byte = 0; 5524e1fdcdSPawel Jakub Dawidek SYSCTL_INT(_kern_geom_zero, OID_AUTO, byte, CTLFLAG_RW, &g_zero_byte, 0, 5624e1fdcdSPawel Jakub Dawidek "Byte (octet) value to clear the buffers with"); 57565bc101SPawel Jakub Dawidek 583843eba8SAlexander Motin static struct g_provider *gpp; 593843eba8SAlexander Motin 603843eba8SAlexander Motin static int 613843eba8SAlexander Motin g_zero_clear_sysctl(SYSCTL_HANDLER_ARGS) 623843eba8SAlexander Motin { 633843eba8SAlexander Motin int error; 643843eba8SAlexander Motin 653843eba8SAlexander Motin error = sysctl_handle_int(oidp, &g_zero_clear, 0, req); 663843eba8SAlexander Motin if (error != 0 || req->newptr == NULL) 673843eba8SAlexander Motin return (error); 683843eba8SAlexander Motin if (gpp == NULL) 693843eba8SAlexander Motin return (ENXIO); 703843eba8SAlexander Motin if (g_zero_clear) 713843eba8SAlexander Motin gpp->flags &= ~G_PF_ACCEPT_UNMAPPED; 723843eba8SAlexander Motin else 733843eba8SAlexander Motin gpp->flags |= G_PF_ACCEPT_UNMAPPED; 743843eba8SAlexander Motin return (0); 753843eba8SAlexander Motin } 763843eba8SAlexander Motin 77565bc101SPawel Jakub Dawidek static void 78565bc101SPawel Jakub Dawidek g_zero_start(struct bio *bp) 79565bc101SPawel Jakub Dawidek { 80565bc101SPawel Jakub Dawidek int error = ENXIO; 81565bc101SPawel Jakub Dawidek 82565bc101SPawel Jakub Dawidek switch (bp->bio_cmd) { 83565bc101SPawel Jakub Dawidek case BIO_READ: 843843eba8SAlexander Motin if (g_zero_clear && (bp->bio_flags & BIO_UNMAPPED) == 0) 8524e1fdcdSPawel Jakub Dawidek memset(bp->bio_data, g_zero_byte, bp->bio_length); 86565bc101SPawel Jakub Dawidek /* FALLTHROUGH */ 87565bc101SPawel Jakub Dawidek case BIO_DELETE: 88565bc101SPawel Jakub Dawidek case BIO_WRITE: 89565bc101SPawel Jakub Dawidek bp->bio_completed = bp->bio_length; 90565bc101SPawel Jakub Dawidek error = 0; 91565bc101SPawel Jakub Dawidek break; 92565bc101SPawel Jakub Dawidek case BIO_GETATTR: 93565bc101SPawel Jakub Dawidek default: 94565bc101SPawel Jakub Dawidek error = EOPNOTSUPP; 95565bc101SPawel Jakub Dawidek break; 96565bc101SPawel Jakub Dawidek } 97565bc101SPawel Jakub Dawidek g_io_deliver(bp, error); 98565bc101SPawel Jakub Dawidek } 99565bc101SPawel Jakub Dawidek 100565bc101SPawel Jakub Dawidek static void 101565bc101SPawel Jakub Dawidek g_zero_init(struct g_class *mp) 102565bc101SPawel Jakub Dawidek { 103565bc101SPawel Jakub Dawidek struct g_geom *gp; 104565bc101SPawel Jakub Dawidek struct g_provider *pp; 105565bc101SPawel Jakub Dawidek 106565bc101SPawel Jakub Dawidek g_topology_assert(); 107565bc101SPawel Jakub Dawidek gp = g_new_geomf(mp, "gzero"); 108565bc101SPawel Jakub Dawidek gp->start = g_zero_start; 109565bc101SPawel Jakub Dawidek gp->access = g_std_access; 1103843eba8SAlexander Motin gpp = pp = g_new_providerf(gp, "%s", gp->name); 11140ea77a0SAlexander Motin pp->flags |= G_PF_DIRECT_SEND | G_PF_DIRECT_RECEIVE; 1123843eba8SAlexander Motin if (!g_zero_clear) 1133843eba8SAlexander Motin pp->flags |= G_PF_ACCEPT_UNMAPPED; 114565bc101SPawel Jakub Dawidek pp->mediasize = 1152921504606846976LLU; 115565bc101SPawel Jakub Dawidek pp->sectorsize = 512; 116565bc101SPawel Jakub Dawidek g_error_provider(pp, 0); 117565bc101SPawel Jakub Dawidek } 118565bc101SPawel Jakub Dawidek 119565bc101SPawel Jakub Dawidek static int 120565bc101SPawel Jakub Dawidek g_zero_destroy_geom(struct gctl_req *req __unused, struct g_class *mp __unused, 121565bc101SPawel Jakub Dawidek struct g_geom *gp) 122565bc101SPawel Jakub Dawidek { 123565bc101SPawel Jakub Dawidek struct g_provider *pp; 124565bc101SPawel Jakub Dawidek 125565bc101SPawel Jakub Dawidek g_topology_assert(); 126565bc101SPawel Jakub Dawidek if (gp == NULL) 127565bc101SPawel Jakub Dawidek return (0); 128565bc101SPawel Jakub Dawidek pp = LIST_FIRST(&gp->provider); 129565bc101SPawel Jakub Dawidek if (pp == NULL) 130565bc101SPawel Jakub Dawidek return (0); 131565bc101SPawel Jakub Dawidek if (pp->acr > 0 || pp->acw > 0 || pp->ace > 0) 132565bc101SPawel Jakub Dawidek return (EBUSY); 1333843eba8SAlexander Motin gpp = NULL; 134565bc101SPawel Jakub Dawidek g_wither_geom(gp, ENXIO); 1355a279fc5SJaakko Heinonen return (0); 136565bc101SPawel Jakub Dawidek } 137565bc101SPawel Jakub Dawidek 138565bc101SPawel Jakub Dawidek static struct g_class g_zero_class = { 139565bc101SPawel Jakub Dawidek .name = G_ZERO_CLASS_NAME, 140565bc101SPawel Jakub Dawidek .version = G_VERSION, 141565bc101SPawel Jakub Dawidek .init = g_zero_init, 142565bc101SPawel Jakub Dawidek .destroy_geom = g_zero_destroy_geom 143565bc101SPawel Jakub Dawidek }; 144565bc101SPawel Jakub Dawidek 145565bc101SPawel Jakub Dawidek DECLARE_GEOM_CLASS(g_zero_class, g_zero); 146*74d6c131SKyle Evans MODULE_VERSION(geom_zero, 0); 147