g_stripe.c (131649) | g_stripe.c (131878) |
---|---|
1/*- 2 * Copyright (c) 2003 Pawel Jakub Dawidek <pjd@FreeBSD.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 11 unchanged lines hidden (view full) --- 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2003 Pawel Jakub Dawidek <pjd@FreeBSD.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 11 unchanged lines hidden (view full) --- 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27#include <sys/cdefs.h> |
28__FBSDID("$FreeBSD: head/sys/geom/stripe/g_stripe.c 131649 2004-07-05 21:16:37Z pjd $"); | 28__FBSDID("$FreeBSD: head/sys/geom/stripe/g_stripe.c 131878 2004-07-09 14:30:09Z pjd $"); |
29 30#include <sys/param.h> 31#include <sys/systm.h> 32#include <sys/kernel.h> 33#include <sys/module.h> 34#include <sys/lock.h> 35#include <sys/mutex.h> 36#include <sys/bio.h> 37#include <sys/sysctl.h> 38#include <sys/malloc.h> | 29 30#include <sys/param.h> 31#include <sys/systm.h> 32#include <sys/kernel.h> 33#include <sys/module.h> 34#include <sys/lock.h> 35#include <sys/mutex.h> 36#include <sys/bio.h> 37#include <sys/sysctl.h> 38#include <sys/malloc.h> |
39#include <vm/uma.h> |
|
39#include <geom/geom.h> 40#include <geom/stripe/g_stripe.h> 41 42 | 40#include <geom/geom.h> 41#include <geom/stripe/g_stripe.h> 42 43 |
44#define MAX_IO_SIZE (DFLTPHYS * 2) |
|
43static MALLOC_DEFINE(M_STRIPE, "stripe data", "GEOM_STRIPE Data"); 44 | 45static MALLOC_DEFINE(M_STRIPE, "stripe data", "GEOM_STRIPE Data"); 46 |
45SYSCTL_DECL(_kern_geom); 46SYSCTL_NODE(_kern_geom, OID_AUTO, stripe, CTLFLAG_RW, 0, "GEOM_STRIPE stuff"); 47static u_int g_stripe_debug = 0; 48SYSCTL_UINT(_kern_geom_stripe, OID_AUTO, debug, CTLFLAG_RW, &g_stripe_debug, 0, 49 "Debug level"); | 47static uma_zone_t g_stripe_zone; |
50 51static int g_stripe_destroy(struct g_stripe_softc *sc, boolean_t force); 52static int g_stripe_destroy_geom(struct gctl_req *req, struct g_class *mp, 53 struct g_geom *gp); 54 55static g_taste_t g_stripe_taste; 56static g_ctl_req_t g_stripe_config; 57static g_dumpconf_t g_stripe_dumpconf; | 48 49static int g_stripe_destroy(struct g_stripe_softc *sc, boolean_t force); 50static int g_stripe_destroy_geom(struct gctl_req *req, struct g_class *mp, 51 struct g_geom *gp); 52 53static g_taste_t g_stripe_taste; 54static g_ctl_req_t g_stripe_config; 55static g_dumpconf_t g_stripe_dumpconf; |
56static g_init_t g_stripe_init; 57static g_fini_t g_stripe_fini; |
|
58 59struct g_class g_stripe_class = { 60 .name = G_STRIPE_CLASS_NAME, 61 .ctlreq = g_stripe_config, 62 .taste = g_stripe_taste, | 58 59struct g_class g_stripe_class = { 60 .name = G_STRIPE_CLASS_NAME, 61 .ctlreq = g_stripe_config, 62 .taste = g_stripe_taste, |
63 .destroy_geom = g_stripe_destroy_geom | 63 .destroy_geom = g_stripe_destroy_geom, 64 .init = g_stripe_init, 65 .fini = g_stripe_fini |
64}; 65 | 66}; 67 |
68SYSCTL_DECL(_kern_geom); 69SYSCTL_NODE(_kern_geom, OID_AUTO, stripe, CTLFLAG_RW, 0, "GEOM_STRIPE stuff"); 70static u_int g_stripe_debug = 0; 71SYSCTL_UINT(_kern_geom_stripe, OID_AUTO, debug, CTLFLAG_RW, &g_stripe_debug, 0, 72 "Debug level"); 73static int g_stripe_fast = 1; 74TUNABLE_INT("kern.geom.stripe.fast", &g_stripe_fast); 75static int 76g_sysctl_stripe_fast(SYSCTL_HANDLER_ARGS) 77{ 78 int error, fast; |
|
66 | 79 |
80 fast = g_stripe_fast; 81 error = sysctl_handle_int(oidp, &fast, sizeof(fast), req); 82 if (error == 0 && req->newptr != NULL) 83 g_stripe_fast = fast; 84 return (error); 85} 86SYSCTL_PROC(_kern_geom_stripe, OID_AUTO, fast, CTLTYPE_INT | CTLFLAG_RW, 87 NULL, 0, g_sysctl_stripe_fast, "I", "Fast, but memory-consuming mode"); 88static u_int g_stripe_maxmem = MAX_IO_SIZE * 10; 89TUNABLE_INT("kern.geom.stripe.maxmem", &g_stripe_maxmem); 90SYSCTL_UINT(_kern_geom_stripe, OID_AUTO, maxmem, CTLFLAG_RD, &g_stripe_maxmem, 91 0, "Maximum memory that could be allocated in \"fast\" mode (in bytes)"); 92 |
|
67/* 68 * Greatest Common Divisor. 69 */ 70static u_int 71gcd(u_int a, u_int b) 72{ 73 u_int c; 74 --- 10 unchanged lines hidden (view full) --- 85 */ 86static u_int 87lcm(u_int a, u_int b) 88{ 89 90 return ((a * b) / gcd(a, b)); 91} 92 | 93/* 94 * Greatest Common Divisor. 95 */ 96static u_int 97gcd(u_int a, u_int b) 98{ 99 u_int c; 100 --- 10 unchanged lines hidden (view full) --- 111 */ 112static u_int 113lcm(u_int a, u_int b) 114{ 115 116 return ((a * b) / gcd(a, b)); 117} 118 |
119static void 120g_stripe_init(struct g_class *mp __unused) 121{ 122 123 g_stripe_zone = uma_zcreate("g_stripe_zone", MAX_IO_SIZE, NULL, NULL, 124 NULL, NULL, 0, 0); 125 g_stripe_maxmem -= g_stripe_maxmem % MAX_IO_SIZE; 126 uma_zone_set_max(g_stripe_zone, g_stripe_maxmem / MAX_IO_SIZE); 127} 128 129static void 130g_stripe_fini(struct g_class *mp __unused) 131{ 132 133 uma_zdestroy(g_stripe_zone); 134} 135 |
|
93/* 94 * Return the number of valid disks. 95 */ 96static u_int 97g_stripe_nvalid(struct g_stripe_softc *sc) 98{ 99 u_int i, no; 100 --- 99 unchanged lines hidden (view full) --- 200 } 201 /* NOTREACHED */ 202 } 203 204 return (error); 205} 206 207static void | 136/* 137 * Return the number of valid disks. 138 */ 139static u_int 140g_stripe_nvalid(struct g_stripe_softc *sc) 141{ 142 u_int i, no; 143 --- 99 unchanged lines hidden (view full) --- 243 } 244 /* NOTREACHED */ 245 } 246 247 return (error); 248} 249 250static void |
208g_stripe_start(struct bio *bp) | 251g_stripe_copy(struct g_stripe_softc *sc, char *src, char *dst, off_t offset, 252 off_t length, int mode) |
209{ | 253{ |
210 struct g_provider *pp; | 254 u_int stripesize; 255 size_t len; 256 257 stripesize = sc->sc_stripesize; 258 len = (size_t)(stripesize - (offset & (stripesize - 1))); 259 do { 260 bcopy(src, dst, len); 261 if (mode) { 262 dst += len + stripesize * (sc->sc_ndisks - 1); 263 src += len; 264 } else { 265 dst += len; 266 src += len + stripesize * (sc->sc_ndisks - 1); 267 } 268 length -= len; 269 KASSERT(length >= 0, 270 ("Length < 0 (stripesize=%zu, offset=%jd, length=%jd).", 271 (size_t)stripesize, (intmax_t)offset, (intmax_t)length)); 272 if (length > stripesize) 273 len = stripesize; 274 else 275 len = length; 276 } while (length > 0); 277} 278 279static void 280g_stripe_done(struct bio *bp) 281{ |
211 struct g_stripe_softc *sc; | 282 struct g_stripe_softc *sc; |
212 off_t off, start, length, nstripe; | 283 struct bio *pbp; 284 285 pbp = bp->bio_parent; 286 sc = pbp->bio_to->geom->softc; 287 if (pbp->bio_error == 0) 288 pbp->bio_error = bp->bio_error; 289 pbp->bio_completed += bp->bio_completed; 290 if (bp->bio_cmd == BIO_READ && bp->bio_driver1 != NULL) { 291 g_stripe_copy(sc, bp->bio_data, bp->bio_driver1, bp->bio_offset, 292 bp->bio_length, 1); 293 bp->bio_data = bp->bio_driver1; 294 bp->bio_driver1 = NULL; 295 } 296 g_destroy_bio(bp); 297 pbp->bio_inbed++; 298 if (pbp->bio_children == pbp->bio_inbed) { 299 if (pbp->bio_caller1 != NULL) 300 uma_zfree(g_stripe_zone, pbp->bio_caller1); 301 g_io_deliver(pbp, pbp->bio_error); 302 } 303} 304 305static int 306g_stripe_start_fast(struct bio *bp, u_int no, off_t offset, off_t length) 307{ 308 TAILQ_HEAD(, bio) queue = TAILQ_HEAD_INITIALIZER(queue); 309 u_int nparts = 0, stripesize; 310 struct g_stripe_softc *sc; 311 char *addr, *data = NULL; |
213 struct bio *cbp; | 312 struct bio *cbp; |
214 u_int sectorsize; | 313 int error; 314 315 sc = bp->bio_to->geom->softc; 316 317 addr = bp->bio_data; 318 stripesize = sc->sc_stripesize; 319 320 cbp = g_clone_bio(bp); 321 if (cbp == NULL) { 322 error = ENOMEM; 323 goto failure; 324 } 325 TAILQ_INSERT_TAIL(&queue, cbp, bio_queue); 326 nparts++; 327 /* 328 * Fill in the component buf structure. 329 */ 330 cbp->bio_done = g_stripe_done; 331 cbp->bio_offset = offset; 332 cbp->bio_data = addr; 333 cbp->bio_driver1 = NULL; 334 cbp->bio_length = length; 335 cbp->bio_driver2 = sc->sc_disks[no]; 336 337 /* offset -= offset % stripesize; */ 338 offset -= offset & (stripesize - 1); 339 addr += length; 340 length = bp->bio_length - length; 341 for (no++; length > 0; no++, length -= stripesize, addr += stripesize) { 342 if (no > sc->sc_ndisks - 1) { 343 no = 0; 344 offset += stripesize; 345 } 346 if (nparts >= sc->sc_ndisks) { 347 cbp = TAILQ_NEXT(cbp, bio_queue); 348 if (cbp == NULL) 349 cbp = TAILQ_FIRST(&queue); 350 nparts++; 351 /* 352 * Update bio structure. 353 */ 354 /* 355 * MIN() is in case when 356 * (bp->bio_length % sc->sc_stripesize) != 0. 357 */ 358 cbp->bio_length += MIN(stripesize, length); 359 if (cbp->bio_driver1 == NULL) { 360 cbp->bio_driver1 = cbp->bio_data; 361 cbp->bio_data = NULL; 362 if (data == NULL) { 363 data = uma_zalloc(g_stripe_zone, 364 M_NOWAIT); 365 if (data == NULL) { 366 error = ENOMEM; 367 goto failure; 368 } 369 } 370 } 371 } else { 372 cbp = g_clone_bio(bp); 373 if (cbp == NULL) { 374 error = ENOMEM; 375 goto failure; 376 } 377 TAILQ_INSERT_TAIL(&queue, cbp, bio_queue); 378 nparts++; 379 /* 380 * Fill in the component buf structure. 381 */ 382 cbp->bio_done = g_stripe_done; 383 cbp->bio_offset = offset; 384 cbp->bio_data = addr; 385 cbp->bio_driver1 = NULL; 386 /* 387 * MIN() is in case when 388 * (bp->bio_length % sc->sc_stripesize) != 0. 389 */ 390 cbp->bio_length = MIN(stripesize, length); 391 cbp->bio_driver2 = sc->sc_disks[no]; 392 } 393 } 394 if (data != NULL) 395 bp->bio_caller1 = data; 396 /* 397 * Fire off all allocated requests! 398 */ 399 while ((cbp = TAILQ_FIRST(&queue)) != NULL) { 400 struct g_consumer *cp; 401 402 TAILQ_REMOVE(&queue, cbp, bio_queue); 403 cp = cbp->bio_driver2; 404 cbp->bio_driver2 = NULL; 405 cbp->bio_to = cp->provider; 406 if (cbp->bio_driver1 != NULL) { 407 cbp->bio_data = data; 408 if (bp->bio_cmd == BIO_WRITE) { 409 g_stripe_copy(sc, cbp->bio_driver1, data, 410 cbp->bio_offset, cbp->bio_length, 0); 411 } 412 data += cbp->bio_length; 413 } 414 G_STRIPE_LOGREQ(cbp, "Sending request."); 415 g_io_request(cbp, cp); 416 } 417 return (0); 418failure: 419 if (data != NULL) 420 uma_zfree(g_stripe_zone, data); 421 while ((cbp = TAILQ_FIRST(&queue)) != NULL) { 422 TAILQ_REMOVE(&queue, cbp, bio_queue); 423 if (cbp->bio_driver1 != NULL) { 424 cbp->bio_data = cbp->bio_driver1; 425 cbp->bio_driver1 = NULL; 426 } 427 g_destroy_bio(cbp); 428 } 429 return (error); 430} 431 432static int 433g_stripe_start_economic(struct bio *bp, u_int no, off_t offset, off_t length) 434{ 435 TAILQ_HEAD(, bio) queue = TAILQ_HEAD_INITIALIZER(queue); 436 struct g_stripe_softc *sc; |
215 uint32_t stripesize; | 437 uint32_t stripesize; |
216 uint16_t no; | 438 struct bio *cbp; |
217 char *addr; | 439 char *addr; |
440 int error; |
|
218 | 441 |
219 pp = bp->bio_to; 220 sc = pp->geom->softc; | 442 sc = bp->bio_to->geom->softc; 443 444 addr = bp->bio_data; 445 stripesize = sc->sc_stripesize; 446 447 cbp = g_clone_bio(bp); 448 if (cbp == NULL) { 449 error = ENOMEM; 450 goto failure; 451 } 452 TAILQ_INSERT_TAIL(&queue, cbp, bio_queue); |
221 /* | 453 /* |
454 * Fill in the component buf structure. 455 */ 456 cbp->bio_done = g_std_done; 457 cbp->bio_offset = offset; 458 cbp->bio_data = addr; 459 cbp->bio_length = length; 460 cbp->bio_driver2 = sc->sc_disks[no]; 461 462 /* offset -= offset % stripesize; */ 463 offset -= offset & (stripesize - 1); 464 addr += length; 465 length = bp->bio_length - length; 466 for (no++; length > 0; no++, length -= stripesize, addr += stripesize) { 467 if (no > sc->sc_ndisks - 1) { 468 no = 0; 469 offset += stripesize; 470 } 471 cbp = g_clone_bio(bp); 472 if (cbp == NULL) { 473 error = ENOMEM; 474 goto failure; 475 } 476 TAILQ_INSERT_TAIL(&queue, cbp, bio_queue); 477 478 /* 479 * Fill in the component buf structure. 480 */ 481 cbp->bio_done = g_std_done; 482 cbp->bio_offset = offset; 483 cbp->bio_data = addr; 484 /* 485 * MIN() is in case when 486 * (bp->bio_length % sc->sc_stripesize) != 0. 487 */ 488 cbp->bio_length = MIN(stripesize, length); 489 490 cbp->bio_driver2 = sc->sc_disks[no]; 491 } 492 /* 493 * Fire off all allocated requests! 494 */ 495 while ((cbp = TAILQ_FIRST(&queue)) != NULL) { 496 struct g_consumer *cp; 497 498 TAILQ_REMOVE(&queue, cbp, bio_queue); 499 cp = cbp->bio_driver2; 500 cbp->bio_driver2 = NULL; 501 cbp->bio_to = cp->provider; 502 G_STRIPE_LOGREQ(cbp, "Sending request."); 503 g_io_request(cbp, cp); 504 } 505 return (0); 506failure: 507 while ((cbp = TAILQ_FIRST(&queue)) != NULL) { 508 TAILQ_REMOVE(&queue, cbp, bio_queue); 509 g_destroy_bio(cbp); 510 } 511 return (error); 512} 513 514static void 515g_stripe_start(struct bio *bp) 516{ 517 off_t offset, start, length, nstripe; 518 struct g_stripe_softc *sc; 519 u_int no, stripesize; 520 int error, fast = 0; 521 522 sc = bp->bio_to->geom->softc; 523 /* |
|
222 * If sc == NULL, provider's error should be set and g_stripe_start() 223 * should not be called at all. 224 */ 225 KASSERT(sc != NULL, 226 ("Provider's error should be set (error=%d)(device=%s).", 227 bp->bio_to->error, bp->bio_to->name)); 228 229 G_STRIPE_LOGREQ(bp, "Request received."); --- 8 unchanged lines hidden (view full) --- 238 break; 239 case BIO_GETATTR: 240 /* To which provider it should be delivered? */ 241 default: 242 g_io_deliver(bp, EOPNOTSUPP); 243 return; 244 } 245 | 524 * If sc == NULL, provider's error should be set and g_stripe_start() 525 * should not be called at all. 526 */ 527 KASSERT(sc != NULL, 528 ("Provider's error should be set (error=%d)(device=%s).", 529 bp->bio_to->error, bp->bio_to->name)); 530 531 G_STRIPE_LOGREQ(bp, "Request received."); --- 8 unchanged lines hidden (view full) --- 540 break; 541 case BIO_GETATTR: 542 /* To which provider it should be delivered? */ 543 default: 544 g_io_deliver(bp, EOPNOTSUPP); 545 return; 546 } 547 |
246 addr = bp->bio_data; 247 sectorsize = sc->sc_provider->sectorsize; | |
248 stripesize = sc->sc_stripesize; 249 250 /* | 548 stripesize = sc->sc_stripesize; 549 550 /* |
251 * Calcucations are quite messy, but fast I hope. | 551 * Calculations are quite messy, but fast I hope. |
252 */ 253 254 /* Stripe number. */ 255 /* nstripe = bp->bio_offset / stripesize; */ 256 nstripe = bp->bio_offset >> (off_t)sc->sc_stripebits; 257 /* Disk number. */ 258 no = nstripe % sc->sc_ndisks; 259 /* Start position in stripe. */ 260 /* start = bp->bio_offset % stripesize; */ 261 start = bp->bio_offset & (stripesize - 1); 262 /* Start position in disk. */ | 552 */ 553 554 /* Stripe number. */ 555 /* nstripe = bp->bio_offset / stripesize; */ 556 nstripe = bp->bio_offset >> (off_t)sc->sc_stripebits; 557 /* Disk number. */ 558 no = nstripe % sc->sc_ndisks; 559 /* Start position in stripe. */ 560 /* start = bp->bio_offset % stripesize; */ 561 start = bp->bio_offset & (stripesize - 1); 562 /* Start position in disk. */ |
263 /* off = (nstripe / sc->sc_ndisks) * stripesize + start; */ 264 off = ((nstripe / sc->sc_ndisks) << sc->sc_stripebits) + start; | 563 /* offset = (nstripe / sc->sc_ndisks) * stripesize + start; */ 564 offset = ((nstripe / sc->sc_ndisks) << sc->sc_stripebits) + start; |
265 /* Length of data to operate. */ 266 length = MIN(bp->bio_length, stripesize - start); 267 | 565 /* Length of data to operate. */ 566 length = MIN(bp->bio_length, stripesize - start); 567 |
268 cbp = g_clone_bio(bp); 269 if (cbp == NULL) { 270 /* 271 * Deny all request. This is pointless 272 * to split rest of the request, bacause 273 * we're setting bio_error here, so all 274 * request will be denied, anyway. 275 */ 276 bp->bio_completed = bp->bio_length; 277 if (bp->bio_error == 0) 278 bp->bio_error = ENOMEM; 279 g_io_deliver(bp, bp->bio_error); 280 return; | 568 /* 569 * Do use "fast" mode when: 570 * 1. "Fast" mode is ON. 571 * and 572 * 2. Request size is less than or equal to MAX_IO_SIZE (128kB), 573 * which should always be true. 574 * and 575 * 3. Request size is bigger than stripesize * ndisks. If it isn't, 576 * there will be no need to send more than one I/O request to 577 * a provider, so there is nothing to optmize. 578 */ 579 if (g_stripe_fast && bp->bio_length <= MAX_IO_SIZE && 580 bp->bio_length >= stripesize * sc->sc_ndisks) { 581 fast = 1; |
281 } | 582 } |
583 error = 0; 584 if (fast) 585 error = g_stripe_start_fast(bp, no, offset, length); |
|
282 /* | 586 /* |
283 * Fill in the component buf structure. | 587 * Do use "economic" when: 588 * 1. "Economic" mode is ON. 589 * or 590 * 2. "Fast" mode failed. It can only failed if there is no memory. |
284 */ | 591 */ |
285 cbp->bio_done = g_std_done; 286 cbp->bio_offset = off; 287 cbp->bio_data = addr; 288 cbp->bio_length = length; 289 cbp->bio_to = sc->sc_disks[no]->provider; 290 G_STRIPE_LOGREQ(cbp, "Sending request."); 291 g_io_request(cbp, sc->sc_disks[no]); 292 293 /* off -= off % stripesize; */ 294 off -= off & (stripesize - 1); 295 addr += length; 296 length = bp->bio_length - length; 297 for (no++; length > 0; no++, length -= stripesize, addr += stripesize) { 298 if (no > sc->sc_ndisks - 1) { 299 no = 0; 300 off += stripesize; 301 } 302 cbp = g_clone_bio(bp); 303 if (cbp == NULL) { 304 /* 305 * Deny remaining part. This is pointless 306 * to split rest of the request, bacause 307 * we're setting bio_error here, so all 308 * request will be denied, anyway. 309 */ 310 bp->bio_completed += length; 311 if (bp->bio_error == 0) 312 bp->bio_error = ENOMEM; 313 if (bp->bio_completed == bp->bio_length) 314 g_io_deliver(bp, bp->bio_error); 315 return; 316 } 317 318 /* 319 * Fill in the component buf structure. 320 */ 321 cbp->bio_done = g_std_done; 322 cbp->bio_offset = off; 323 cbp->bio_data = addr; 324 /* 325 * MIN() is in case when 326 * (bp->bio_length % sc->sc_stripesize) != 0. 327 */ 328 cbp->bio_length = MIN(stripesize, length); 329 330 cbp->bio_to = sc->sc_disks[no]->provider; 331 G_STRIPE_LOGREQ(cbp, "Sending request."); 332 g_io_request(cbp, sc->sc_disks[no]); | 592 if (!fast || error != 0) 593 error = g_stripe_start_economic(bp, no, offset, length); 594 if (error != 0) { 595 if (bp->bio_error == 0) 596 bp->bio_error = error; 597 g_io_deliver(bp, bp->bio_error); |
333 } 334} 335 336static void 337g_stripe_check_and_run(struct g_stripe_softc *sc) 338{ 339 off_t mediasize, ms; 340 u_int no, sectorsize = 0; --- 571 unchanged lines hidden --- | 598 } 599} 600 601static void 602g_stripe_check_and_run(struct g_stripe_softc *sc) 603{ 604 off_t mediasize, ms; 605 u_int no, sectorsize = 0; --- 571 unchanged lines hidden --- |