g_zero.c revision 254936
1185573Srwatson/*- 2185573Srwatson * Copyright (c) 2005 Pawel Jakub Dawidek <pjd@FreeBSD.org> 3155131Srwatson * All rights reserved. 4155131Srwatson * 5155131Srwatson * Redistribution and use in source and binary forms, with or without 6155131Srwatson * modification, are permitted provided that the following conditions 7155131Srwatson * are met: 8155131Srwatson * 1. Redistributions of source code must retain the above copyright 9155131Srwatson * notice, this list of conditions and the following disclaimer. 10155131Srwatson * 2. Redistributions in binary form must reproduce the above copyright 11155131Srwatson * notice, this list of conditions and the following disclaimer in the 12155131Srwatson * documentation and/or other materials provided with the distribution. 13155131Srwatson * 14185573Srwatson * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND 15155131Srwatson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16155131Srwatson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17155131Srwatson * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 18155131Srwatson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19155131Srwatson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20155131Srwatson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21155131Srwatson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22155131Srwatson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23155131Srwatson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24155131Srwatson * SUCH DAMAGE. 25155131Srwatson */ 26155131Srwatson 27155131Srwatson#include <sys/cdefs.h> 28155131Srwatson__FBSDID("$FreeBSD: head/sys/geom/zero/g_zero.c 254936 2013-08-26 20:39:02Z mav $"); 29155131Srwatson 30185573Srwatson#include <sys/param.h> 31155131Srwatson#include <sys/bio.h> 32155131Srwatson#include <sys/kernel.h> 33185573Srwatson#include <sys/limits.h> 34185573Srwatson#include <sys/malloc.h> 35155131Srwatson#include <sys/queue.h> 36155131Srwatson#include <sys/sysctl.h> 37155131Srwatson#include <sys/systm.h> 38155131Srwatson 39155131Srwatson#include <geom/geom.h> 40155131Srwatson 41155131Srwatson 42185573Srwatson#define G_ZERO_CLASS_NAME "ZERO" 43185573Srwatson 44185573Srwatsonstatic int g_zero_clear_sysctl(SYSCTL_HANDLER_ARGS); 45185573Srwatson 46155131SrwatsonSYSCTL_DECL(_kern_geom); 47155131Srwatsonstatic SYSCTL_NODE(_kern_geom, OID_AUTO, zero, CTLFLAG_RW, 0, 48155131Srwatson "GEOM_ZERO stuff"); 49155131Srwatsonstatic int g_zero_clear = 1; 50155131SrwatsonSYSCTL_PROC(_kern_geom_zero, OID_AUTO, clear, CTLTYPE_INT|CTLFLAG_RW, 51155131Srwatson &g_zero_clear, 0, g_zero_clear_sysctl, "I", "Clear read data buffer"); 52155131Srwatsonstatic int g_zero_byte = 0; 53155131SrwatsonSYSCTL_INT(_kern_geom_zero, OID_AUTO, byte, CTLFLAG_RW, &g_zero_byte, 0, 54155131Srwatson "Byte (octet) value to clear the buffers with"); 55155131Srwatson 56155131Srwatsonstatic struct g_provider *gpp; 57155131Srwatson 58155131Srwatsonstatic int 59155131Srwatsong_zero_clear_sysctl(SYSCTL_HANDLER_ARGS) 60155131Srwatson{ 61155131Srwatson int error; 62155131Srwatson 63155131Srwatson error = sysctl_handle_int(oidp, &g_zero_clear, 0, req); 64155131Srwatson if (error != 0 || req->newptr == NULL) 65155131Srwatson return (error); 66155131Srwatson if (gpp == NULL) 67155131Srwatson return (ENXIO); 68155131Srwatson if (g_zero_clear) 69155131Srwatson gpp->flags &= ~G_PF_ACCEPT_UNMAPPED; 70155131Srwatson else 71155131Srwatson gpp->flags |= G_PF_ACCEPT_UNMAPPED; 72155131Srwatson return (0); 73155131Srwatson} 74155131Srwatson 75185573Srwatsonstatic void 76155131Srwatsong_zero_start(struct bio *bp) 77155131Srwatson{ 78155131Srwatson int error = ENXIO; 79155131Srwatson 80155131Srwatson switch (bp->bio_cmd) { 81155131Srwatson case BIO_READ: 82155131Srwatson if (g_zero_clear && (bp->bio_flags & BIO_UNMAPPED) == 0) 83155131Srwatson memset(bp->bio_data, g_zero_byte, bp->bio_length); 84155131Srwatson /* FALLTHROUGH */ 85155131Srwatson case BIO_DELETE: 86155131Srwatson case BIO_WRITE: 87155131Srwatson bp->bio_completed = bp->bio_length; 88155131Srwatson error = 0; 89155131Srwatson break; 90155131Srwatson case BIO_GETATTR: 91155131Srwatson default: 92155131Srwatson error = EOPNOTSUPP; 93155131Srwatson break; 94155131Srwatson } 95155131Srwatson g_io_deliver(bp, error); 96155131Srwatson} 97155131Srwatson 98155131Srwatsonstatic void 99155131Srwatsong_zero_init(struct g_class *mp) 100155131Srwatson{ 101155131Srwatson struct g_geom *gp; 102155131Srwatson struct g_provider *pp; 103155131Srwatson 104155131Srwatson g_topology_assert(); 105155131Srwatson gp = g_new_geomf(mp, "gzero"); 106155131Srwatson gp->start = g_zero_start; 107155131Srwatson gp->access = g_std_access; 108155131Srwatson gpp = pp = g_new_providerf(gp, "%s", gp->name); 109155131Srwatson if (!g_zero_clear) 110155131Srwatson pp->flags |= G_PF_ACCEPT_UNMAPPED; 111155131Srwatson pp->mediasize = 1152921504606846976LLU; 112155131Srwatson pp->sectorsize = 512; 113155131Srwatson g_error_provider(pp, 0); 114155131Srwatson} 115155131Srwatson 116155131Srwatsonstatic int 117155131Srwatsong_zero_destroy_geom(struct gctl_req *req __unused, struct g_class *mp __unused, 118155131Srwatson struct g_geom *gp) 119155131Srwatson{ 120155131Srwatson struct g_provider *pp; 121155131Srwatson 122155131Srwatson g_topology_assert(); 123155131Srwatson if (gp == NULL) 124155131Srwatson return (0); 125155131Srwatson pp = LIST_FIRST(&gp->provider); 126155131Srwatson if (pp == NULL) 127155131Srwatson return (0); 128155131Srwatson if (pp->acr > 0 || pp->acw > 0 || pp->ace > 0) 129155131Srwatson return (EBUSY); 130155131Srwatson gpp = NULL; 131155131Srwatson g_wither_geom(gp, ENXIO); 132155131Srwatson return (0); 133155131Srwatson} 134155131Srwatson 135155131Srwatsonstatic struct g_class g_zero_class = { 136155131Srwatson .name = G_ZERO_CLASS_NAME, 137155131Srwatson .version = G_VERSION, 138155131Srwatson .init = g_zero_init, 139155131Srwatson .destroy_geom = g_zero_destroy_geom 140155131Srwatson}; 141155131Srwatson 142155131SrwatsonDECLARE_GEOM_CLASS(g_zero_class, g_zero); 143155131Srwatson