vnd.c (1.35) | vnd.c (1.36) |
---|---|
1/* $NetBSD: vnd.c,v 1.35 1997/05/25 16:21:45 pk Exp $ */ | 1/* $NetBSD: vnd.c,v 1.36 1997/05/25 19:37:36 pk Exp $ */ |
2 3/* 4 * Copyright (c) 1988 University of Utah. 5 * Copyright (c) 1990, 1993 6 * The Regents of the University of California. All rights reserved. 7 * 8 * This code is derived from software contributed to Berkeley by 9 * the Systems Programming Group of the University of Utah Computer --- 80 unchanged lines hidden (view full) --- 90#define VDB_INIT 0x02 91#define VDB_IO 0x04 92#endif 93 94#define b_cylin b_resid 95 96#define vndunit(x) DISKUNIT(x) 97 | 2 3/* 4 * Copyright (c) 1988 University of Utah. 5 * Copyright (c) 1990, 1993 6 * The Regents of the University of California. All rights reserved. 7 * 8 * This code is derived from software contributed to Berkeley by 9 * the Systems Programming Group of the University of Utah Computer --- 80 unchanged lines hidden (view full) --- 90#define VDB_INIT 0x02 91#define VDB_IO 0x04 92#endif 93 94#define b_cylin b_resid 95 96#define vndunit(x) DISKUNIT(x) 97 |
98struct vndxfer { 99 struct buf *vx_bp; /* Pointer to parent buffer */ 100 int vx_error; 101 int vx_pending; /* # of pending aux buffers */ 102}; 103 |
|
98struct vndbuf { 99 struct buf vb_buf; | 104struct vndbuf { 105 struct buf vb_buf; |
100 struct buf *vb_obp; | 106 struct vndxfer *vb_xfer; |
101}; 102 | 107}; 108 |
109#define getvndxfer() \ 110 ((struct vndxfer *)malloc(sizeof(struct vndxfer), M_DEVBUF, M_WAITOK)) 111#define putvndxfer(vnx) \ 112 free((caddr_t)(vnx), M_DEVBUF) |
|
103#define getvndbuf() \ 104 ((struct vndbuf *)malloc(sizeof(struct vndbuf), M_DEVBUF, M_WAITOK)) 105#define putvndbuf(vbp) \ 106 free((caddr_t)(vbp), M_DEVBUF) 107 108struct vnd_softc { 109 int sc_flags; /* flags */ 110 size_t sc_size; /* size of vnd */ --- 140 unchanged lines hidden (view full) --- 251 */ 252void 253vndstrategy(bp) 254 register struct buf *bp; 255{ 256 int unit = vndunit(bp->b_dev); 257 register struct vnd_softc *vnd = &vnd_softc[unit]; 258 register struct vndbuf *nbp; | 113#define getvndbuf() \ 114 ((struct vndbuf *)malloc(sizeof(struct vndbuf), M_DEVBUF, M_WAITOK)) 115#define putvndbuf(vbp) \ 116 free((caddr_t)(vbp), M_DEVBUF) 117 118struct vnd_softc { 119 int sc_flags; /* flags */ 120 size_t sc_size; /* size of vnd */ --- 140 unchanged lines hidden (view full) --- 261 */ 262void 263vndstrategy(bp) 264 register struct buf *bp; 265{ 266 int unit = vndunit(bp->b_dev); 267 register struct vnd_softc *vnd = &vnd_softc[unit]; 268 register struct vndbuf *nbp; |
269 struct vndxfer *vnx; |
|
259 register int bn, bsize, resid; 260 register caddr_t addr; 261 int sz, flags, error; 262 263#ifdef DEBUG 264 if (vnddebug & VDB_FOLLOW) 265 printf("vndstrategy(%p): unit %d\n", bp, unit); 266#endif --- 13 unchanged lines hidden (view full) --- 280 } 281 biodone(bp); 282 return; 283 } 284 bn = dbtob(bn); 285 bsize = vnd->sc_vp->v_mount->mnt_stat.f_iosize; 286 addr = bp->b_data; 287 flags = bp->b_flags | B_CALL; | 270 register int bn, bsize, resid; 271 register caddr_t addr; 272 int sz, flags, error; 273 274#ifdef DEBUG 275 if (vnddebug & VDB_FOLLOW) 276 printf("vndstrategy(%p): unit %d\n", bp, unit); 277#endif --- 13 unchanged lines hidden (view full) --- 291 } 292 biodone(bp); 293 return; 294 } 295 bn = dbtob(bn); 296 bsize = vnd->sc_vp->v_mount->mnt_stat.f_iosize; 297 addr = bp->b_data; 298 flags = bp->b_flags | B_CALL; |
299 300 /* Allocate a header for this transfer and link it to the buffer */ 301 vnx = getvndxfer(); 302 vnx->vx_error = 0; 303 vnx->vx_pending = 0; 304 vnx->vx_bp = bp; 305 |
|
288 for (resid = bp->b_resid; resid; resid -= sz) { 289 struct vnode *vp; 290 daddr_t nbn; 291 int off, s, nra; 292 293 nra = 0; 294 VOP_LOCK(vnd->sc_vp); 295 error = VOP_BMAP(vnd->sc_vp, bn / bsize, &vp, &nbn, &nra); 296 VOP_UNLOCK(vnd->sc_vp); 297 if (error == 0 && (long)nbn == -1) 298 error = EIO; | 306 for (resid = bp->b_resid; resid; resid -= sz) { 307 struct vnode *vp; 308 daddr_t nbn; 309 int off, s, nra; 310 311 nra = 0; 312 VOP_LOCK(vnd->sc_vp); 313 error = VOP_BMAP(vnd->sc_vp, bn / bsize, &vp, &nbn, &nra); 314 VOP_UNLOCK(vnd->sc_vp); 315 if (error == 0 && (long)nbn == -1) 316 error = EIO; |
317 318 /* 319 * If there was an error or a hole in the file...punt. 320 * Note that we may have to wait for any operations 321 * that we have already fired off before releasing 322 * the buffer. 323 * 324 * XXX we could deal with holes here but it would be 325 * a hassle (in the write case). 326 */ 327 if (error) { 328 vnx->vx_error = error; 329 if (vnx->vx_pending == 0) { 330 bp->b_error = error; 331 bp->b_flags |= B_ERROR; 332 putvndxfer(vnx); 333 biodone(bp); 334 } 335 return; 336 } 337 |
|
299#ifdef DEBUG 300 if (!dovndcluster) 301 nra = 0; 302#endif 303 304 if ((off = bn % bsize) != 0) 305 sz = bsize - off; 306 else --- 38 unchanged lines hidden (view full) --- 345 } else { 346 nbp->vb_buf.b_validoff = 347 max(0, bp->b_validoff - (bp->b_bcount - resid)); 348 nbp->vb_buf.b_validend = 349 min(sz, 350 max(0, bp->b_validend - (bp->b_bcount-resid))); 351 } 352 | 338#ifdef DEBUG 339 if (!dovndcluster) 340 nra = 0; 341#endif 342 343 if ((off = bn % bsize) != 0) 344 sz = bsize - off; 345 else --- 38 unchanged lines hidden (view full) --- 384 } else { 385 nbp->vb_buf.b_validoff = 386 max(0, bp->b_validoff - (bp->b_bcount - resid)); 387 nbp->vb_buf.b_validend = 388 min(sz, 389 max(0, bp->b_validend - (bp->b_bcount-resid))); 390 } 391 |
353 /* save a reference to the old buffer */ 354 nbp->vb_obp = bp; | 392 nbp->vb_xfer = vnx; 393 vnx->vx_pending++; |
355 356 /* | 394 395 /* |
357 * If there was an error or a hole in the file...punt. 358 * Note that we deal with this after the nbp allocation. 359 * This ensures that we properly clean up any operations 360 * that we have already fired off. 361 * 362 * XXX we could deal with holes here but it would be 363 * a hassle (in the write case). 364 */ 365 if (error) { 366 nbp->vb_buf.b_error = error; 367 nbp->vb_buf.b_flags |= B_ERROR; 368 bp->b_resid -= (resid - sz); 369 biodone(&nbp->vb_buf); 370 return; 371 } 372 /* | |
373 * Just sort by block number 374 */ 375 nbp->vb_buf.b_cylin = nbp->vb_buf.b_blkno; 376 s = splbio(); 377 disksort(&vnd->sc_tab, &nbp->vb_buf); 378 if (vnd->sc_tab.b_active < vnd->sc_maxactive) { 379 vnd->sc_tab.b_active++; 380 vndstart(vnd); --- 37 unchanged lines hidden (view full) --- 418 VOP_STRATEGY(bp); 419} 420 421void 422vndiodone(bp) 423 struct buf *bp; 424{ 425 register struct vndbuf *vbp = (struct vndbuf *) bp; | 396 * Just sort by block number 397 */ 398 nbp->vb_buf.b_cylin = nbp->vb_buf.b_blkno; 399 s = splbio(); 400 disksort(&vnd->sc_tab, &nbp->vb_buf); 401 if (vnd->sc_tab.b_active < vnd->sc_maxactive) { 402 vnd->sc_tab.b_active++; 403 vndstart(vnd); --- 37 unchanged lines hidden (view full) --- 441 VOP_STRATEGY(bp); 442} 443 444void 445vndiodone(bp) 446 struct buf *bp; 447{ 448 register struct vndbuf *vbp = (struct vndbuf *) bp; |
426 register struct buf *pbp = vbp->vb_obp; | 449 register struct vndxfer *vnx = (struct vndxfer *)vbp->vb_xfer; 450 register struct buf *pbp = vnx->vx_bp; |
427 register struct vnd_softc *vnd = &vnd_softc[vndunit(pbp->b_dev)]; | 451 register struct vnd_softc *vnd = &vnd_softc[vndunit(pbp->b_dev)]; |
428 int s; | 452 int s, resid; |
429 430 s = splbio(); 431#ifdef DEBUG 432 if (vnddebug & VDB_IO) 433 printf("vndiodone(%ld): vbp %p vp %p blkno %x addr %p cnt %lx\n", 434 (long) (vnd-vnd_softc), vbp, vbp->vb_buf.b_vp, 435 vbp->vb_buf.b_blkno, vbp->vb_buf.b_data, 436 vbp->vb_buf.b_bcount); 437#endif 438 | 453 454 s = splbio(); 455#ifdef DEBUG 456 if (vnddebug & VDB_IO) 457 printf("vndiodone(%ld): vbp %p vp %p blkno %x addr %p cnt %lx\n", 458 (long) (vnd-vnd_softc), vbp, vbp->vb_buf.b_vp, 459 vbp->vb_buf.b_blkno, vbp->vb_buf.b_data, 460 vbp->vb_buf.b_bcount); 461#endif 462 |
463 resid = vbp->vb_buf.b_bcount - vbp->vb_buf.b_resid; 464 pbp->b_resid -= resid; 465 disk_unbusy(&vnd->sc_dkdev, resid); 466 vnx->vx_pending--; 467 |
|
439 if (vbp->vb_buf.b_error) { 440#ifdef DEBUG 441 if (vnddebug & VDB_IO) 442 printf("vndiodone: vbp %p error %d\n", vbp, 443 vbp->vb_buf.b_error); 444#endif | 468 if (vbp->vb_buf.b_error) { 469#ifdef DEBUG 470 if (vnddebug & VDB_IO) 471 printf("vndiodone: vbp %p error %d\n", vbp, 472 vbp->vb_buf.b_error); 473#endif |
445 pbp->b_flags |= B_ERROR; 446 pbp->b_error = biowait(&vbp->vb_buf); | 474 vnx->vx_error = vbp->vb_buf.b_error; |
447 } | 475 } |
448 pbp->b_resid -= vbp->vb_buf.b_bcount; | |
449 putvndbuf(vbp); | 476 putvndbuf(vbp); |
450 disk_unbusy(&vnd->sc_dkdev, vbp->vb_buf.b_bcount - vbp->vb_buf.b_resid); 451 if (pbp->b_resid == 0) { | 477 478 /* 479 * Wrap up this transaction if it has run to completion or, in 480 * case of an error, when all auxiliary buffers have returned. 481 */ 482 if (pbp->b_resid == 0 || (vnx->vx_error && vnx->vx_pending == 0)) { 483 484 if (vnx->vx_error != 0) { 485 pbp->b_flags |= B_ERROR; 486 pbp->b_error = vnx->vx_error; 487 } 488 putvndxfer(vnx); |
452#ifdef DEBUG 453 if (vnddebug & VDB_IO) 454 printf("vndiodone: pbp %p iodone\n", pbp); 455#endif 456 biodone(pbp); 457 } | 489#ifdef DEBUG 490 if (vnddebug & VDB_IO) 491 printf("vndiodone: pbp %p iodone\n", pbp); 492#endif 493 biodone(pbp); 494 } |
495 |
|
458 if (vnd->sc_tab.b_actf) 459 vndstart(vnd); 460 else 461 vnd->sc_tab.b_active--; 462 splx(s); 463} 464 465/* ARGSUSED */ --- 324 unchanged lines hidden --- | 496 if (vnd->sc_tab.b_actf) 497 vndstart(vnd); 498 else 499 vnd->sc_tab.b_active--; 500 splx(s); 501} 502 503/* ARGSUSED */ --- 324 unchanged lines hidden --- |