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 107953 2002-12-16 22:33:27Z phk $ |
36 */ 37 38 39#include <sys/param.h> 40#include <sys/stdint.h> 41#ifndef _KERNEL 42#include <stdio.h> 43#include <unistd.h> --- 33 unchanged lines hidden (view full) --- 77 M_WAITOK | M_ZERO); 78 gsp->nslice = nslice; 79 return (gsp); 80} 81 82static int 83g_slice_access(struct g_provider *pp, int dr, int dw, int de) 84{ |
85 int error; 86 u_int u; |
87 struct g_geom *gp; 88 struct g_consumer *cp; 89 struct g_provider *pp2; 90 struct g_slicer *gsp; 91 struct g_slice *gsl, *gsl2; 92 93 gp = pp->geom; 94 cp = LIST_FIRST(&gp->consumer); 95 KASSERT (cp != NULL, ("g_slice_access but no consumer")); 96 gsp = gp->softc; 97 gsl = &gsp->slices[pp->index]; |
98 for (u = 0; u < gsp->nslice; u++) { 99 gsl2 = &gsp->slices[u]; |
100 if (gsl2->length == 0) 101 continue; |
102 if (u == pp->index) |
103 continue; 104 if (gsl->offset + gsl->length <= gsl2->offset) 105 continue; 106 if (gsl2->offset + gsl2->length <= gsl->offset) 107 continue; 108 /* overlap */ 109 pp2 = gsl2->provider; 110 if ((pp->acw + dw) > 0 && pp2->ace > 0) --- 14 unchanged lines hidden (view full) --- 125void 126g_slice_finish_hot(struct bio *bp) 127{ 128 struct bio *bp2; 129 struct g_geom *gp; 130 struct g_consumer *cp; 131 struct g_slicer *gsp; 132 struct g_slice *gsl; |
133 int idx; |
134 135 KASSERT(bp->bio_to != NULL, ("NULL bio_to in g_slice_finish_hot(%p)", bp)); 136 KASSERT(bp->bio_from != NULL, ("NULL bio_from in g_slice_finish_hot(%p)", bp)); 137 gp = bp->bio_to->geom; 138 gsp = gp->softc; 139 cp = LIST_FIRST(&gp->consumer); 140 KASSERT(cp != NULL, ("NULL consumer in g_slice_finish_hot(%p)", bp)); |
141 idx = bp->bio_to->index; 142 gsl = &gsp->slices[idx]; |
143 144 bp2 = g_clone_bio(bp); 145 if (bp2 == NULL) { 146 g_io_deliver(bp, ENOMEM); 147 return; 148 } 149 if (bp2->bio_offset + bp2->bio_length > gsl->length) 150 bp2->bio_length = gsl->length - bp2->bio_offset; --- 7 unchanged lines hidden (view full) --- 158g_slice_start(struct bio *bp) 159{ 160 struct bio *bp2; 161 struct g_provider *pp; 162 struct g_geom *gp; 163 struct g_consumer *cp; 164 struct g_slicer *gsp; 165 struct g_slice *gsl, *gmp; |
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); |
174 idx = pp->index; 175 gsl = &gsp->slices[idx]; |
176 switch(bp->bio_cmd) { 177 case BIO_READ: 178 case BIO_WRITE: 179 case BIO_DELETE: 180 if (bp->bio_offset > gsl->length) { 181 g_io_deliver(bp, EINVAL); /* XXX: EWHAT ? */ 182 return; 183 } --- 45 unchanged lines hidden (view full) --- 229 g_handleattr_off_t(bp, "GEOM::frontstuff", t); 230 return; 231 } 232#ifdef _KERNEL 233 if (!strcmp("GEOM::kerneldump", bp->bio_attribute)) { 234 struct g_kerneldump *gkd; 235 236 gkd = (struct g_kerneldump *)bp->bio_data; |
237 gkd->offset += gsp->slices[idx].offset; 238 if (gkd->length > gsp->slices[idx].length) 239 gkd->length = gsp->slices[idx].length; |
240 /* now, pass it on downwards... */ 241 } 242#endif 243 bp2 = g_clone_bio(bp); 244 if (bp2 == NULL) { 245 g_io_deliver(bp, ENOMEM); 246 return; 247 } 248 bp2->bio_done = g_std_done; 249 g_io_request(bp2, cp); 250 break; 251 default: 252 g_io_deliver(bp, EOPNOTSUPP); 253 return; 254 } 255} 256 257void |
258g_slice_dumpconf(struct sbuf *sb, const char *indent, struct g_geom *gp, struct g_consumer *cp, struct g_provider *pp) |
259{ 260 struct g_slicer *gsp; 261 262 gsp = gp->softc; 263 if (indent == NULL) { 264 sbuf_printf(sb, " i %u", pp->index); 265 sbuf_printf(sb, " o %ju", 266 (uintmax_t)gsp->slices[pp->index].offset); --- 12 unchanged lines hidden (view full) --- 279 sbuf_printf(sb, "%s<offset>%ju</offset>\n", indent, 280 (uintmax_t)gsp->slices[pp->index].offset); 281 sbuf_printf(sb, "%s<secoffset>%ju</secoffset>\n", indent, 282 (uintmax_t)gsp->slices[pp->index].offset / 512); 283 } 284} 285 286int |
287g_slice_config(struct g_geom *gp, u_int idx, int how, off_t offset, off_t length, u_int sectorsize, const char *fmt, ...) |
288{ 289 struct g_provider *pp; 290 struct g_slicer *gsp; 291 struct g_slice *gsl; 292 va_list ap; 293 struct sbuf *sb; 294 int error, acc; 295 296 g_trace(G_T_TOPOLOGY, "g_slice_config(%s, %d, %d)", |
297 gp->name, idx, how); |
298 g_topology_assert(); 299 gsp = gp->softc; 300 error = 0; |
301 if (idx >= gsp->nslice) |
302 return(EINVAL); |
303 gsl = &gsp->slices[idx]; |
304 pp = gsl->provider; 305 if (pp != NULL) 306 acc = pp->acr + pp->acw + pp->ace; 307 else 308 acc = 0; 309 if (acc != 0 && how != G_SLICE_CONFIG_FORCE) { 310 if (length < gsl->length) 311 return(EBUSY); --- 28 unchanged lines hidden (view full) --- 340 sb = sbuf_new(NULL, NULL, 0, SBUF_AUTOEXTEND); 341 sbuf_vprintf(sb, fmt, ap); 342 sbuf_finish(sb); 343 pp = g_new_providerf(gp, sbuf_data(sb)); 344 if (bootverbose) 345 printf("GEOM: Configure %s, start %jd length %jd end %jd\n", 346 pp->name, (intmax_t)offset, (intmax_t)length, 347 (intmax_t)(offset + length - 1)); |
348 pp->index = idx; |
349 pp->mediasize = gsl->length; 350 pp->sectorsize = gsl->sectorsize; 351 gsl->provider = pp; 352 gsp->nprovider++; 353 g_error_provider(pp, 0); 354 sbuf_delete(sb); 355 return(0); 356} 357 358int |
359g_slice_conf_hot(struct g_geom *gp, u_int idx, off_t offset, off_t length) |
360{ 361 struct g_slicer *gsp; 362 struct g_slice *gsl, *gsl2; 363 364 g_trace(G_T_TOPOLOGY, "g_slice_conf_hot()"); 365 g_topology_assert(); 366 gsp = gp->softc; 367 gsl = gsp->hot; |
368 if(idx >= gsp->nhot) { 369 gsl2 = g_malloc((idx + 1) * sizeof *gsl2, M_WAITOK | M_ZERO); |
370 if (gsp->hot != NULL) 371 bcopy(gsp->hot, gsl2, gsp->nhot * sizeof *gsl2); 372 gsp->hot = gsl2; 373 if (gsp->hot != NULL) 374 g_free(gsl); 375 gsl = gsl2; |
376 gsp->nhot = idx + 1; |
377 } 378 if (bootverbose) 379 printf("GEOM: Add %s hot[%d] start %jd length %jd end %jd\n", |
380 gp->name, idx, (intmax_t)offset, (intmax_t)length, |
381 (intmax_t)(offset + length - 1)); |
382 gsl[idx].offset = offset; 383 gsl[idx].length = length; |
384 return (0); 385} 386 387struct g_provider * |
388g_slice_addslice(struct g_geom *gp, int idx, off_t offset, off_t length, u_int sectorsize, const char *fmt, ...) |
389{ 390 struct g_provider *pp; 391 struct g_slicer *gsp; 392 va_list ap; 393 struct sbuf *sb; 394 395 g_trace(G_T_TOPOLOGY, "g_slice_addslice()"); 396 g_topology_assert(); 397 gsp = gp->softc; 398 va_start(ap, fmt); 399 sb = sbuf_new(NULL, NULL, 0, SBUF_AUTOEXTEND); 400 sbuf_vprintf(sb, fmt, ap); 401 sbuf_finish(sb); 402 pp = g_new_providerf(gp, sbuf_data(sb)); 403 |
404 pp->index = idx; 405 gsp->slices[idx].length = length; 406 gsp->slices[idx].offset = offset; 407 gsp->slices[idx].provider = pp; 408 gsp->slices[idx].sectorsize = sectorsize; 409 pp->mediasize = gsp->slices[idx].length; 410 pp->sectorsize = gsp->slices[idx].sectorsize; |
411 sbuf_delete(sb); 412 if (bootverbose) 413 printf("GEOM: Add %s, start %jd length %jd end %jd\n", 414 pp->name, (intmax_t)offset, (intmax_t)length, 415 (intmax_t)(offset + length - 1)); 416 return(pp); 417} 418 --- 63 unchanged lines hidden --- |