geom_io.c (110517) | geom_io.c (110523) |
---|---|
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_io.c 110517 2003-02-07 21:09:51Z phk $ | 35 * $FreeBSD: head/sys/geom/geom_io.c 110523 2003-02-07 23:08:24Z phk $ |
36 */ 37 38 39#include <sys/param.h> 40#include <sys/stdint.h> 41#ifndef _KERNEL 42#include <stdio.h> 43#include <string.h> --- 105 unchanged lines hidden (view full) --- 149 bp2 = g_new_bio(); 150 if (bp2 != NULL) { 151 bp2->bio_parent = bp; 152 bp2->bio_cmd = bp->bio_cmd; 153 bp2->bio_length = bp->bio_length; 154 bp2->bio_offset = bp->bio_offset; 155 bp2->bio_data = bp->bio_data; 156 bp2->bio_attribute = bp->bio_attribute; | 36 */ 37 38 39#include <sys/param.h> 40#include <sys/stdint.h> 41#ifndef _KERNEL 42#include <stdio.h> 43#include <string.h> --- 105 unchanged lines hidden (view full) --- 149 bp2 = g_new_bio(); 150 if (bp2 != NULL) { 151 bp2->bio_parent = bp; 152 bp2->bio_cmd = bp->bio_cmd; 153 bp2->bio_length = bp->bio_length; 154 bp2->bio_offset = bp->bio_offset; 155 bp2->bio_data = bp->bio_data; 156 bp2->bio_attribute = bp->bio_attribute; |
157 bp->bio_children++; /* XXX: atomic ? */ | 157 bp->bio_children++; |
158 } 159 /* g_trace(G_T_BIO, "g_clone_bio(%p) = %p", bp, bp2); */ 160 return(bp2); 161} 162 163void 164g_io_init() 165{ --- 90 unchanged lines hidden (view full) --- 256 break; 257 } 258 return (0); 259} 260 261void 262g_io_request(struct bio *bp, struct g_consumer *cp) 263{ | 158 } 159 /* g_trace(G_T_BIO, "g_clone_bio(%p) = %p", bp, bp2); */ 160 return(bp2); 161} 162 163void 164g_io_init() 165{ --- 90 unchanged lines hidden (view full) --- 256 break; 257 } 258 return (0); 259} 260 261void 262g_io_request(struct bio *bp, struct g_consumer *cp) 263{ |
264 struct g_provider *pp; 265 struct bintime bt; |
|
264 | 266 |
267 pp = cp->provider; |
|
265 KASSERT(cp != NULL, ("NULL cp in g_io_request")); 266 KASSERT(bp != NULL, ("NULL bp in g_io_request")); 267 KASSERT(bp->bio_data != NULL, ("NULL bp->data in g_io_request")); | 268 KASSERT(cp != NULL, ("NULL cp in g_io_request")); 269 KASSERT(bp != NULL, ("NULL bp in g_io_request")); 270 KASSERT(bp->bio_data != NULL, ("NULL bp->data in g_io_request")); |
268 KASSERT(bp->bio_to == NULL, ("consumer not attached in g_io_request")); | 271 KASSERT(pp != NULL, ("consumer not attached in g_io_request")); 272 |
269 bp->bio_from = cp; | 273 bp->bio_from = cp; |
270 bp->bio_to = cp->provider; | 274 bp->bio_to = pp; |
271 bp->bio_error = 0; 272 bp->bio_completed = 0; 273 | 275 bp->bio_error = 0; 276 bp->bio_completed = 0; 277 |
274 /* begin_stats(&bp->stats); */ | 278 if (g_collectstats) { 279 /* Collect statistics */ 280 binuptime(&bp->bio_t0); 281 if (cp->stat.nop == cp->stat.nend) { 282 /* Consumer is idle */ 283 bt = bp->bio_t0; 284 bintime_sub(&bt, &cp->stat.wentidle); 285 bintime_add(&cp->stat.it, &bt); 286 if (pp->stat.nop == pp->stat.nend) { 287 /* 288 * NB: Provider can only be idle if the 289 * consumer is but we cannot trust them 290 * to have gone idle at the same time. 291 */ 292 bt = bp->bio_t0; 293 bintime_sub(&bt, &pp->stat.wentidle); 294 bintime_add(&pp->stat.it, &bt); 295 } 296 } 297 } 298 cp->stat.nop++; 299 pp->stat.nop++; |
275 | 300 |
276 atomic_add_int(&cp->biocount, 1); 277 | |
278 /* Pass it on down. */ 279 g_trace(G_T_BIO, "bio_request(%p) from %p(%s) to %p(%s) cmd %d", | 301 /* Pass it on down. */ 302 g_trace(G_T_BIO, "bio_request(%p) from %p(%s) to %p(%s) cmd %d", |
280 bp, bp->bio_from, bp->bio_from->geom->name, 281 bp->bio_to, bp->bio_to->name, bp->bio_cmd); | 303 bp, cp, cp->geom->name, pp, pp->name, bp->bio_cmd); |
282 g_bioq_enqueue_tail(bp, &g_bio_run_down); 283 wakeup(&g_wait_down); 284} 285 286void 287g_io_deliver(struct bio *bp, int error) 288{ | 304 g_bioq_enqueue_tail(bp, &g_bio_run_down); 305 wakeup(&g_wait_down); 306} 307 308void 309g_io_deliver(struct bio *bp, int error) 310{ |
311 struct g_consumer *cp; 312 struct g_provider *pp; 313 struct bintime t1; 314 int idx; |
|
289 | 315 |
316 cp = bp->bio_from; 317 pp = bp->bio_to; |
|
290 KASSERT(bp != NULL, ("NULL bp in g_io_deliver")); | 318 KASSERT(bp != NULL, ("NULL bp in g_io_deliver")); |
291 KASSERT(bp->bio_from != NULL, ("NULL bio_from in g_io_deliver")); 292 KASSERT(bp->bio_from->geom != NULL, 293 ("NULL bio_from->geom in g_io_deliver")); 294 KASSERT(bp->bio_to != NULL, ("NULL bio_to in g_io_deliver")); | 319 KASSERT(cp != NULL, ("NULL bio_from in g_io_deliver")); 320 KASSERT(cp->geom != NULL, ("NULL bio_from->geom in g_io_deliver")); 321 KASSERT(pp != NULL, ("NULL bio_to in g_io_deliver")); |
295 296 g_trace(G_T_BIO, 297"g_io_deliver(%p) from %p(%s) to %p(%s) cmd %d error %d off %jd len %jd", | 322 323 g_trace(G_T_BIO, 324"g_io_deliver(%p) from %p(%s) to %p(%s) cmd %d error %d off %jd len %jd", |
298 bp, bp->bio_from, bp->bio_from->geom->name, 299 bp->bio_to, bp->bio_to->name, bp->bio_cmd, error, | 325 bp, cp, cp->geom->name, pp, pp->name, bp->bio_cmd, error, |
300 (intmax_t)bp->bio_offset, (intmax_t)bp->bio_length); | 326 (intmax_t)bp->bio_offset, (intmax_t)bp->bio_length); |
301 /* finish_stats(&bp->stats); */ | |
302 | 327 |
328 switch (bp->bio_cmd) { 329 case BIO_READ: idx = G_STAT_IDX_READ; break; 330 case BIO_WRITE: idx = G_STAT_IDX_WRITE; break; 331 case BIO_DELETE: idx = G_STAT_IDX_DELETE; break; 332 case BIO_GETATTR: idx = -1; break; 333 case BIO_SETATTR: idx = -1; break; 334 default: 335 panic("unknown bio_cmd in g_io_deliver"); 336 break; 337 } 338 339 /* Collect statistics */ 340 if (g_collectstats) { 341 binuptime(&t1); 342 pp->stat.wentidle = t1; 343 cp->stat.wentidle = t1; 344 345 if (idx >= 0) { 346 bintime_sub(&t1, &bp->bio_t0); 347 bintime_add(&cp->stat.ops[idx].dt, &t1); 348 bintime_add(&pp->stat.ops[idx].dt, &t1); 349 pp->stat.ops[idx].nbyte += bp->bio_completed; 350 cp->stat.ops[idx].nbyte += bp->bio_completed; 351 pp->stat.ops[idx].nop++; 352 cp->stat.ops[idx].nop++; 353 if (error == ENOMEM) { 354 cp->stat.ops[idx].nmem++; 355 pp->stat.ops[idx].nmem++; 356 } else if (error != 0) { 357 cp->stat.ops[idx].nerr++; 358 pp->stat.ops[idx].nerr++; 359 } 360 } 361 } 362 363 pp->stat.nend++; /* In reverse order of g_io_request() */ 364 cp->stat.nend++; 365 |
|
303 if (error == ENOMEM) { | 366 if (error == ENOMEM) { |
304 printf("ENOMEM %p on %p(%s)\n", 305 bp, bp->bio_to, bp->bio_to->name); 306 g_io_request(bp, bp->bio_from); | 367 printf("ENOMEM %p on %p(%s)\n", bp, pp, pp->name); 368 g_io_request(bp, cp); |
307 pace++; 308 return; 309 } | 369 pace++; 370 return; 371 } |
310 | |
311 bp->bio_error = error; | 372 bp->bio_error = error; |
312 | |
313 g_bioq_enqueue_tail(bp, &g_bio_run_up); | 373 g_bioq_enqueue_tail(bp, &g_bio_run_up); |
314 | |
315 wakeup(&g_wait_up); 316} 317 318void 319g_io_schedule_down(struct thread *tp __unused) 320{ 321 struct bio *bp; 322 off_t excess; --- 34 unchanged lines hidden (view full) --- 357 struct g_consumer *cp; 358 359 for(;;) { 360 bp = g_bioq_first(&g_bio_run_up); 361 if (bp == NULL) 362 break; 363 364 cp = bp->bio_from; | 374 wakeup(&g_wait_up); 375} 376 377void 378g_io_schedule_down(struct thread *tp __unused) 379{ 380 struct bio *bp; 381 off_t excess; --- 34 unchanged lines hidden (view full) --- 416 struct g_consumer *cp; 417 418 for(;;) { 419 bp = g_bioq_first(&g_bio_run_up); 420 if (bp == NULL) 421 break; 422 423 cp = bp->bio_from; |
365 366 atomic_add_int(&cp->biocount, -1); | |
367 biodone(bp); 368 } 369} 370 371void * 372g_read_data(struct g_consumer *cp, off_t offset, off_t length, int *error) 373{ 374 struct bio *bp; --- 39 unchanged lines hidden --- | 424 biodone(bp); 425 } 426} 427 428void * 429g_read_data(struct g_consumer *cp, off_t offset, off_t length, int *error) 430{ 431 struct bio *bp; --- 39 unchanged lines hidden --- |