1/*- 2 * Copyright (c) 2002 Poul-Henning Kamp 3 * Copyright (c) 2002 Networks Associates Technology, Inc. 4 * All rights reserved. 5 * 6 * This software was developed for the FreeBSD Project by Poul-Henning Kamp 7 * and NAI Labs, the Security Research Division of Network Associates, Inc. 8 * under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the --- 20 unchanged lines hidden (view full) --- 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 */ 35 36#include <sys/cdefs.h> |
37__FBSDID("$FreeBSD: head/sys/geom/geom_disk.c 248694 2013-03-25 05:45:24Z mav $"); |
38 39#include "opt_geom.h" 40 41#include <sys/param.h> 42#include <sys/systm.h> 43#include <sys/kernel.h> 44#include <sys/sysctl.h> 45#include <sys/bio.h> --- 9 unchanged lines hidden (view full) --- 55#include <sys/mutex.h> 56#include <geom/geom.h> 57#include <geom/geom_disk.h> 58#include <geom/geom_int.h> 59 60#include <dev/led/led.h> 61 62struct g_disk_softc { |
63 struct mtx done_mtx; |
64 struct disk *dp; 65 struct sysctl_ctx_list sysctl_ctx; 66 struct sysctl_oid *sysctl_tree; 67 char led[64]; 68 uint32_t state; 69}; 70 |
71static g_access_t g_disk_access; |
72static g_start_t g_disk_start; 73static g_ioctl_t g_disk_ioctl; 74static g_dumpconf_t g_disk_dumpconf; 75static g_provgone_t g_disk_providergone; 76 77static struct g_class g_disk_class = { 78 .name = "DISK", 79 .version = G_VERSION, |
80 .start = g_disk_start, 81 .access = g_disk_access, 82 .ioctl = g_disk_ioctl, 83 .providergone = g_disk_providergone, 84 .dumpconf = g_disk_dumpconf, 85}; 86 87SYSCTL_DECL(_kern_geom); 88static SYSCTL_NODE(_kern_geom, OID_AUTO, disk, CTLFLAG_RW, 0, 89 "GEOM_DISK stuff"); 90 |
91DECLARE_GEOM_CLASS(g_disk_class, g_disk); 92 93static void __inline 94g_disk_lock_giant(struct disk *dp) 95{ 96 97 if (dp->d_flags & DISKFLAG_NEEDSGIANT) 98 mtx_lock(&Giant); --- 12 unchanged lines hidden (view full) --- 111{ 112 struct disk *dp; 113 struct g_disk_softc *sc; 114 int error; 115 116 g_trace(G_T_ACCESS, "g_disk_access(%s, %d, %d, %d)", 117 pp->name, r, w, e); 118 g_topology_assert(); |
119 sc = pp->private; |
120 if (sc == NULL || (dp = sc->dp) == NULL || dp->d_destroyed) { 121 /* 122 * Allow decreasing access count even if disk is not 123 * avaliable anymore. 124 */ 125 if (r <= 0 && w <= 0 && e <= 0) 126 return (0); 127 return (ENXIO); --- 88 unchanged lines hidden (view full) --- 216 } 217 g_io_deliver(bp, 0); 218} 219 220static void 221g_disk_done(struct bio *bp) 222{ 223 struct bio *bp2; |
224 struct g_disk_softc *sc; 225 226 /* See "notes" for why we need a mutex here */ 227 /* XXX: will witness accept a mix of Giant/unGiant drivers here ? */ |
228 bp2 = bp->bio_parent; |
229 sc = bp2->bio_to->private; 230 bp->bio_completed = bp->bio_length - bp->bio_resid; 231 mtx_lock(&sc->done_mtx); |
232 if (bp2->bio_error == 0) 233 bp2->bio_error = bp->bio_error; 234 bp2->bio_completed += bp->bio_completed; |
235 if ((bp->bio_cmd & (BIO_READ|BIO_WRITE|BIO_DELETE)) != 0) 236 devstat_end_transaction_bio(sc->dp->d_devstat, bp); |
237 g_destroy_bio(bp); 238 bp2->bio_inbed++; 239 if (bp2->bio_children == bp2->bio_inbed) { 240 bp2->bio_resid = bp2->bio_bcount - bp2->bio_completed; 241 g_io_deliver(bp2, bp2->bio_error); 242 } |
243 mtx_unlock(&sc->done_mtx); |
244} 245 246static int 247g_disk_ioctl(struct g_provider *pp, u_long cmd, void * data, int fflag, struct thread *td) 248{ |
249 struct disk *dp; 250 struct g_disk_softc *sc; 251 int error; 252 |
253 sc = pp->private; |
254 dp = sc->dp; 255 256 if (dp->d_ioctl == NULL) 257 return (ENOIOCTL); 258 g_disk_lock_giant(dp); 259 error = dp->d_ioctl(dp, cmd, data, fflag, td); 260 g_disk_unlock_giant(dp); 261 return (error); 262} 263 264static void 265g_disk_start(struct bio *bp) 266{ 267 struct bio *bp2, *bp3; 268 struct disk *dp; 269 struct g_disk_softc *sc; 270 int error; 271 off_t off; 272 |
273 sc = bp->bio_to->private; |
274 if (sc == NULL || (dp = sc->dp) == NULL || dp->d_destroyed) { 275 g_io_deliver(bp, ENXIO); 276 return; 277 } 278 error = EJUSTRETURN; 279 switch(bp->bio_cmd) { 280 case BIO_DELETE: 281 if (!(dp->d_flags & DISKFLAG_CANDELETE)) { --- 184 unchanged lines hidden (view full) --- 466 struct g_disk_softc *sc; 467 char tmpstr[80]; 468 469 if (flag == EV_CANCEL) 470 return; 471 g_topology_assert(); 472 dp = arg; 473 sc = g_malloc(sizeof(*sc), M_WAITOK | M_ZERO); |
474 mtx_init(&sc->done_mtx, "g_disk_done", NULL, MTX_DEF); |
475 sc->dp = dp; 476 gp = g_new_geomf(&g_disk_class, "%s%d", dp->d_name, dp->d_unit); 477 gp->softc = sc; 478 pp = g_new_providerf(gp, "%s", gp->name); 479 pp->mediasize = dp->d_mediasize; 480 pp->sectorsize = dp->d_sectorsize; 481 pp->stripeoffset = dp->d_stripeoffset; 482 pp->stripesize = dp->d_stripesize; --- 27 unchanged lines hidden (view full) --- 510 * be getting any more accesses from GEOM. 511 */ 512static void 513g_disk_providergone(struct g_provider *pp) 514{ 515 struct disk *dp; 516 struct g_disk_softc *sc; 517 |
518 sc = (struct g_disk_softc *)pp->private; |
519 dp = sc->dp; |
520 if (dp != NULL && dp->d_gone != NULL) |
521 dp->d_gone(dp); |
522 if (sc->sysctl_tree != NULL) { 523 sysctl_ctx_free(&sc->sysctl_ctx); 524 sc->sysctl_tree = NULL; 525 } 526 if (sc->led[0] != 0) { 527 led_set(sc->led, "0"); 528 sc->led[0] = 0; 529 } 530 pp->private = NULL; 531 pp->geom->softc = NULL; 532 mtx_destroy(&sc->done_mtx); 533 g_free(sc); |
534} 535 536static void 537g_disk_destroy(void *ptr, int flag) 538{ 539 struct disk *dp; 540 struct g_geom *gp; 541 struct g_disk_softc *sc; 542 543 g_topology_assert(); 544 dp = ptr; 545 gp = dp->d_geom; 546 if (gp != NULL) { 547 sc = gp->softc; |
548 if (sc != NULL) 549 sc->dp = NULL; 550 dp->d_geom = NULL; |
551 g_wither_geom(gp, ENXIO); 552 } 553 g_free(dp); 554} 555 556/* 557 * We only allow printable characters in disk ident, 558 * the rest is converted to 'x<HH>'. --- 163 unchanged lines hidden --- |