Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/geom/geom_subr.c
105569 views
1
/*-
2
* SPDX-License-Identifier: BSD-3-Clause
3
*
4
* Copyright (c) 2002 Poul-Henning Kamp
5
* Copyright (c) 2002 Networks Associates Technology, Inc.
6
* All rights reserved.
7
*
8
* This software was developed for the FreeBSD Project by Poul-Henning Kamp
9
* and NAI Labs, the Security Research Division of Network Associates, Inc.
10
* under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the
11
* DARPA CHATS research program.
12
*
13
* Redistribution and use in source and binary forms, with or without
14
* modification, are permitted provided that the following conditions
15
* are met:
16
* 1. Redistributions of source code must retain the above copyright
17
* notice, this list of conditions and the following disclaimer.
18
* 2. Redistributions in binary form must reproduce the above copyright
19
* notice, this list of conditions and the following disclaimer in the
20
* documentation and/or other materials provided with the distribution.
21
* 3. The names of the authors may not be used to endorse or promote
22
* products derived from this software without specific prior written
23
* permission.
24
*
25
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
26
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
29
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35
* SUCH DAMAGE.
36
*/
37
38
#include <sys/cdefs.h>
39
#include "opt_ddb.h"
40
41
#define EXTERR_CATEGORY EXTERR_CAT_GEOM
42
#include <sys/param.h>
43
#include <sys/systm.h>
44
#include <sys/devicestat.h>
45
#include <sys/exterrvar.h>
46
#include <sys/kernel.h>
47
#include <sys/malloc.h>
48
#include <sys/bio.h>
49
#include <sys/proc.h>
50
#include <sys/kthread.h>
51
#include <sys/lock.h>
52
#include <sys/mutex.h>
53
#include <sys/errno.h>
54
#include <sys/sbuf.h>
55
#include <sys/sdt.h>
56
#include <sys/stdarg.h>
57
#include <geom/geom.h>
58
#include <geom/geom_dbg.h>
59
#include <geom/geom_int.h>
60
61
#ifdef DDB
62
#include <ddb/ddb.h>
63
#endif
64
65
#ifdef KDB
66
#include <sys/kdb.h>
67
#endif
68
69
SDT_PROVIDER_DEFINE(geom);
70
71
struct class_list_head g_classes = LIST_HEAD_INITIALIZER(g_classes);
72
static struct g_tailq_head geoms = TAILQ_HEAD_INITIALIZER(geoms);
73
char *g_wait_event, *g_wait_up, *g_wait_down;
74
75
struct g_hh00 {
76
struct g_class *mp;
77
struct g_provider *pp;
78
off_t size;
79
int error;
80
int post;
81
};
82
83
void
84
g_dbg_printf(const char *classname, int lvl, struct bio *bp,
85
const char *format,
86
...)
87
{
88
#ifndef PRINTF_BUFR_SIZE
89
#define PRINTF_BUFR_SIZE 64
90
#endif
91
char bufr[PRINTF_BUFR_SIZE];
92
struct sbuf sb, *sbp __unused;
93
va_list ap;
94
95
sbp = sbuf_new(&sb, bufr, sizeof(bufr), SBUF_FIXEDLEN);
96
KASSERT(sbp != NULL, ("sbuf_new misused?"));
97
98
sbuf_set_drain(&sb, sbuf_printf_drain, NULL);
99
100
sbuf_cat(&sb, classname);
101
if (lvl >= 0)
102
sbuf_printf(&sb, "[%d]", lvl);
103
104
va_start(ap, format);
105
sbuf_vprintf(&sb, format, ap);
106
va_end(ap);
107
108
if (bp != NULL) {
109
sbuf_putc(&sb, ' ');
110
g_format_bio(&sb, bp);
111
}
112
113
/* Terminate the debug line with a single '\n'. */
114
sbuf_nl_terminate(&sb);
115
116
/* Flush line to printf. */
117
sbuf_finish(&sb);
118
sbuf_delete(&sb);
119
}
120
121
/*
122
* This event offers a new class a chance to taste all preexisting providers.
123
*/
124
static void
125
g_load_class(void *arg, int flag)
126
{
127
struct g_hh00 *hh;
128
struct g_class *mp2, *mp;
129
struct g_geom *gp;
130
struct g_provider *pp;
131
132
g_topology_assert();
133
if (flag == EV_CANCEL) /* XXX: can't happen ? */
134
return;
135
if (g_shutdown)
136
return;
137
138
hh = arg;
139
mp = hh->mp;
140
hh->error = 0;
141
if (hh->post) {
142
g_free(hh);
143
hh = NULL;
144
}
145
g_trace(G_T_TOPOLOGY, "g_load_class(%s)", mp->name);
146
KASSERT(mp->name != NULL && *mp->name != '\0',
147
("GEOM class has no name"));
148
LIST_FOREACH(mp2, &g_classes, class) {
149
if (mp2 == mp) {
150
printf("The GEOM class %s is already loaded.\n",
151
mp2->name);
152
if (hh != NULL)
153
hh->error = EEXIST;
154
return;
155
} else if (strcmp(mp2->name, mp->name) == 0) {
156
printf("A GEOM class %s is already loaded.\n",
157
mp2->name);
158
if (hh != NULL)
159
hh->error = EEXIST;
160
return;
161
}
162
}
163
164
LIST_INIT(&mp->geom);
165
LIST_INSERT_HEAD(&g_classes, mp, class);
166
if (mp->init != NULL)
167
mp->init(mp);
168
if (mp->taste == NULL)
169
return;
170
LIST_FOREACH(mp2, &g_classes, class) {
171
if (mp == mp2)
172
continue;
173
LIST_FOREACH(gp, &mp2->geom, geom) {
174
LIST_FOREACH(pp, &gp->provider, provider) {
175
mp->taste(mp, pp, 0);
176
g_topology_assert();
177
}
178
}
179
}
180
}
181
182
static int
183
g_unload_class(struct g_class *mp)
184
{
185
struct g_geom *gp;
186
struct g_provider *pp;
187
struct g_consumer *cp;
188
int error;
189
190
g_topology_lock();
191
g_trace(G_T_TOPOLOGY, "g_unload_class(%s)", mp->name);
192
retry:
193
G_VALID_CLASS(mp);
194
LIST_FOREACH(gp, &mp->geom, geom) {
195
/* We refuse to unload if anything is open */
196
LIST_FOREACH(pp, &gp->provider, provider)
197
if (pp->acr || pp->acw || pp->ace) {
198
g_topology_unlock();
199
return (EBUSY);
200
}
201
LIST_FOREACH(cp, &gp->consumer, consumer)
202
if (cp->acr || cp->acw || cp->ace) {
203
g_topology_unlock();
204
return (EBUSY);
205
}
206
/* If the geom is withering, wait for it to finish. */
207
if (gp->flags & G_GEOM_WITHER) {
208
g_topology_sleep(mp, 1);
209
goto retry;
210
}
211
}
212
213
/*
214
* We allow unloading if we have no geoms, or a class
215
* method we can use to get rid of them.
216
*/
217
if (!LIST_EMPTY(&mp->geom) && mp->destroy_geom == NULL) {
218
g_topology_unlock();
219
return (EOPNOTSUPP);
220
}
221
222
/* Bar new entries */
223
mp->taste = NULL;
224
225
LIST_FOREACH(gp, &mp->geom, geom) {
226
error = mp->destroy_geom(NULL, mp, gp);
227
if (error != 0) {
228
g_topology_unlock();
229
return (error);
230
}
231
}
232
/* Wait for withering to finish. */
233
for (;;) {
234
gp = LIST_FIRST(&mp->geom);
235
if (gp == NULL)
236
break;
237
KASSERT(gp->flags & G_GEOM_WITHER,
238
("Non-withering geom in class %s", mp->name));
239
g_topology_sleep(mp, 1);
240
}
241
G_VALID_CLASS(mp);
242
if (mp->fini != NULL)
243
mp->fini(mp);
244
LIST_REMOVE(mp, class);
245
g_topology_unlock();
246
247
return (0);
248
}
249
250
int
251
g_modevent(module_t mod, int type, void *data)
252
{
253
struct g_hh00 *hh;
254
int error;
255
static int g_ignition;
256
struct g_class *mp;
257
258
mp = data;
259
if (mp->version != G_VERSION) {
260
printf("GEOM class %s has Wrong version %x\n",
261
mp->name, mp->version);
262
return (EINVAL);
263
}
264
if (!g_ignition) {
265
g_ignition++;
266
g_init();
267
}
268
error = EOPNOTSUPP;
269
switch (type) {
270
case MOD_LOAD:
271
g_trace(G_T_TOPOLOGY, "g_modevent(%s, LOAD)", mp->name);
272
hh = g_malloc(sizeof(*hh), M_WAITOK | M_ZERO);
273
hh->mp = mp;
274
/*
275
* Once the system is not cold, MOD_LOAD calls will be
276
* from the userland and the g_event thread will be able
277
* to acknowledge their completion.
278
*/
279
if (cold) {
280
hh->post = 1;
281
error = g_post_event(g_load_class, hh, M_WAITOK, NULL);
282
} else {
283
error = g_waitfor_event(g_load_class, hh, M_WAITOK,
284
NULL);
285
if (error == 0)
286
error = hh->error;
287
g_free(hh);
288
}
289
break;
290
case MOD_UNLOAD:
291
g_trace(G_T_TOPOLOGY, "g_modevent(%s, UNLOAD)", mp->name);
292
error = g_unload_class(mp);
293
if (error == 0) {
294
KASSERT(LIST_EMPTY(&mp->geom),
295
("Unloaded class (%s) still has geom", mp->name));
296
}
297
break;
298
}
299
return (error);
300
}
301
302
static void
303
g_retaste_event(void *arg, int flag)
304
{
305
struct g_class *mp, *mp2;
306
struct g_geom *gp;
307
struct g_hh00 *hh;
308
struct g_provider *pp;
309
struct g_consumer *cp;
310
311
g_topology_assert();
312
if (flag == EV_CANCEL) /* XXX: can't happen ? */
313
return;
314
if (g_shutdown || g_notaste)
315
return;
316
317
hh = arg;
318
mp = hh->mp;
319
hh->error = 0;
320
if (hh->post) {
321
g_free(hh);
322
hh = NULL;
323
}
324
g_trace(G_T_TOPOLOGY, "g_retaste(%s)", mp->name);
325
326
LIST_FOREACH(mp2, &g_classes, class) {
327
LIST_FOREACH(gp, &mp2->geom, geom) {
328
LIST_FOREACH(pp, &gp->provider, provider) {
329
if (pp->acr || pp->acw || pp->ace)
330
continue;
331
LIST_FOREACH(cp, &pp->consumers, consumers) {
332
if (cp->geom->class == mp &&
333
(cp->flags & G_CF_ORPHAN) == 0)
334
break;
335
}
336
if (cp != NULL) {
337
cp->flags |= G_CF_ORPHAN;
338
g_wither_geom(cp->geom, ENXIO);
339
}
340
mp->taste(mp, pp, 0);
341
g_topology_assert();
342
}
343
}
344
}
345
}
346
347
int
348
g_retaste(struct g_class *mp)
349
{
350
struct g_hh00 *hh;
351
int error;
352
353
if (mp->taste == NULL)
354
return (EINVAL);
355
356
hh = g_malloc(sizeof(*hh), M_WAITOK | M_ZERO);
357
hh->mp = mp;
358
359
if (cold) {
360
hh->post = 1;
361
error = g_post_event(g_retaste_event, hh, M_WAITOK, NULL);
362
} else {
363
error = g_waitfor_event(g_retaste_event, hh, M_WAITOK, NULL);
364
if (error == 0)
365
error = hh->error;
366
g_free(hh);
367
}
368
369
return (error);
370
}
371
372
struct g_geom *
373
g_new_geom(struct g_class *mp, const char *name)
374
{
375
int len;
376
struct g_geom *gp;
377
378
g_topology_assert();
379
G_VALID_CLASS(mp);
380
len = strlen(name);
381
gp = g_malloc(sizeof(*gp) + len + 1, M_WAITOK | M_ZERO);
382
gp->name = (char *)(gp + 1);
383
gp->class = mp;
384
gp->rank = 1;
385
LIST_INIT(&gp->consumer);
386
LIST_INIT(&gp->provider);
387
LIST_INSERT_HEAD(&mp->geom, gp, geom);
388
TAILQ_INSERT_HEAD(&geoms, gp, geoms);
389
memcpy(gp->name, name, len);
390
/* Fill in defaults from class */
391
gp->start = mp->start;
392
gp->spoiled = mp->spoiled;
393
gp->attrchanged = mp->attrchanged;
394
gp->providergone = mp->providergone;
395
gp->dumpconf = mp->dumpconf;
396
gp->access = mp->access;
397
gp->orphan = mp->orphan;
398
gp->ioctl = mp->ioctl;
399
gp->resize = mp->resize;
400
return (gp);
401
}
402
403
struct g_geom *
404
g_new_geomf(struct g_class *mp, const char *fmt, ...)
405
{
406
struct g_geom *gp;
407
va_list ap;
408
struct sbuf *sb;
409
410
sb = sbuf_new_auto();
411
va_start(ap, fmt);
412
sbuf_vprintf(sb, fmt, ap);
413
va_end(ap);
414
sbuf_finish(sb);
415
gp = g_new_geom(mp, sbuf_data(sb));
416
sbuf_delete(sb);
417
return (gp);
418
}
419
420
void
421
g_destroy_geom(struct g_geom *gp)
422
{
423
424
g_topology_assert();
425
G_VALID_GEOM(gp);
426
g_trace(G_T_TOPOLOGY, "g_destroy_geom(%p(%s))", gp, gp->name);
427
KASSERT(LIST_EMPTY(&gp->consumer),
428
("g_destroy_geom(%s) with consumer(s) [%p]",
429
gp->name, LIST_FIRST(&gp->consumer)));
430
KASSERT(LIST_EMPTY(&gp->provider),
431
("g_destroy_geom(%s) with provider(s) [%p]",
432
gp->name, LIST_FIRST(&gp->provider)));
433
g_cancel_event(gp);
434
LIST_REMOVE(gp, geom);
435
TAILQ_REMOVE(&geoms, gp, geoms);
436
g_free(gp);
437
}
438
439
/*
440
* This function is called (repeatedly) until the geom has withered away.
441
*/
442
void
443
g_wither_geom(struct g_geom *gp, int error)
444
{
445
struct g_provider *pp;
446
447
g_topology_assert();
448
G_VALID_GEOM(gp);
449
g_trace(G_T_TOPOLOGY, "g_wither_geom(%p(%s))", gp, gp->name);
450
if (!(gp->flags & G_GEOM_WITHER)) {
451
gp->flags |= G_GEOM_WITHER;
452
LIST_FOREACH(pp, &gp->provider, provider)
453
if (!(pp->flags & G_PF_ORPHAN))
454
g_orphan_provider(pp, error);
455
}
456
g_do_wither();
457
}
458
459
/*
460
* Convenience function to destroy a particular provider.
461
*/
462
void
463
g_wither_provider(struct g_provider *pp, int error)
464
{
465
466
pp->flags |= G_PF_WITHER;
467
if (!(pp->flags & G_PF_ORPHAN))
468
g_orphan_provider(pp, error);
469
}
470
471
/*
472
* This function is called (repeatedly) until the has withered away.
473
*/
474
void
475
g_wither_geom_close(struct g_geom *gp, int error)
476
{
477
struct g_consumer *cp;
478
479
g_topology_assert();
480
G_VALID_GEOM(gp);
481
g_trace(G_T_TOPOLOGY, "g_wither_geom_close(%p(%s))", gp, gp->name);
482
LIST_FOREACH(cp, &gp->consumer, consumer)
483
if (cp->acr || cp->acw || cp->ace)
484
g_access(cp, -cp->acr, -cp->acw, -cp->ace);
485
g_wither_geom(gp, error);
486
}
487
488
/*
489
* This function is called (repeatedly) until we can't wash away more
490
* withered bits at present.
491
*/
492
void
493
g_wither_washer(void)
494
{
495
struct g_class *mp;
496
struct g_geom *gp, *gp2;
497
struct g_provider *pp, *pp2;
498
struct g_consumer *cp, *cp2;
499
500
g_topology_assert();
501
LIST_FOREACH(mp, &g_classes, class) {
502
LIST_FOREACH_SAFE(gp, &mp->geom, geom, gp2) {
503
LIST_FOREACH_SAFE(pp, &gp->provider, provider, pp2) {
504
if (!(pp->flags & G_PF_WITHER))
505
continue;
506
if (LIST_EMPTY(&pp->consumers))
507
g_destroy_provider(pp);
508
}
509
if (!(gp->flags & G_GEOM_WITHER))
510
continue;
511
LIST_FOREACH_SAFE(pp, &gp->provider, provider, pp2) {
512
if (LIST_EMPTY(&pp->consumers))
513
g_destroy_provider(pp);
514
}
515
LIST_FOREACH_SAFE(cp, &gp->consumer, consumer, cp2) {
516
if (cp->acr || cp->acw || cp->ace)
517
continue;
518
if (cp->provider != NULL)
519
g_detach(cp);
520
g_destroy_consumer(cp);
521
}
522
if (LIST_EMPTY(&gp->provider) &&
523
LIST_EMPTY(&gp->consumer))
524
g_destroy_geom(gp);
525
}
526
}
527
}
528
529
struct g_consumer *
530
g_new_consumer(struct g_geom *gp)
531
{
532
struct g_consumer *cp;
533
534
g_topology_assert();
535
G_VALID_GEOM(gp);
536
KASSERT(!(gp->flags & G_GEOM_WITHER),
537
("g_new_consumer on WITHERing geom(%s) (class %s)",
538
gp->name, gp->class->name));
539
KASSERT(gp->orphan != NULL,
540
("g_new_consumer on geom(%s) (class %s) without orphan",
541
gp->name, gp->class->name));
542
543
cp = g_malloc(sizeof(*cp), M_WAITOK | M_ZERO);
544
cp->geom = gp;
545
cp->stat = devstat_new_entry(cp, -1, 0, DEVSTAT_ALL_SUPPORTED,
546
DEVSTAT_TYPE_DIRECT, DEVSTAT_PRIORITY_MAX);
547
LIST_INSERT_HEAD(&gp->consumer, cp, consumer);
548
return(cp);
549
}
550
551
void
552
g_destroy_consumer(struct g_consumer *cp)
553
{
554
struct g_geom *gp;
555
556
g_topology_assert();
557
G_VALID_CONSUMER(cp);
558
g_trace(G_T_TOPOLOGY, "g_destroy_consumer(%p)", cp);
559
KASSERT (cp->provider == NULL, ("g_destroy_consumer but attached"));
560
KASSERT (cp->acr == 0, ("g_destroy_consumer with acr"));
561
KASSERT (cp->acw == 0, ("g_destroy_consumer with acw"));
562
KASSERT (cp->ace == 0, ("g_destroy_consumer with ace"));
563
g_cancel_event(cp);
564
gp = cp->geom;
565
LIST_REMOVE(cp, consumer);
566
devstat_remove_entry(cp->stat);
567
g_free(cp);
568
if (gp->flags & G_GEOM_WITHER)
569
g_do_wither();
570
}
571
572
static void
573
g_new_provider_event(void *arg, int flag)
574
{
575
struct g_class *mp;
576
struct g_provider *pp;
577
struct g_consumer *cp, *next_cp;
578
579
g_topology_assert();
580
if (flag == EV_CANCEL)
581
return;
582
if (g_shutdown)
583
return;
584
pp = arg;
585
G_VALID_PROVIDER(pp);
586
if ((pp->flags & G_PF_WITHER) != 0)
587
return;
588
LIST_FOREACH_SAFE(cp, &pp->consumers, consumers, next_cp) {
589
if ((cp->flags & G_CF_ORPHAN) == 0 &&
590
cp->geom->attrchanged != NULL)
591
cp->geom->attrchanged(cp, "GEOM::media");
592
}
593
if (g_notaste)
594
return;
595
LIST_FOREACH(mp, &g_classes, class) {
596
if (mp->taste == NULL)
597
continue;
598
LIST_FOREACH(cp, &pp->consumers, consumers)
599
if (cp->geom->class == mp &&
600
(cp->flags & G_CF_ORPHAN) == 0)
601
break;
602
if (cp != NULL)
603
continue;
604
mp->taste(mp, pp, 0);
605
g_topology_assert();
606
}
607
}
608
609
struct g_provider *
610
g_new_providerf(struct g_geom *gp, const char *fmt, ...)
611
{
612
struct g_provider *pp;
613
struct sbuf *sb;
614
va_list ap;
615
616
g_topology_assert();
617
G_VALID_GEOM(gp);
618
KASSERT(gp->access != NULL,
619
("new provider on geom(%s) without ->access (class %s)",
620
gp->name, gp->class->name));
621
KASSERT(gp->start != NULL,
622
("new provider on geom(%s) without ->start (class %s)",
623
gp->name, gp->class->name));
624
KASSERT(!(gp->flags & G_GEOM_WITHER),
625
("new provider on WITHERing geom(%s) (class %s)",
626
gp->name, gp->class->name));
627
sb = sbuf_new_auto();
628
va_start(ap, fmt);
629
sbuf_vprintf(sb, fmt, ap);
630
va_end(ap);
631
sbuf_finish(sb);
632
pp = g_malloc(sizeof(*pp) + sbuf_len(sb) + 1, M_WAITOK | M_ZERO);
633
pp->name = (char *)(pp + 1);
634
strcpy(pp->name, sbuf_data(sb));
635
sbuf_delete(sb);
636
LIST_INIT(&pp->consumers);
637
LIST_INIT(&pp->aliases);
638
pp->error = ENXIO;
639
pp->geom = gp;
640
pp->stat = devstat_new_entry(pp, -1, 0, DEVSTAT_ALL_SUPPORTED,
641
DEVSTAT_TYPE_DIRECT, DEVSTAT_PRIORITY_MAX);
642
LIST_INSERT_HEAD(&gp->provider, pp, provider);
643
g_post_event(g_new_provider_event, pp, M_WAITOK, pp, gp, NULL);
644
return (pp);
645
}
646
647
void
648
g_provider_add_alias(struct g_provider *pp, const char *fmt, ...)
649
{
650
struct sbuf *sb;
651
struct g_geom_alias *gap;
652
va_list ap;
653
654
/*
655
* Generate the alias string and save it in the list.
656
*/
657
sb = sbuf_new_auto();
658
va_start(ap, fmt);
659
sbuf_vprintf(sb, fmt, ap);
660
va_end(ap);
661
sbuf_finish(sb);
662
663
LIST_FOREACH(gap, &pp->aliases, ga_next) {
664
if (strcmp(gap->ga_alias, sbuf_data(sb)) != 0)
665
continue;
666
/* Don't re-add the same alias. */
667
sbuf_delete(sb);
668
return;
669
}
670
671
gap = g_malloc(sizeof(*gap) + sbuf_len(sb) + 1, M_WAITOK | M_ZERO);
672
memcpy((char *)(gap + 1), sbuf_data(sb), sbuf_len(sb));
673
sbuf_delete(sb);
674
gap->ga_alias = (const char *)(gap + 1);
675
LIST_INSERT_HEAD(&pp->aliases, gap, ga_next);
676
}
677
678
void
679
g_error_provider(struct g_provider *pp, int error)
680
{
681
682
/* G_VALID_PROVIDER(pp); We may not have g_topology */
683
pp->error = error;
684
}
685
686
static void
687
g_resize_provider_event(void *arg, int flag)
688
{
689
struct g_hh00 *hh;
690
struct g_class *mp;
691
struct g_geom *gp;
692
struct g_provider *pp;
693
struct g_consumer *cp, *cp2;
694
off_t size;
695
696
g_topology_assert();
697
if (g_shutdown)
698
return;
699
700
hh = arg;
701
pp = hh->pp;
702
size = hh->size;
703
g_free(hh);
704
705
G_VALID_PROVIDER(pp);
706
KASSERT(!(pp->flags & G_PF_WITHER),
707
("g_resize_provider_event but withered"));
708
g_trace(G_T_TOPOLOGY, "g_resize_provider_event(%p)", pp);
709
710
LIST_FOREACH_SAFE(cp, &pp->consumers, consumers, cp2) {
711
gp = cp->geom;
712
if (gp->resize == NULL && size < pp->mediasize) {
713
/*
714
* XXX: g_dev_orphan method does deferred destroying
715
* and it is possible, that other event could already
716
* call the orphan method. Check consumer's flags to
717
* do not schedule it twice.
718
*/
719
if (cp->flags & G_CF_ORPHAN)
720
continue;
721
cp->flags |= G_CF_ORPHAN;
722
cp->geom->orphan(cp);
723
}
724
}
725
726
pp->mediasize = size;
727
728
LIST_FOREACH_SAFE(cp, &pp->consumers, consumers, cp2) {
729
gp = cp->geom;
730
if ((gp->flags & G_GEOM_WITHER) == 0 && gp->resize != NULL)
731
gp->resize(cp);
732
}
733
734
/*
735
* After resizing, the previously invalid GEOM class metadata
736
* might become valid. This means we should retaste.
737
*/
738
LIST_FOREACH(mp, &g_classes, class) {
739
if (mp->taste == NULL)
740
continue;
741
LIST_FOREACH(cp, &pp->consumers, consumers)
742
if (cp->geom->class == mp &&
743
(cp->flags & G_CF_ORPHAN) == 0)
744
break;
745
if (cp != NULL)
746
continue;
747
mp->taste(mp, pp, 0);
748
g_topology_assert();
749
}
750
}
751
752
void
753
g_resize_provider(struct g_provider *pp, off_t size)
754
{
755
struct g_hh00 *hh;
756
757
G_VALID_PROVIDER(pp);
758
if (pp->flags & G_PF_WITHER)
759
return;
760
761
if (size == pp->mediasize)
762
return;
763
764
hh = g_malloc(sizeof(*hh), M_WAITOK | M_ZERO);
765
hh->pp = pp;
766
hh->size = size;
767
g_post_event(g_resize_provider_event, hh, M_WAITOK, NULL);
768
}
769
770
struct g_provider *
771
g_provider_by_name(char const *arg)
772
{
773
struct g_class *cp;
774
struct g_geom *gp;
775
struct g_provider *pp, *wpp;
776
777
if (strncmp(arg, _PATH_DEV, sizeof(_PATH_DEV) - 1) == 0)
778
arg += sizeof(_PATH_DEV) - 1;
779
780
wpp = NULL;
781
LIST_FOREACH(cp, &g_classes, class) {
782
LIST_FOREACH(gp, &cp->geom, geom) {
783
LIST_FOREACH(pp, &gp->provider, provider) {
784
if (strcmp(arg, pp->name) != 0)
785
continue;
786
if ((gp->flags & G_GEOM_WITHER) == 0 &&
787
(pp->flags & G_PF_WITHER) == 0)
788
return (pp);
789
else
790
wpp = pp;
791
}
792
}
793
}
794
795
return (wpp);
796
}
797
798
void
799
g_destroy_provider(struct g_provider *pp)
800
{
801
struct g_geom *gp;
802
struct g_geom_alias *gap, *gaptmp;
803
804
g_topology_assert();
805
G_VALID_PROVIDER(pp);
806
KASSERT(LIST_EMPTY(&pp->consumers),
807
("g_destroy_provider but attached"));
808
KASSERT (pp->acr == 0, ("g_destroy_provider with acr"));
809
KASSERT (pp->acw == 0, ("g_destroy_provider with acw"));
810
KASSERT (pp->ace == 0, ("g_destroy_provider with ace"));
811
g_cancel_event(pp);
812
LIST_REMOVE(pp, provider);
813
gp = pp->geom;
814
devstat_remove_entry(pp->stat);
815
/*
816
* If a callback was provided, send notification that the provider
817
* is now gone.
818
*/
819
if (gp->providergone != NULL)
820
gp->providergone(pp);
821
LIST_FOREACH_SAFE(gap, &pp->aliases, ga_next, gaptmp)
822
g_free(gap);
823
g_free(pp);
824
if ((gp->flags & G_GEOM_WITHER))
825
g_do_wither();
826
}
827
828
/*
829
* We keep the "geoms" list sorted by topological order (== increasing
830
* numerical rank) at all times.
831
* When an attach is done, the attaching geoms rank is invalidated
832
* and it is moved to the tail of the list.
833
* All geoms later in the sequence has their ranks reevaluated in
834
* sequence. If we cannot assign rank to a geom because it's
835
* prerequisites do not have rank, we move that element to the tail
836
* of the sequence with invalid rank as well.
837
* At some point we encounter our original geom and if we stil fail
838
* to assign it a rank, there must be a loop and we fail back to
839
* g_attach() which detach again and calls redo_rank again
840
* to fix up the damage.
841
* It would be much simpler code wise to do it recursively, but we
842
* can't risk that on the kernel stack.
843
*/
844
845
static int
846
redo_rank(struct g_geom *gp)
847
{
848
struct g_consumer *cp;
849
struct g_geom *gp1, *gp2;
850
int n, m;
851
852
g_topology_assert();
853
G_VALID_GEOM(gp);
854
855
/* Invalidate this geoms rank and move it to the tail */
856
gp1 = TAILQ_NEXT(gp, geoms);
857
if (gp1 != NULL) {
858
gp->rank = 0;
859
TAILQ_REMOVE(&geoms, gp, geoms);
860
TAILQ_INSERT_TAIL(&geoms, gp, geoms);
861
} else {
862
gp1 = gp;
863
}
864
865
/* re-rank the rest of the sequence */
866
for (; gp1 != NULL; gp1 = gp2) {
867
gp1->rank = 0;
868
m = 1;
869
LIST_FOREACH(cp, &gp1->consumer, consumer) {
870
if (cp->provider == NULL)
871
continue;
872
n = cp->provider->geom->rank;
873
if (n == 0) {
874
m = 0;
875
break;
876
} else if (n >= m)
877
m = n + 1;
878
}
879
gp1->rank = m;
880
gp2 = TAILQ_NEXT(gp1, geoms);
881
882
/* got a rank, moving on */
883
if (m != 0)
884
continue;
885
886
/* no rank to original geom means loop */
887
if (gp == gp1)
888
return (ELOOP);
889
890
/* no rank, put it at the end move on */
891
TAILQ_REMOVE(&geoms, gp1, geoms);
892
TAILQ_INSERT_TAIL(&geoms, gp1, geoms);
893
}
894
return (0);
895
}
896
897
int
898
g_attach(struct g_consumer *cp, struct g_provider *pp)
899
{
900
int error;
901
902
g_topology_assert();
903
G_VALID_CONSUMER(cp);
904
G_VALID_PROVIDER(pp);
905
g_trace(G_T_TOPOLOGY, "g_attach(%p, %p)", cp, pp);
906
KASSERT(cp->provider == NULL, ("attach but attached"));
907
if ((pp->flags & (G_PF_ORPHAN | G_PF_WITHER)) != 0)
908
return (ENXIO);
909
cp->provider = pp;
910
cp->flags &= ~G_CF_ORPHAN;
911
LIST_INSERT_HEAD(&pp->consumers, cp, consumers);
912
error = redo_rank(cp->geom);
913
if (error) {
914
LIST_REMOVE(cp, consumers);
915
cp->provider = NULL;
916
redo_rank(cp->geom);
917
}
918
return (error);
919
}
920
921
void
922
g_detach(struct g_consumer *cp)
923
{
924
struct g_provider *pp;
925
926
g_topology_assert();
927
G_VALID_CONSUMER(cp);
928
g_trace(G_T_TOPOLOGY, "g_detach(%p)", cp);
929
KASSERT(cp->provider != NULL, ("detach but not attached"));
930
KASSERT(cp->acr == 0, ("detach but nonzero acr"));
931
KASSERT(cp->acw == 0, ("detach but nonzero acw"));
932
KASSERT(cp->ace == 0, ("detach but nonzero ace"));
933
KASSERT(cp->nstart == cp->nend,
934
("detach with active requests"));
935
pp = cp->provider;
936
LIST_REMOVE(cp, consumers);
937
cp->provider = NULL;
938
if ((cp->geom->flags & G_GEOM_WITHER) ||
939
(pp->geom->flags & G_GEOM_WITHER) ||
940
(pp->flags & G_PF_WITHER))
941
g_do_wither();
942
redo_rank(cp->geom);
943
}
944
945
/*
946
* g_access()
947
*
948
* Access-check with delta values. The question asked is "can provider
949
* "cp" change the access counters by the relative amounts dc[rwe] ?"
950
*/
951
952
int
953
g_access(struct g_consumer *cp, int dcr, int dcw, int dce)
954
{
955
struct g_provider *pp;
956
struct g_geom *gp;
957
int pw, pe;
958
#ifdef INVARIANTS
959
int sr, sw, se;
960
#endif
961
int error;
962
963
g_topology_assert();
964
G_VALID_CONSUMER(cp);
965
pp = cp->provider;
966
KASSERT(pp != NULL, ("access but not attached"));
967
G_VALID_PROVIDER(pp);
968
gp = pp->geom;
969
970
g_trace(G_T_ACCESS, "g_access(%p(%s), %d, %d, %d)",
971
cp, pp->name, dcr, dcw, dce);
972
973
KASSERT(cp->acr + dcr >= 0, ("access resulting in negative acr"));
974
KASSERT(cp->acw + dcw >= 0, ("access resulting in negative acw"));
975
KASSERT(cp->ace + dce >= 0, ("access resulting in negative ace"));
976
KASSERT(dcr != 0 || dcw != 0 || dce != 0, ("NOP access request"));
977
KASSERT(cp->acr + dcr != 0 || cp->acw + dcw != 0 ||
978
cp->ace + dce != 0 || cp->nstart == cp->nend,
979
("Last close with active requests"));
980
KASSERT(gp->access != NULL, ("NULL geom->access"));
981
982
/*
983
* If our class cares about being spoiled, and we have been, we
984
* are probably just ahead of the event telling us that. Fail
985
* now rather than having to unravel this later.
986
*/
987
if (cp->geom->spoiled != NULL && (cp->flags & G_CF_SPOILED) &&
988
(dcr > 0 || dcw > 0 || dce > 0))
989
return (ENXIO);
990
991
/*
992
* A number of GEOM classes either need to perform an I/O on the first
993
* open or to acquire a different subsystem's lock. To do that they
994
* may have to drop the topology lock.
995
* Other GEOM classes perform special actions when opening a lower rank
996
* geom for the first time. As a result, more than one thread may
997
* end up performing the special actions.
998
* So, we prevent concurrent "first" opens by marking the consumer with
999
* special flag.
1000
*
1001
* Note that if the geom's access method never drops the topology lock,
1002
* then we will never see G_GEOM_IN_ACCESS here.
1003
*/
1004
while ((gp->flags & G_GEOM_IN_ACCESS) != 0) {
1005
g_trace(G_T_ACCESS,
1006
"%s: race on geom %s via provider %s and consumer of %s",
1007
__func__, gp->name, pp->name, cp->geom->name);
1008
gp->flags |= G_GEOM_ACCESS_WAIT;
1009
g_topology_sleep(gp, 0);
1010
}
1011
1012
/*
1013
* Figure out what counts the provider would have had, if this
1014
* consumer had (r0w0e0) at this time.
1015
*/
1016
pw = pp->acw - cp->acw;
1017
pe = pp->ace - cp->ace;
1018
1019
g_trace(G_T_ACCESS,
1020
"open delta:[r%dw%de%d] old:[r%dw%de%d] provider:[r%dw%de%d] %p(%s)",
1021
dcr, dcw, dce,
1022
cp->acr, cp->acw, cp->ace,
1023
pp->acr, pp->acw, pp->ace,
1024
pp, pp->name);
1025
1026
/* If foot-shooting is enabled, any open on rank#1 is OK */
1027
if ((g_debugflags & G_F_FOOTSHOOTING) && gp->rank == 1)
1028
;
1029
/* If we try exclusive but already write: fail */
1030
else if (dce > 0 && pw > 0)
1031
return (EPERM);
1032
/* If we try write but already exclusive: fail */
1033
else if (dcw > 0 && pe > 0)
1034
return (EPERM);
1035
/* If we try to open more but provider is error'ed: fail */
1036
else if ((dcr > 0 || dcw > 0 || dce > 0) && pp->error != 0) {
1037
printf("%s(%d): provider %s has error %d set\n",
1038
__func__, __LINE__, pp->name, pp->error);
1039
return (pp->error);
1040
}
1041
1042
/* Ok then... */
1043
1044
#ifdef INVARIANTS
1045
sr = cp->acr;
1046
sw = cp->acw;
1047
se = cp->ace;
1048
#endif
1049
gp->flags |= G_GEOM_IN_ACCESS;
1050
error = gp->access(pp, dcr, dcw, dce);
1051
KASSERT(dcr > 0 || dcw > 0 || dce > 0 || error == 0,
1052
("Geom provider %s::%s dcr=%d dcw=%d dce=%d error=%d failed "
1053
"closing ->access()", gp->class->name, pp->name, dcr, dcw,
1054
dce, error));
1055
1056
g_topology_assert();
1057
gp->flags &= ~G_GEOM_IN_ACCESS;
1058
KASSERT(cp->acr == sr && cp->acw == sw && cp->ace == se,
1059
("Access counts changed during geom->access"));
1060
if ((gp->flags & G_GEOM_ACCESS_WAIT) != 0) {
1061
gp->flags &= ~G_GEOM_ACCESS_WAIT;
1062
wakeup(gp);
1063
}
1064
1065
if (!error) {
1066
/*
1067
* If we open first write, spoil any partner consumers.
1068
* If we close last write and provider is not errored,
1069
* trigger re-taste.
1070
*/
1071
if (pp->acw == 0 && dcw != 0)
1072
g_spoil(pp, cp);
1073
else if (pp->acw != 0 && pp->acw == -dcw && pp->error == 0 &&
1074
!(gp->flags & G_GEOM_WITHER))
1075
g_post_event(g_new_provider_event, pp, M_WAITOK,
1076
pp, NULL);
1077
1078
pp->acr += dcr;
1079
pp->acw += dcw;
1080
pp->ace += dce;
1081
cp->acr += dcr;
1082
cp->acw += dcw;
1083
cp->ace += dce;
1084
if (pp->acr != 0 || pp->acw != 0 || pp->ace != 0)
1085
KASSERT(pp->sectorsize > 0,
1086
("Provider %s lacks sectorsize", pp->name));
1087
if ((cp->geom->flags & G_GEOM_WITHER) &&
1088
cp->acr == 0 && cp->acw == 0 && cp->ace == 0)
1089
g_do_wither();
1090
}
1091
return (error);
1092
}
1093
1094
int
1095
g_handleattr_int(struct bio *bp, const char *attribute, int val)
1096
{
1097
1098
return (g_handleattr(bp, attribute, &val, sizeof(val)));
1099
}
1100
1101
int
1102
g_handleattr_uint16_t(struct bio *bp, const char *attribute, uint16_t val)
1103
{
1104
1105
return (g_handleattr(bp, attribute, &val, sizeof(val)));
1106
}
1107
1108
int
1109
g_handleattr_off_t(struct bio *bp, const char *attribute, off_t val)
1110
{
1111
1112
return (g_handleattr(bp, attribute, &val, sizeof(val)));
1113
}
1114
1115
int
1116
g_handleattr_str(struct bio *bp, const char *attribute, const char *str)
1117
{
1118
1119
return (g_handleattr(bp, attribute, str, 0));
1120
}
1121
1122
int
1123
g_handleattr(struct bio *bp, const char *attribute, const void *val, int len)
1124
{
1125
int error = 0;
1126
1127
if (strcmp(bp->bio_attribute, attribute))
1128
return (0);
1129
if (len == 0) {
1130
bzero(bp->bio_data, bp->bio_length);
1131
if (strlcpy(bp->bio_data, val, bp->bio_length) >=
1132
bp->bio_length) {
1133
printf("%s: %s %s bio_length %jd strlen %zu -> EFAULT\n",
1134
__func__, bp->bio_to->name, attribute,
1135
(intmax_t)bp->bio_length, strlen(val));
1136
error = EFAULT;
1137
}
1138
} else if (bp->bio_length == len) {
1139
bcopy(val, bp->bio_data, len);
1140
} else {
1141
printf("%s: %s %s bio_length %jd len %d -> EFAULT\n", __func__,
1142
bp->bio_to->name, attribute, (intmax_t)bp->bio_length, len);
1143
error = EFAULT;
1144
}
1145
if (error == 0)
1146
bp->bio_completed = bp->bio_length;
1147
g_io_deliver(bp, error);
1148
return (1);
1149
}
1150
1151
int
1152
g_std_access(struct g_provider *pp,
1153
int dr __unused, int dw __unused, int de __unused)
1154
{
1155
1156
g_topology_assert();
1157
G_VALID_PROVIDER(pp);
1158
return (0);
1159
}
1160
1161
void
1162
g_std_done(struct bio *bp)
1163
{
1164
struct bio *bp2;
1165
1166
bp2 = bp->bio_parent;
1167
if (bp2->bio_error == 0) {
1168
if ((bp->bio_flags & BIO_EXTERR) != 0) {
1169
bp2->bio_flags |= BIO_EXTERR;
1170
bp2->bio_exterr = bp->bio_exterr;
1171
} else {
1172
bp2->bio_error = bp->bio_error;
1173
}
1174
}
1175
bp2->bio_completed += bp->bio_completed;
1176
g_destroy_bio(bp);
1177
bp2->bio_inbed++;
1178
if (bp2->bio_children == bp2->bio_inbed) {
1179
if (bp2->bio_cmd == BIO_SPEEDUP)
1180
bp2->bio_completed = bp2->bio_length;
1181
g_io_deliver(bp2, bp2->bio_error);
1182
}
1183
}
1184
1185
/* XXX: maybe this is only g_slice_spoiled */
1186
1187
void
1188
g_std_spoiled(struct g_consumer *cp)
1189
{
1190
struct g_geom *gp;
1191
struct g_provider *pp;
1192
1193
g_topology_assert();
1194
G_VALID_CONSUMER(cp);
1195
g_trace(G_T_TOPOLOGY, "g_std_spoiled(%p)", cp);
1196
cp->flags |= G_CF_ORPHAN;
1197
g_detach(cp);
1198
gp = cp->geom;
1199
LIST_FOREACH(pp, &gp->provider, provider)
1200
g_orphan_provider(pp, ENXIO);
1201
g_destroy_consumer(cp);
1202
if (LIST_EMPTY(&gp->provider) && LIST_EMPTY(&gp->consumer))
1203
g_destroy_geom(gp);
1204
else
1205
gp->flags |= G_GEOM_WITHER;
1206
}
1207
1208
/*
1209
* Spoiling happens when a provider is opened for writing, but consumers
1210
* which are configured by in-band data are attached (slicers for instance).
1211
* Since the write might potentially change the in-band data, such consumers
1212
* need to re-evaluate their existence after the writing session closes.
1213
* We do this by (offering to) tear them down when the open for write happens
1214
* in return for a re-taste when it closes again.
1215
* Together with the fact that such consumers grab an 'e' bit whenever they
1216
* are open, regardless of mode, this ends up DTRT.
1217
*/
1218
1219
static void
1220
g_spoil_event(void *arg, int flag)
1221
{
1222
struct g_provider *pp;
1223
struct g_consumer *cp, *cp2;
1224
1225
g_topology_assert();
1226
if (flag == EV_CANCEL)
1227
return;
1228
pp = arg;
1229
G_VALID_PROVIDER(pp);
1230
g_trace(G_T_TOPOLOGY, "%s %p(%s:%s:%s)", __func__, pp,
1231
pp->geom->class->name, pp->geom->name, pp->name);
1232
for (cp = LIST_FIRST(&pp->consumers); cp != NULL; cp = cp2) {
1233
cp2 = LIST_NEXT(cp, consumers);
1234
if ((cp->flags & G_CF_SPOILED) == 0)
1235
continue;
1236
cp->flags &= ~G_CF_SPOILED;
1237
if (cp->geom->spoiled == NULL)
1238
continue;
1239
cp->geom->spoiled(cp);
1240
g_topology_assert();
1241
}
1242
}
1243
1244
void
1245
g_spoil(struct g_provider *pp, struct g_consumer *cp)
1246
{
1247
struct g_consumer *cp2;
1248
1249
g_topology_assert();
1250
G_VALID_PROVIDER(pp);
1251
G_VALID_CONSUMER(cp);
1252
1253
LIST_FOREACH(cp2, &pp->consumers, consumers) {
1254
if (cp2 == cp)
1255
continue;
1256
/*
1257
KASSERT(cp2->acr == 0, ("spoiling cp->acr = %d", cp2->acr));
1258
KASSERT(cp2->acw == 0, ("spoiling cp->acw = %d", cp2->acw));
1259
*/
1260
KASSERT(cp2->ace == 0, ("spoiling cp->ace = %d", cp2->ace));
1261
cp2->flags |= G_CF_SPOILED;
1262
}
1263
g_post_event(g_spoil_event, pp, M_WAITOK, pp, NULL);
1264
}
1265
1266
static void
1267
g_media_changed_event(void *arg, int flag)
1268
{
1269
struct g_provider *pp;
1270
int retaste;
1271
1272
g_topology_assert();
1273
if (flag == EV_CANCEL)
1274
return;
1275
pp = arg;
1276
G_VALID_PROVIDER(pp);
1277
1278
/*
1279
* If provider was not open for writing, queue retaste after spoiling.
1280
* If it was, retaste will happen automatically on close.
1281
*/
1282
retaste = (pp->acw == 0 && pp->error == 0 &&
1283
!(pp->geom->flags & G_GEOM_WITHER));
1284
g_spoil_event(arg, flag);
1285
if (retaste)
1286
g_post_event(g_new_provider_event, pp, M_WAITOK, pp, NULL);
1287
}
1288
1289
int
1290
g_media_changed(struct g_provider *pp, int flag)
1291
{
1292
struct g_consumer *cp;
1293
1294
LIST_FOREACH(cp, &pp->consumers, consumers)
1295
cp->flags |= G_CF_SPOILED;
1296
return (g_post_event(g_media_changed_event, pp, flag, pp, NULL));
1297
}
1298
1299
int
1300
g_media_gone(struct g_provider *pp, int flag)
1301
{
1302
struct g_consumer *cp;
1303
1304
LIST_FOREACH(cp, &pp->consumers, consumers)
1305
cp->flags |= G_CF_SPOILED;
1306
return (g_post_event(g_spoil_event, pp, flag, pp, NULL));
1307
}
1308
1309
int
1310
g_getattr__(const char *attr, struct g_consumer *cp, void *var, int len)
1311
{
1312
int error, i;
1313
1314
i = len;
1315
error = g_io_getattr(attr, cp, &i, var);
1316
if (error)
1317
return (error);
1318
if (i != len)
1319
return (EINVAL);
1320
return (0);
1321
}
1322
1323
static int
1324
g_get_device_prefix_len(const char *name)
1325
{
1326
int len;
1327
1328
if (strncmp(name, "ada", 3) == 0)
1329
len = 3;
1330
else if (strncmp(name, "ad", 2) == 0)
1331
len = 2;
1332
else
1333
return (0);
1334
if (name[len] < '0' || name[len] > '9')
1335
return (0);
1336
do {
1337
len++;
1338
} while (name[len] >= '0' && name[len] <= '9');
1339
return (len);
1340
}
1341
1342
int
1343
g_compare_names(const char *namea, const char *nameb)
1344
{
1345
int deva, devb;
1346
1347
if (strcmp(namea, nameb) == 0)
1348
return (1);
1349
deva = g_get_device_prefix_len(namea);
1350
if (deva == 0)
1351
return (0);
1352
devb = g_get_device_prefix_len(nameb);
1353
if (devb == 0)
1354
return (0);
1355
if (strcmp(namea + deva, nameb + devb) == 0)
1356
return (1);
1357
return (0);
1358
}
1359
1360
#if defined(DIAGNOSTIC) || defined(DDB)
1361
/*
1362
* This function walks the mesh and returns a non-zero integer if it
1363
* finds the argument pointer is an object. The return value indicates
1364
* which type of object it is believed to be. If topology is not locked,
1365
* this function is potentially dangerous, but we don't assert that the
1366
* topology lock is held when called from debugger.
1367
*/
1368
int
1369
g_valid_obj(void const *ptr)
1370
{
1371
struct g_class *mp;
1372
struct g_geom *gp;
1373
struct g_consumer *cp;
1374
struct g_provider *pp;
1375
1376
#ifdef KDB
1377
if (kdb_active == 0)
1378
#endif
1379
g_topology_assert();
1380
1381
LIST_FOREACH(mp, &g_classes, class) {
1382
if (ptr == mp)
1383
return (1);
1384
LIST_FOREACH(gp, &mp->geom, geom) {
1385
if (ptr == gp)
1386
return (2);
1387
LIST_FOREACH(cp, &gp->consumer, consumer)
1388
if (ptr == cp)
1389
return (3);
1390
LIST_FOREACH(pp, &gp->provider, provider)
1391
if (ptr == pp)
1392
return (4);
1393
}
1394
}
1395
return(0);
1396
}
1397
#endif
1398
1399
#ifdef DDB
1400
1401
#define gprintf(...) do { \
1402
db_printf("%*s", indent, ""); \
1403
db_printf(__VA_ARGS__); \
1404
} while (0)
1405
#define gprintln(...) do { \
1406
gprintf(__VA_ARGS__); \
1407
db_printf("\n"); \
1408
} while (0)
1409
1410
#define ADDFLAG(obj, flag, sflag) do { \
1411
if ((obj)->flags & (flag)) { \
1412
if (comma) \
1413
strlcat(str, ",", size); \
1414
strlcat(str, (sflag), size); \
1415
comma = 1; \
1416
} \
1417
} while (0)
1418
1419
static char *
1420
provider_flags_to_string(struct g_provider *pp, char *str, size_t size)
1421
{
1422
int comma = 0;
1423
1424
bzero(str, size);
1425
if (pp->flags == 0) {
1426
strlcpy(str, "NONE", size);
1427
return (str);
1428
}
1429
ADDFLAG(pp, G_PF_WITHER, "G_PF_WITHER");
1430
ADDFLAG(pp, G_PF_ORPHAN, "G_PF_ORPHAN");
1431
return (str);
1432
}
1433
1434
static char *
1435
geom_flags_to_string(struct g_geom *gp, char *str, size_t size)
1436
{
1437
int comma = 0;
1438
1439
bzero(str, size);
1440
if (gp->flags == 0) {
1441
strlcpy(str, "NONE", size);
1442
return (str);
1443
}
1444
ADDFLAG(gp, G_GEOM_WITHER, "G_GEOM_WITHER");
1445
return (str);
1446
}
1447
static void
1448
db_show_geom_consumer(int indent, struct g_consumer *cp)
1449
{
1450
1451
if (indent == 0) {
1452
gprintln("consumer: %p", cp);
1453
gprintln(" class: %s (%p)", cp->geom->class->name,
1454
cp->geom->class);
1455
gprintln(" geom: %s (%p)", cp->geom->name, cp->geom);
1456
if (cp->provider == NULL)
1457
gprintln(" provider: none");
1458
else {
1459
gprintln(" provider: %s (%p)", cp->provider->name,
1460
cp->provider);
1461
}
1462
gprintln(" access: r%dw%de%d", cp->acr, cp->acw, cp->ace);
1463
gprintln(" flags: 0x%04x", cp->flags);
1464
#ifdef INVARIANTS
1465
gprintln(" nstart: %u", cp->nstart);
1466
gprintln(" nend: %u", cp->nend);
1467
#endif
1468
} else {
1469
gprintf("consumer: %p (%s), access=r%dw%de%d", cp,
1470
cp->provider != NULL ? cp->provider->name : "none",
1471
cp->acr, cp->acw, cp->ace);
1472
if (cp->flags)
1473
db_printf(", flags=0x%04x", cp->flags);
1474
db_printf("\n");
1475
}
1476
}
1477
1478
static void
1479
db_show_geom_provider(int indent, struct g_provider *pp)
1480
{
1481
struct g_consumer *cp;
1482
char flags[64];
1483
1484
if (indent == 0) {
1485
gprintln("provider: %s (%p)", pp->name, pp);
1486
gprintln(" class: %s (%p)", pp->geom->class->name,
1487
pp->geom->class);
1488
gprintln(" geom: %s (%p)", pp->geom->name, pp->geom);
1489
gprintln(" mediasize: %jd", (intmax_t)pp->mediasize);
1490
gprintln(" sectorsize: %u", pp->sectorsize);
1491
gprintln(" stripesize: %ju", (uintmax_t)pp->stripesize);
1492
gprintln(" stripeoffset: %ju", (uintmax_t)pp->stripeoffset);
1493
gprintln(" access: r%dw%de%d", pp->acr, pp->acw,
1494
pp->ace);
1495
gprintln(" flags: %s (0x%04x)",
1496
provider_flags_to_string(pp, flags, sizeof(flags)),
1497
pp->flags);
1498
gprintln(" error: %d", pp->error);
1499
if (LIST_EMPTY(&pp->consumers))
1500
gprintln(" consumers: none");
1501
} else {
1502
gprintf("provider: %s (%p), access=r%dw%de%d",
1503
pp->name, pp, pp->acr, pp->acw, pp->ace);
1504
if (pp->flags != 0) {
1505
db_printf(", flags=%s (0x%04x)",
1506
provider_flags_to_string(pp, flags, sizeof(flags)),
1507
pp->flags);
1508
}
1509
db_printf("\n");
1510
}
1511
if (!LIST_EMPTY(&pp->consumers)) {
1512
LIST_FOREACH(cp, &pp->consumers, consumers) {
1513
db_show_geom_consumer(indent + 2, cp);
1514
if (db_pager_quit)
1515
break;
1516
}
1517
}
1518
}
1519
1520
static void
1521
db_show_geom_geom(int indent, struct g_geom *gp)
1522
{
1523
struct g_provider *pp;
1524
struct g_consumer *cp;
1525
char flags[64];
1526
1527
if (indent == 0) {
1528
gprintln("geom: %s (%p)", gp->name, gp);
1529
gprintln(" class: %s (%p)", gp->class->name, gp->class);
1530
gprintln(" flags: %s (0x%04x)",
1531
geom_flags_to_string(gp, flags, sizeof(flags)), gp->flags);
1532
gprintln(" rank: %d", gp->rank);
1533
if (LIST_EMPTY(&gp->provider))
1534
gprintln(" providers: none");
1535
if (LIST_EMPTY(&gp->consumer))
1536
gprintln(" consumers: none");
1537
} else {
1538
gprintf("geom: %s (%p), rank=%d", gp->name, gp, gp->rank);
1539
if (gp->flags != 0) {
1540
db_printf(", flags=%s (0x%04x)",
1541
geom_flags_to_string(gp, flags, sizeof(flags)),
1542
gp->flags);
1543
}
1544
db_printf("\n");
1545
}
1546
if (!LIST_EMPTY(&gp->provider)) {
1547
LIST_FOREACH(pp, &gp->provider, provider) {
1548
db_show_geom_provider(indent + 2, pp);
1549
if (db_pager_quit)
1550
break;
1551
}
1552
}
1553
if (!LIST_EMPTY(&gp->consumer)) {
1554
LIST_FOREACH(cp, &gp->consumer, consumer) {
1555
db_show_geom_consumer(indent + 2, cp);
1556
if (db_pager_quit)
1557
break;
1558
}
1559
}
1560
}
1561
1562
static void
1563
db_show_geom_class(struct g_class *mp)
1564
{
1565
struct g_geom *gp;
1566
1567
db_printf("class: %s (%p)\n", mp->name, mp);
1568
LIST_FOREACH(gp, &mp->geom, geom) {
1569
db_show_geom_geom(2, gp);
1570
if (db_pager_quit)
1571
break;
1572
}
1573
}
1574
1575
/*
1576
* Print the GEOM topology or the given object.
1577
*/
1578
DB_SHOW_COMMAND(geom, db_show_geom)
1579
{
1580
struct g_class *mp;
1581
1582
if (!have_addr) {
1583
/* No address given, print the entire topology. */
1584
LIST_FOREACH(mp, &g_classes, class) {
1585
db_show_geom_class(mp);
1586
db_printf("\n");
1587
if (db_pager_quit)
1588
break;
1589
}
1590
} else {
1591
switch (g_valid_obj((void *)addr)) {
1592
case 1:
1593
db_show_geom_class((struct g_class *)addr);
1594
break;
1595
case 2:
1596
db_show_geom_geom(0, (struct g_geom *)addr);
1597
break;
1598
case 3:
1599
db_show_geom_consumer(0, (struct g_consumer *)addr);
1600
break;
1601
case 4:
1602
db_show_geom_provider(0, (struct g_provider *)addr);
1603
break;
1604
default:
1605
db_printf("Not a GEOM object.\n");
1606
break;
1607
}
1608
}
1609
}
1610
1611
static void
1612
db_print_bio_cmd(struct bio *bp)
1613
{
1614
db_printf(" cmd: ");
1615
switch (bp->bio_cmd) {
1616
case BIO_READ: db_printf("BIO_READ"); break;
1617
case BIO_WRITE: db_printf("BIO_WRITE"); break;
1618
case BIO_DELETE: db_printf("BIO_DELETE"); break;
1619
case BIO_GETATTR: db_printf("BIO_GETATTR"); break;
1620
case BIO_FLUSH: db_printf("BIO_FLUSH"); break;
1621
case BIO_CMD0: db_printf("BIO_CMD0"); break;
1622
case BIO_CMD1: db_printf("BIO_CMD1"); break;
1623
case BIO_CMD2: db_printf("BIO_CMD2"); break;
1624
case BIO_ZONE: db_printf("BIO_ZONE"); break;
1625
default: db_printf("UNKNOWN"); break;
1626
}
1627
db_printf("\n");
1628
}
1629
1630
static void
1631
db_print_bio_flags(struct bio *bp)
1632
{
1633
int comma;
1634
1635
comma = 0;
1636
db_printf(" flags: ");
1637
if (bp->bio_flags & BIO_ERROR) {
1638
db_printf("BIO_ERROR");
1639
comma = 1;
1640
}
1641
if (bp->bio_flags & BIO_DONE) {
1642
db_printf("%sBIO_DONE", (comma ? ", " : ""));
1643
comma = 1;
1644
}
1645
if (bp->bio_flags & BIO_ONQUEUE)
1646
db_printf("%sBIO_ONQUEUE", (comma ? ", " : ""));
1647
db_printf("\n");
1648
}
1649
1650
/*
1651
* Print useful information in a BIO
1652
*/
1653
DB_SHOW_COMMAND(bio, db_show_bio)
1654
{
1655
struct bio *bp;
1656
1657
if (have_addr) {
1658
bp = (struct bio *)addr;
1659
db_printf("BIO %p\n", bp);
1660
db_print_bio_cmd(bp);
1661
db_print_bio_flags(bp);
1662
db_printf(" cflags: 0x%hx\n", bp->bio_cflags);
1663
db_printf(" pflags: 0x%hx\n", bp->bio_pflags);
1664
db_printf(" offset: %jd\n", (intmax_t)bp->bio_offset);
1665
db_printf(" length: %jd\n", (intmax_t)bp->bio_length);
1666
db_printf(" bcount: %ld\n", bp->bio_bcount);
1667
db_printf(" resid: %ld\n", bp->bio_resid);
1668
db_printf(" completed: %jd\n", (intmax_t)bp->bio_completed);
1669
db_printf(" children: %u\n", bp->bio_children);
1670
db_printf(" inbed: %u\n", bp->bio_inbed);
1671
db_printf(" error: %d\n", bp->bio_error);
1672
db_printf(" parent: %p\n", bp->bio_parent);
1673
db_printf(" driver1: %p\n", bp->bio_driver1);
1674
db_printf(" driver2: %p\n", bp->bio_driver2);
1675
db_printf(" caller1: %p\n", bp->bio_caller1);
1676
db_printf(" caller2: %p\n", bp->bio_caller2);
1677
db_printf(" bio_from: %p\n", bp->bio_from);
1678
db_printf(" bio_to: %p\n", bp->bio_to);
1679
if ((bp->bio_flags & BIO_EXTERR) != 0)
1680
exterr_db_print(&bp->bio_exterr);
1681
1682
#if defined(BUF_TRACKING) || defined(FULL_BUF_TRACKING)
1683
db_printf(" bio_track_bp: %p\n", bp->bio_track_bp);
1684
#endif
1685
}
1686
}
1687
1688
#undef gprintf
1689
#undef gprintln
1690
#undef ADDFLAG
1691
1692
#endif /* DDB */
1693
1694