Deleted Added
full compact
geom_vinum_drive.c (143259) geom_vinum_drive.c (146325)
1/*-
2 * Copyright (c) 2004, 2005 Lukas Ertl
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 11 unchanged lines hidden (view full) ---

20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 2004, 2005 Lukas Ertl
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 11 unchanged lines hidden (view full) ---

20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27#include <sys/cdefs.h>
28__FBSDID("$FreeBSD: head/sys/geom/vinum/geom_vinum_drive.c 143259 2005-03-07 19:58:58Z le $");
28__FBSDID("$FreeBSD: head/sys/geom/vinum/geom_vinum_drive.c 146325 2005-05-17 16:38:30Z le $");
29
30#include <sys/param.h>
31#include <sys/bio.h>
32#include <sys/errno.h>
33#include <sys/conf.h>
34#include <sys/kernel.h>
35#include <sys/kthread.h>
36#include <sys/libkern.h>

--- 5 unchanged lines hidden (view full) ---

42#include <sys/systm.h>
43#include <sys/time.h>
44
45#include <geom/geom.h>
46#include <geom/vinum/geom_vinum_var.h>
47#include <geom/vinum/geom_vinum.h>
48#include <geom/vinum/geom_vinum_share.h>
49
29
30#include <sys/param.h>
31#include <sys/bio.h>
32#include <sys/errno.h>
33#include <sys/conf.h>
34#include <sys/kernel.h>
35#include <sys/kthread.h>
36#include <sys/libkern.h>

--- 5 unchanged lines hidden (view full) ---

42#include <sys/systm.h>
43#include <sys/time.h>
44
45#include <geom/geom.h>
46#include <geom/vinum/geom_vinum_var.h>
47#include <geom/vinum/geom_vinum.h>
48#include <geom/vinum/geom_vinum_share.h>
49
50static void gv_drive_dead(void *, int);
50static void gv_drive_worker(void *);
51void gv_drive_modify(struct gv_drive *);
52
53void
54gv_config_new_drive(struct gv_drive *d)
55{
56 struct gv_hdr *vhdr;
57 struct gv_freelist *fl;

--- 49 unchanged lines hidden (view full) ---

107 struct sbuf *sb;
108 int error;
109
110 g_topology_assert();
111
112 KASSERT(d != NULL, ("gv_save_config: null d"));
113 KASSERT(sc != NULL, ("gv_save_config: null sc"));
114
51static void gv_drive_worker(void *);
52void gv_drive_modify(struct gv_drive *);
53
54void
55gv_config_new_drive(struct gv_drive *d)
56{
57 struct gv_hdr *vhdr;
58 struct gv_freelist *fl;

--- 49 unchanged lines hidden (view full) ---

108 struct sbuf *sb;
109 int error;
110
111 g_topology_assert();
112
113 KASSERT(d != NULL, ("gv_save_config: null d"));
114 KASSERT(sc != NULL, ("gv_save_config: null sc"));
115
116 if (d->state != GV_DRIVE_UP)
117 return;
118
115 if (cp == NULL) {
116 gp = d->geom;
117 KASSERT(gp != NULL, ("gv_save_config: null gp"));
118 cp2 = LIST_FIRST(&gp->consumer);
119 KASSERT(cp2 != NULL, ("gv_save_config: null cp2"));
120 } else
121 cp2 = cp;
122
123 vhdr = g_malloc(GV_HDR_LEN, M_WAITOK | M_ZERO);
124 vhdr->magic = GV_MAGIC;
125 vhdr->config_length = GV_CFG_LEN;
126
127 hdr = d->hdr;
128 if (hdr == NULL) {
119 if (cp == NULL) {
120 gp = d->geom;
121 KASSERT(gp != NULL, ("gv_save_config: null gp"));
122 cp2 = LIST_FIRST(&gp->consumer);
123 KASSERT(cp2 != NULL, ("gv_save_config: null cp2"));
124 } else
125 cp2 = cp;
126
127 vhdr = g_malloc(GV_HDR_LEN, M_WAITOK | M_ZERO);
128 vhdr->magic = GV_MAGIC;
129 vhdr->config_length = GV_CFG_LEN;
130
131 hdr = d->hdr;
132 if (hdr == NULL) {
129 printf("NULL hdr!!!\n");
133 printf("GEOM_VINUM: drive %s has NULL hdr\n", d->name);
130 g_free(vhdr);
131 return;
132 }
133 microtime(&hdr->label.last_update);
134 bcopy(&hdr->label, &vhdr->label, sizeof(struct gv_label));
135
136 sb = sbuf_new(NULL, NULL, GV_CFG_LEN, SBUF_FIXEDLEN);
137 gv_format_config(sc, sb, 1, NULL);
138 sbuf_finish(sb);
139
140 error = g_access(cp2, 0, 1, 0);
141 if (error) {
134 g_free(vhdr);
135 return;
136 }
137 microtime(&hdr->label.last_update);
138 bcopy(&hdr->label, &vhdr->label, sizeof(struct gv_label));
139
140 sb = sbuf_new(NULL, NULL, GV_CFG_LEN, SBUF_FIXEDLEN);
141 gv_format_config(sc, sb, 1, NULL);
142 sbuf_finish(sb);
143
144 error = g_access(cp2, 0, 1, 0);
145 if (error) {
142 printf("g_access failed: %d\n", error);
146 printf("GEOM_VINUM: g_access failed on drive %s, errno %d\n",
147 d->name, error);
143 sbuf_delete(sb);
148 sbuf_delete(sb);
149 g_free(vhdr);
144 return;
145 }
146 g_topology_unlock();
147
148 do {
149 error = g_write_data(cp2, GV_HDR_OFFSET, vhdr, GV_HDR_LEN);
150 if (error) {
150 return;
151 }
152 g_topology_unlock();
153
154 do {
155 error = g_write_data(cp2, GV_HDR_OFFSET, vhdr, GV_HDR_LEN);
156 if (error) {
151 printf("writing vhdr failed: %d", error);
157 printf("GEOM_VINUM: writing vhdr failed on drive %s, "
158 "errno %d", d->name, error);
152 break;
153 }
154
155 error = g_write_data(cp2, GV_CFG_OFFSET, sbuf_data(sb),
156 GV_CFG_LEN);
157 if (error) {
159 break;
160 }
161
162 error = g_write_data(cp2, GV_CFG_OFFSET, sbuf_data(sb),
163 GV_CFG_LEN);
164 if (error) {
158 printf("writing first config copy failed: %d", error);
165 printf("GEOM_VINUM: writing first config copy failed "
166 "on drive %s, errno %d", d->name, error);
159 break;
160 }
161
162 error = g_write_data(cp2, GV_CFG_OFFSET + GV_CFG_LEN,
163 sbuf_data(sb), GV_CFG_LEN);
164 if (error)
167 break;
168 }
169
170 error = g_write_data(cp2, GV_CFG_OFFSET + GV_CFG_LEN,
171 sbuf_data(sb), GV_CFG_LEN);
172 if (error)
165 printf("writing second config copy failed: %d", error);
173 printf("GEOM_VINUM: writing second config copy failed "
174 "on drive %s, errno %d", d->name, error);
166 } while (0);
167
168 g_topology_lock();
169 g_access(cp2, 0, -1, 0);
170 sbuf_delete(sb);
171 g_free(vhdr);
172
173 if (d->geom != NULL)

--- 12 unchanged lines hidden (view full) ---

186 int error;
187
188 gp = pp->geom;
189 cp = LIST_FIRST(&gp->consumer);
190 if (cp == NULL)
191 return (0);
192
193 d = gp->softc;
175 } while (0);
176
177 g_topology_lock();
178 g_access(cp2, 0, -1, 0);
179 sbuf_delete(sb);
180 g_free(vhdr);
181
182 if (d->geom != NULL)

--- 12 unchanged lines hidden (view full) ---

195 int error;
196
197 gp = pp->geom;
198 cp = LIST_FIRST(&gp->consumer);
199 if (cp == NULL)
200 return (0);
201
202 d = gp->softc;
203 if (d == NULL)
204 return (0);
194
195 s = pp->private;
196 KASSERT(s != NULL, ("gv_drive_access: NULL s"));
197
198 LIST_FOREACH(s2, &d->subdisks, from_drive) {
199 if (s == s2)
200 continue;
201 if (s->drive_offset + s->size <= s2->drive_offset)
202 continue;
203 if (s2->drive_offset + s2->size <= s->drive_offset)
204 continue;
205
206 /* Overlap. */
207 pp2 = s2->provider;
208 KASSERT(s2 != NULL, ("gv_drive_access: NULL s2"));
205
206 s = pp->private;
207 KASSERT(s != NULL, ("gv_drive_access: NULL s"));
208
209 LIST_FOREACH(s2, &d->subdisks, from_drive) {
210 if (s == s2)
211 continue;
212 if (s->drive_offset + s->size <= s2->drive_offset)
213 continue;
214 if (s2->drive_offset + s2->size <= s->drive_offset)
215 continue;
216
217 /* Overlap. */
218 pp2 = s2->provider;
219 KASSERT(s2 != NULL, ("gv_drive_access: NULL s2"));
209 if ((pp->acw + dw) > 0 && pp2->ace > 0) {
210 printf("FOOO: permission denied - e\n");
220 if ((pp->acw + dw) > 0 && pp2->ace > 0)
211 return (EPERM);
221 return (EPERM);
212 }
213 if ((pp->ace + de) > 0 && pp2->acw > 0) {
214 printf("FOOO: permission denied - w\n");
222 if ((pp->ace + de) > 0 && pp2->acw > 0)
215 return (EPERM);
223 return (EPERM);
216 }
217 }
218
224 }
225
219#if 0
220 /* On first open, grab an extra "exclusive" bit */
221 if (cp->acr == 0 && cp->acw == 0 && cp->ace == 0)
222 de++;
223 /* ... and let go of it on last close */
224 if ((cp->acr + dr) == 0 && (cp->acw + dw) == 0 && (cp->ace + de) == 1)
225 de--;
226#endif
227 error = g_access(cp, dr, dw, de);
226 error = g_access(cp, dr, dw, de);
228 if (error) {
229 printf("FOOO: g_access failed: %d\n", error);
230 }
231 return (error);
232}
233
234static void
235gv_drive_done(struct bio *bp)
236{
237 struct gv_drive *d;
238 struct gv_bioq *bq;

--- 89 unchanged lines hidden (view full) ---

328 /* Deliver the original request. */
329 g_std_done(bp);
330
331 /* The request had an error, we need to clean up. */
332 if (error != 0) {
333 g_topology_lock();
334 gv_set_drive_state(d, GV_DRIVE_DOWN,
335 GV_SETSTATE_FORCE | GV_SETSTATE_CONFIG);
227 return (error);
228}
229
230static void
231gv_drive_done(struct bio *bp)
232{
233 struct gv_drive *d;
234 struct gv_bioq *bq;

--- 89 unchanged lines hidden (view full) ---

324 /* Deliver the original request. */
325 g_std_done(bp);
326
327 /* The request had an error, we need to clean up. */
328 if (error != 0) {
329 g_topology_lock();
330 gv_set_drive_state(d, GV_DRIVE_DOWN,
331 GV_SETSTATE_FORCE | GV_SETSTATE_CONFIG);
336 g_wither_geom(d->geom, ENXIO);
337 g_topology_unlock();
332 g_topology_unlock();
333 g_post_event(gv_drive_dead, d, M_WAITOK, d,
334 NULL);
338 }
339
340 /* New request, needs to be sent downwards. */
341 } else {
342 s = pp->private;
343
344 if ((s->state == GV_SD_DOWN) ||
345 (s->state == GV_SD_STALE)) {

--- 42 unchanged lines hidden (view full) ---

388}
389
390
391static void
392gv_drive_orphan(struct g_consumer *cp)
393{
394 struct g_geom *gp;
395 struct gv_drive *d;
335 }
336
337 /* New request, needs to be sent downwards. */
338 } else {
339 s = pp->private;
340
341 if ((s->state == GV_SD_DOWN) ||
342 (s->state == GV_SD_STALE)) {

--- 42 unchanged lines hidden (view full) ---

385}
386
387
388static void
389gv_drive_orphan(struct g_consumer *cp)
390{
391 struct g_geom *gp;
392 struct gv_drive *d;
396 struct gv_sd *s;
397 int error;
398
399 g_topology_assert();
400 gp = cp->geom;
401 g_trace(G_T_TOPOLOGY, "gv_drive_orphan(%s)", gp->name);
393
394 g_topology_assert();
395 gp = cp->geom;
396 g_trace(G_T_TOPOLOGY, "gv_drive_orphan(%s)", gp->name);
402 if (cp->acr != 0 || cp->acw != 0 || cp->ace != 0)
403 g_access(cp, -cp->acr, -cp->acw, -cp->ace);
404 error = cp->provider->error;
405 if (error == 0)
406 error = ENXIO;
407 g_detach(cp);
408 g_destroy_consumer(cp);
409 if (!LIST_EMPTY(&gp->consumer))
410 return;
411 d = gp->softc;
412 if (d != NULL) {
397 d = gp->softc;
398 if (d != NULL) {
413 printf("gvinum: lost drive '%s'\n", d->name);
414 d->geom = NULL;
415 LIST_FOREACH(s, &d->subdisks, from_drive) {
416 s->provider = NULL;
417 s->consumer = NULL;
418 }
419 gv_kill_drive_thread(d);
420 gv_set_drive_state(d, GV_DRIVE_DOWN,
421 GV_SETSTATE_FORCE | GV_SETSTATE_CONFIG);
399 gv_set_drive_state(d, GV_DRIVE_DOWN,
400 GV_SETSTATE_FORCE | GV_SETSTATE_CONFIG);
422 }
423 gp->softc = NULL;
424 g_wither_geom(gp, error);
401 g_post_event(gv_drive_dead, d, M_WAITOK, d, NULL);
402 } else
403 g_wither_geom(gp, ENXIO);
425}
426
427static struct g_geom *
428gv_drive_taste(struct g_class *mp, struct g_provider *pp, int flags __unused)
429{
430 struct g_geom *gp, *gp2;
431 struct g_consumer *cp;
432 struct gv_drive *d;

--- 155 unchanged lines hidden (view full) ---

588 */
589void
590gv_drive_modify(struct gv_drive *d)
591{
592 struct g_geom *gp;
593 struct g_consumer *cp;
594 struct g_provider *pp, *pp2;
595 struct gv_sd *s;
404}
405
406static struct g_geom *
407gv_drive_taste(struct g_class *mp, struct g_provider *pp, int flags __unused)
408{
409 struct g_geom *gp, *gp2;
410 struct g_consumer *cp;
411 struct gv_drive *d;

--- 155 unchanged lines hidden (view full) ---

567 */
568void
569gv_drive_modify(struct gv_drive *d)
570{
571 struct g_geom *gp;
572 struct g_consumer *cp;
573 struct g_provider *pp, *pp2;
574 struct gv_sd *s;
596 int nsd;
597
598 KASSERT(d != NULL, ("gv_drive_modify: null d"));
599 gp = d->geom;
600 KASSERT(gp != NULL, ("gv_drive_modify: null gp"));
601 cp = LIST_FIRST(&gp->consumer);
602 KASSERT(cp != NULL, ("gv_drive_modify: null cp"));
603 pp = cp->provider;
604 KASSERT(pp != NULL, ("gv_drive_modify: null pp"));
605
606 g_topology_assert();
607
575
576 KASSERT(d != NULL, ("gv_drive_modify: null d"));
577 gp = d->geom;
578 KASSERT(gp != NULL, ("gv_drive_modify: null gp"));
579 cp = LIST_FIRST(&gp->consumer);
580 KASSERT(cp != NULL, ("gv_drive_modify: null cp"));
581 pp = cp->provider;
582 KASSERT(pp != NULL, ("gv_drive_modify: null pp"));
583
584 g_topology_assert();
585
608 nsd = 0;
609 LIST_FOREACH(s, &d->subdisks, from_drive) {
610 /* This subdisk already has a provider. */
611 if (s->provider != NULL)
612 continue;
613 pp2 = g_new_providerf(gp, "gvinum/sd/%s", s->name);
614 pp2->mediasize = s->size;
615 pp2->sectorsize = pp->sectorsize;
616 g_error_provider(pp2, 0);
617 s->provider = pp2;
618 pp2->private = s;
619 }
620}
621
586 LIST_FOREACH(s, &d->subdisks, from_drive) {
587 /* This subdisk already has a provider. */
588 if (s->provider != NULL)
589 continue;
590 pp2 = g_new_providerf(gp, "gvinum/sd/%s", s->name);
591 pp2->mediasize = s->size;
592 pp2->sectorsize = pp->sectorsize;
593 g_error_provider(pp2, 0);
594 s->provider = pp2;
595 pp2->private = s;
596 }
597}
598
599static void
600gv_drive_dead(void *arg, int flag)
601{
602 struct g_geom *gp;
603 struct g_consumer *cp;
604 struct gv_drive *d;
605 struct gv_sd *s;
606
607 g_topology_assert();
608 KASSERT(arg != NULL, ("gv_drive_dead: NULL arg"));
609
610 if (flag == EV_CANCEL)
611 return;
612
613 d = arg;
614 if (d->state != GV_DRIVE_DOWN)
615 return;
616
617 g_trace(G_T_TOPOLOGY, "gv_drive_dead(%s)", d->name);
618
619 gp = d->geom;
620 if (gp == NULL)
621 return;
622
623 LIST_FOREACH(cp, &gp->consumer, consumer) {
624 if (cp->nstart != cp->nend) {
625 printf("GEOM_VINUM: dead drive '%s' has still "
626 "active requests, can't detach consumer\n",
627 d->name);
628 g_post_event(gv_drive_dead, d, M_WAITOK, d,
629 NULL);
630 return;
631 }
632 if (cp->acr != 0 || cp->acw != 0 || cp->ace != 0)
633 g_access(cp, -cp->acr, -cp->acw, -cp->ace);
634 }
635
636 printf("GEOM_VINUM: lost drive '%s'\n", d->name);
637 d->geom = NULL;
638 LIST_FOREACH(s, &d->subdisks, from_drive) {
639 s->provider = NULL;
640 s->consumer = NULL;
641 }
642 gv_kill_drive_thread(d);
643 gp->softc = NULL;
644 g_wither_geom(gp, ENXIO);
645}
646
622static int
623gv_drive_destroy_geom(struct gctl_req *req, struct g_class *mp,
624 struct g_geom *gp)
625{
626 struct gv_drive *d;
627
628 g_trace(G_T_TOPOLOGY, "gv_drive_destroy_geom: %s", gp->name);
629 g_topology_assert();

--- 18 unchanged lines hidden ---
647static int
648gv_drive_destroy_geom(struct gctl_req *req, struct g_class *mp,
649 struct g_geom *gp)
650{
651 struct gv_drive *d;
652
653 g_trace(G_T_TOPOLOGY, "gv_drive_destroy_geom: %s", gp->name);
654 g_topology_assert();

--- 18 unchanged lines hidden ---