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 --- |