Deleted Added
full compact
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 ---