Deleted Added
full compact
geom_slice.c (113712) geom_slice.c (113713)
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

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

27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
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 *
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

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

27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
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 * $FreeBSD: head/sys/geom/geom_slice.c 113712 2003-04-19 10:00:22Z phk $
35 * $FreeBSD: head/sys/geom/geom_slice.c 113713 2003-04-19 10:14:39Z phk $
36 */
37
38
39#include <sys/param.h>
40#include <sys/systm.h>
41#include <sys/kernel.h>
42#include <sys/malloc.h>
43#include <sys/bio.h>

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

107 de++;
108 /* ... and let go of it on last close */
109 if ((cp->acr + dr) == 0 && (cp->acw + dw) == 0 && (cp->ace + de) == 1)
110 de--;
111 error = g_access_rel(cp, dr, dw, de);
112 return (error);
113}
114
36 */
37
38
39#include <sys/param.h>
40#include <sys/systm.h>
41#include <sys/kernel.h>
42#include <sys/malloc.h>
43#include <sys/bio.h>

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

107 de++;
108 /* ... and let go of it on last close */
109 if ((cp->acr + dr) == 0 && (cp->acw + dw) == 0 && (cp->ace + de) == 1)
110 de--;
111 error = g_access_rel(cp, dr, dw, de);
112 return (error);
113}
114
115/*
116 * XXX: It should be possible to specify here if we should finish all of the
117 * XXX: bio, or only the non-hot bits. This would get messy if there were
118 * XXX: two hot spots in the same bio, so for now we simply finish off the
119 * XXX: entire bio. Modifying hot data on the way to disk is frowned on
120 * XXX: so making that considerably harder is not a bad idea anyway.
121 */
115void
116g_slice_finish_hot(struct bio *bp)
117{
118 struct bio *bp2;
119 struct g_geom *gp;
120 struct g_consumer *cp;
121 struct g_slicer *gsp;
122 struct g_slice *gsl;
123 int idx;
124
122void
123g_slice_finish_hot(struct bio *bp)
124{
125 struct bio *bp2;
126 struct g_geom *gp;
127 struct g_consumer *cp;
128 struct g_slicer *gsp;
129 struct g_slice *gsl;
130 int idx;
131
125 KASSERT(bp->bio_to != NULL, ("NULL bio_to in g_slice_finish_hot(%p)", bp));
126 KASSERT(bp->bio_from != NULL, ("NULL bio_from in g_slice_finish_hot(%p)", bp));
132 KASSERT(bp->bio_to != NULL,
133 ("NULL bio_to in g_slice_finish_hot(%p)", bp));
134 KASSERT(bp->bio_from != NULL,
135 ("NULL bio_from in g_slice_finish_hot(%p)", bp));
127 gp = bp->bio_to->geom;
128 gsp = gp->softc;
129 cp = LIST_FIRST(&gp->consumer);
130 KASSERT(cp != NULL, ("NULL consumer in g_slice_finish_hot(%p)", bp));
131 idx = bp->bio_to->index;
132 gsl = &gsp->slices[idx];
133
134 bp2 = g_clone_bio(bp);

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

148g_slice_start(struct bio *bp)
149{
150 struct bio *bp2;
151 struct g_provider *pp;
152 struct g_geom *gp;
153 struct g_consumer *cp;
154 struct g_slicer *gsp;
155 struct g_slice *gsl;
136 gp = bp->bio_to->geom;
137 gsp = gp->softc;
138 cp = LIST_FIRST(&gp->consumer);
139 KASSERT(cp != NULL, ("NULL consumer in g_slice_finish_hot(%p)", bp));
140 idx = bp->bio_to->index;
141 gsl = &gsp->slices[idx];
142
143 bp2 = g_clone_bio(bp);

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

157g_slice_start(struct bio *bp)
158{
159 struct bio *bp2;
160 struct g_provider *pp;
161 struct g_geom *gp;
162 struct g_consumer *cp;
163 struct g_slicer *gsp;
164 struct g_slice *gsl;
156 struct g_slice_hot *gmp;
165 struct g_slice_hot *ghp;
157 int idx, error;
158 u_int m_index;
159 off_t t;
160
161 pp = bp->bio_to;
162 gp = pp->geom;
163 gsp = gp->softc;
164 cp = LIST_FIRST(&gp->consumer);

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

172 g_io_deliver(bp, EINVAL); /* XXX: EWHAT ? */
173 return;
174 }
175 /*
176 * Check if we collide with any hot spaces, and call the
177 * method once if so.
178 */
179 t = bp->bio_offset + gsl->offset;
166 int idx, error;
167 u_int m_index;
168 off_t t;
169
170 pp = bp->bio_to;
171 gp = pp->geom;
172 gsp = gp->softc;
173 cp = LIST_FIRST(&gp->consumer);

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

181 g_io_deliver(bp, EINVAL); /* XXX: EWHAT ? */
182 return;
183 }
184 /*
185 * Check if we collide with any hot spaces, and call the
186 * method once if so.
187 */
188 t = bp->bio_offset + gsl->offset;
180 /* .ctl devices may take us negative */
181 if (t < 0 || (t + bp->bio_length) < 0) {
182 g_io_deliver(bp, EINVAL);
183 return;
184 }
185 for (m_index = 0; m_index < gsp->nhotspot; m_index++) {
189 for (m_index = 0; m_index < gsp->nhotspot; m_index++) {
186 gmp = &gsp->hotspot[m_index];
187 if (t >= gmp->offset + gmp->length)
190 ghp = &gsp->hotspot[m_index];
191 if (t >= ghp->offset + ghp->length)
188 continue;
192 continue;
189 if (t + bp->bio_length <= gmp->offset)
193 if (t + bp->bio_length <= ghp->offset)
190 continue;
194 continue;
191 error = gsp->start(bp);
192 if (error == EJUSTRETURN)
195 switch(bp->bio_cmd) {
196 case BIO_READ: idx = ghp->ract; break;
197 case BIO_WRITE: idx = ghp->wact; break;
198 case BIO_DELETE: idx = ghp->dact; break;
199 }
200 switch(idx) {
201 case G_SLICE_HOT_ALLOW:
202 /* Fall out and continue normal processing */
203 continue;
204 case G_SLICE_HOT_DENY:
205 g_io_deliver(bp, EROFS);
193 return;
206 return;
194 else if (error) {
195 g_io_deliver(bp, error);
207 case G_SLICE_HOT_START:
208 error = gsp->start(bp);
209 if (error && error != EJUSTRETURN)
210 g_io_deliver(bp, error);
196 return;
211 return;
212 case G_SLICE_HOT_CALL:
213 error = g_call_me(gsp->hot, bp, gp, NULL);
214 if (error)
215 g_io_deliver(bp, error);
216 return;
197 }
198 break;
199 }
200 bp2 = g_clone_bio(bp);
201 if (bp2 == NULL) {
202 g_io_deliver(bp, ENOMEM);
203 return;
204 }

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

333 pp->sectorsize = gsl->sectorsize;
334 gsl->provider = pp;
335 gsp->nprovider++;
336 g_error_provider(pp, 0);
337 sbuf_delete(sb);
338 return(0);
339}
340
217 }
218 break;
219 }
220 bp2 = g_clone_bio(bp);
221 if (bp2 == NULL) {
222 g_io_deliver(bp, ENOMEM);
223 return;
224 }

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

353 pp->sectorsize = gsl->sectorsize;
354 gsl->provider = pp;
355 gsp->nprovider++;
356 g_error_provider(pp, 0);
357 sbuf_delete(sb);
358 return(0);
359}
360
361/*
362 * Configure "hotspots". A hotspot is a piece of the parent device which
363 * this particular slicer cares about for some reason. Typically because
364 * it contains meta-data used to configure the slicer.
365 * A hotspot is identified by its index number. The offset and length are
366 * relative to the parent device, and the three "?act" fields specify
367 * what action to take on BIO_READ, BIO_DELETE and BIO_WRITE.
368 *
369 * XXX: There may be a race relative to g_slice_start() here, if an existing
370 * XXX: hotspot is changed wile I/O is happening. Should this become a problem
371 * XXX: we can protect the hotspot stuff with a mutex.
372 */
373
341int
374int
342g_slice_conf_hot(struct g_geom *gp, u_int idx, off_t offset, off_t length)
375g_slice_conf_hot(struct g_geom *gp, u_int idx, off_t offset, off_t length, int ract, int dact, int wact)
343{
344 struct g_slicer *gsp;
345 struct g_slice_hot *gsl, *gsl2;
346
376{
377 struct g_slicer *gsp;
378 struct g_slice_hot *gsl, *gsl2;
379
347 g_trace(G_T_TOPOLOGY, "g_slice_conf_hot()");
380 g_trace(G_T_TOPOLOGY, "g_slice_conf_hot(%s, idx: %d, off: %jd, len: %jd)",
381 gp->name, idx, (intmax_t)offset, (intmax_t)length);
348 g_topology_assert();
349 gsp = gp->softc;
350 gsl = gsp->hotspot;
351 if(idx >= gsp->nhotspot) {
352 gsl2 = g_malloc((idx + 1) * sizeof *gsl2, M_WAITOK | M_ZERO);
353 if (gsp->hotspot != NULL)
354 bcopy(gsp->hotspot, gsl2, gsp->nhotspot * sizeof *gsl2);
355 gsp->hotspot = gsl2;
356 if (gsp->hotspot != NULL)
357 g_free(gsl);
358 gsl = gsl2;
359 gsp->nhotspot = idx + 1;
360 }
382 g_topology_assert();
383 gsp = gp->softc;
384 gsl = gsp->hotspot;
385 if(idx >= gsp->nhotspot) {
386 gsl2 = g_malloc((idx + 1) * sizeof *gsl2, M_WAITOK | M_ZERO);
387 if (gsp->hotspot != NULL)
388 bcopy(gsp->hotspot, gsl2, gsp->nhotspot * sizeof *gsl2);
389 gsp->hotspot = gsl2;
390 if (gsp->hotspot != NULL)
391 g_free(gsl);
392 gsl = gsl2;
393 gsp->nhotspot = idx + 1;
394 }
361 if (bootverbose)
362 printf("GEOM: Add %s hot[%d] start %jd length %jd end %jd\n",
363 gp->name, idx, (intmax_t)offset, (intmax_t)length,
364 (intmax_t)(offset + length - 1));
365 gsl[idx].offset = offset;
366 gsl[idx].length = length;
395 gsl[idx].offset = offset;
396 gsl[idx].length = length;
397 gsl[idx].ract = ract;
398 gsl[idx].dact = dact;
399 gsl[idx].wact = wact;
367 return (0);
368}
369
370struct g_geom *
371g_slice_new(struct g_class *mp, u_int slices, struct g_provider *pp, struct g_consumer **cpp, void *extrap, int extra, g_slice_start_t *start)
372{
373 struct g_geom *gp;
374 struct g_slicer *gsp;

--- 53 unchanged lines hidden ---
400 return (0);
401}
402
403struct g_geom *
404g_slice_new(struct g_class *mp, u_int slices, struct g_provider *pp, struct g_consumer **cpp, void *extrap, int extra, g_slice_start_t *start)
405{
406 struct g_geom *gp;
407 struct g_slicer *gsp;

--- 53 unchanged lines hidden ---