Deleted Added
full compact
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 ---