geom_disk.c (248516) | geom_disk.c (248694) |
---|---|
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> | 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 248516 2013-03-19 14:49:15Z kib $"); | 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 { | 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; |
|
63 struct disk *dp; 64 struct sysctl_ctx_list sysctl_ctx; 65 struct sysctl_oid *sysctl_tree; 66 char led[64]; 67 uint32_t state; 68}; 69 | 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 |
70static struct mtx g_disk_done_mtx; 71 | |
72static g_access_t g_disk_access; | 71static g_access_t g_disk_access; |
73static g_init_t g_disk_init; 74static g_fini_t g_disk_fini; | |
75static g_start_t g_disk_start; 76static g_ioctl_t g_disk_ioctl; 77static g_dumpconf_t g_disk_dumpconf; 78static g_provgone_t g_disk_providergone; 79 80static struct g_class g_disk_class = { 81 .name = "DISK", 82 .version = G_VERSION, | 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, |
83 .init = g_disk_init, 84 .fini = g_disk_fini, | |
85 .start = g_disk_start, 86 .access = g_disk_access, 87 .ioctl = g_disk_ioctl, 88 .providergone = g_disk_providergone, 89 .dumpconf = g_disk_dumpconf, 90}; 91 92SYSCTL_DECL(_kern_geom); 93static SYSCTL_NODE(_kern_geom, OID_AUTO, disk, CTLFLAG_RW, 0, 94 "GEOM_DISK stuff"); 95 | 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 |
96static void 97g_disk_init(struct g_class *mp __unused) 98{ 99 100 mtx_init(&g_disk_done_mtx, "g_disk_done", NULL, MTX_DEF); 101} 102 103static void 104g_disk_fini(struct g_class *mp __unused) 105{ 106 107 mtx_destroy(&g_disk_done_mtx); 108} 109 | |
110DECLARE_GEOM_CLASS(g_disk_class, g_disk); 111 112static void __inline 113g_disk_lock_giant(struct disk *dp) 114{ 115 116 if (dp->d_flags & DISKFLAG_NEEDSGIANT) 117 mtx_lock(&Giant); --- 12 unchanged lines hidden (view full) --- 130{ 131 struct disk *dp; 132 struct g_disk_softc *sc; 133 int error; 134 135 g_trace(G_T_ACCESS, "g_disk_access(%s, %d, %d, %d)", 136 pp->name, r, w, e); 137 g_topology_assert(); | 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(); |
138 sc = pp->geom->softc; | 119 sc = pp->private; |
139 if (sc == NULL || (dp = sc->dp) == NULL || dp->d_destroyed) { 140 /* 141 * Allow decreasing access count even if disk is not 142 * avaliable anymore. 143 */ 144 if (r <= 0 && w <= 0 && e <= 0) 145 return (0); 146 return (ENXIO); --- 88 unchanged lines hidden (view full) --- 235 } 236 g_io_deliver(bp, 0); 237} 238 239static void 240g_disk_done(struct bio *bp) 241{ 242 struct bio *bp2; | 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; |
243 struct disk *dp; | |
244 struct g_disk_softc *sc; 245 246 /* See "notes" for why we need a mutex here */ 247 /* XXX: will witness accept a mix of Giant/unGiant drivers here ? */ | 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 ? */ |
248 mtx_lock(&g_disk_done_mtx); 249 bp->bio_completed = bp->bio_length - bp->bio_resid; 250 | |
251 bp2 = bp->bio_parent; | 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); |
|
252 if (bp2->bio_error == 0) 253 bp2->bio_error = bp->bio_error; 254 bp2->bio_completed += bp->bio_completed; | 232 if (bp2->bio_error == 0) 233 bp2->bio_error = bp->bio_error; 234 bp2->bio_completed += bp->bio_completed; |
255 if ((bp->bio_cmd & (BIO_READ|BIO_WRITE|BIO_DELETE)) != 0 && 256 (sc = bp2->bio_to->geom->softc) != NULL && 257 (dp = sc->dp) != NULL) { 258 devstat_end_transaction_bio(dp->d_devstat, bp); 259 } | 235 if ((bp->bio_cmd & (BIO_READ|BIO_WRITE|BIO_DELETE)) != 0) 236 devstat_end_transaction_bio(sc->dp->d_devstat, bp); |
260 g_destroy_bio(bp); 261 bp2->bio_inbed++; 262 if (bp2->bio_children == bp2->bio_inbed) { 263 bp2->bio_resid = bp2->bio_bcount - bp2->bio_completed; 264 g_io_deliver(bp2, bp2->bio_error); 265 } | 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 } |
266 mtx_unlock(&g_disk_done_mtx); | 243 mtx_unlock(&sc->done_mtx); |
267} 268 269static int 270g_disk_ioctl(struct g_provider *pp, u_long cmd, void * data, int fflag, struct thread *td) 271{ | 244} 245 246static int 247g_disk_ioctl(struct g_provider *pp, u_long cmd, void * data, int fflag, struct thread *td) 248{ |
272 struct g_geom *gp; | |
273 struct disk *dp; 274 struct g_disk_softc *sc; 275 int error; 276 | 249 struct disk *dp; 250 struct g_disk_softc *sc; 251 int error; 252 |
277 gp = pp->geom; 278 sc = gp->softc; | 253 sc = pp->private; |
279 dp = sc->dp; 280 281 if (dp->d_ioctl == NULL) 282 return (ENOIOCTL); 283 g_disk_lock_giant(dp); 284 error = dp->d_ioctl(dp, cmd, data, fflag, td); 285 g_disk_unlock_giant(dp); 286 return (error); 287} 288 289static void 290g_disk_start(struct bio *bp) 291{ 292 struct bio *bp2, *bp3; 293 struct disk *dp; 294 struct g_disk_softc *sc; 295 int error; 296 off_t off; 297 | 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 |
298 sc = bp->bio_to->geom->softc; | 273 sc = bp->bio_to->private; |
299 if (sc == NULL || (dp = sc->dp) == NULL || dp->d_destroyed) { 300 g_io_deliver(bp, ENXIO); 301 return; 302 } 303 error = EJUSTRETURN; 304 switch(bp->bio_cmd) { 305 case BIO_DELETE: 306 if (!(dp->d_flags & DISKFLAG_CANDELETE)) { --- 184 unchanged lines hidden (view full) --- 491 struct g_disk_softc *sc; 492 char tmpstr[80]; 493 494 if (flag == EV_CANCEL) 495 return; 496 g_topology_assert(); 497 dp = arg; 498 sc = g_malloc(sizeof(*sc), M_WAITOK | M_ZERO); | 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); |
|
499 sc->dp = dp; 500 gp = g_new_geomf(&g_disk_class, "%s%d", dp->d_name, dp->d_unit); 501 gp->softc = sc; 502 pp = g_new_providerf(gp, "%s", gp->name); 503 pp->mediasize = dp->d_mediasize; 504 pp->sectorsize = dp->d_sectorsize; 505 pp->stripeoffset = dp->d_stripeoffset; 506 pp->stripesize = dp->d_stripesize; --- 27 unchanged lines hidden (view full) --- 534 * be getting any more accesses from GEOM. 535 */ 536static void 537g_disk_providergone(struct g_provider *pp) 538{ 539 struct disk *dp; 540 struct g_disk_softc *sc; 541 | 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 |
542 sc = (struct g_disk_softc *)pp->geom->softc; 543 544 /* 545 * If the softc is already NULL, then we've probably been through 546 * g_disk_destroy already; there is nothing for us to do anyway. 547 */ 548 if (sc == NULL) 549 return; 550 | 518 sc = (struct g_disk_softc *)pp->private; |
551 dp = sc->dp; | 519 dp = sc->dp; |
552 553 if (dp->d_gone != NULL) | 520 if (dp != NULL && dp->d_gone != NULL) |
554 dp->d_gone(dp); | 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); |
|
555} 556 557static void 558g_disk_destroy(void *ptr, int flag) 559{ 560 struct disk *dp; 561 struct g_geom *gp; 562 struct g_disk_softc *sc; 563 564 g_topology_assert(); 565 dp = ptr; 566 gp = dp->d_geom; 567 if (gp != NULL) { 568 sc = gp->softc; | 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; |
569 if (sc->sysctl_tree != NULL) { 570 sysctl_ctx_free(&sc->sysctl_ctx); 571 sc->sysctl_tree = NULL; 572 } 573 if (sc->led[0] != 0) { 574 led_set(sc->led, "0"); 575 sc->led[0] = 0; 576 } 577 g_free(sc); 578 gp->softc = NULL; | 548 if (sc != NULL) 549 sc->dp = NULL; 550 dp->d_geom = NULL; |
579 g_wither_geom(gp, ENXIO); 580 } 581 g_free(dp); 582} 583 584/* 585 * We only allow printable characters in disk ident, 586 * the rest is converted to 'x<HH>'. --- 163 unchanged lines hidden --- | 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 --- |