vfs_cluster.c (58345) | vfs_cluster.c (58909) |
---|---|
1/*- 2 * Copyright (c) 1993 3 * The Regents of the University of California. All rights reserved. 4 * Modifications/enhancements: 5 * Copyright (c) 1995 John S. Dyson. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions --- 19 unchanged lines hidden (view full) --- 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 * @(#)vfs_cluster.c 8.7 (Berkeley) 2/13/94 | 1/*- 2 * Copyright (c) 1993 3 * The Regents of the University of California. All rights reserved. 4 * Modifications/enhancements: 5 * Copyright (c) 1995 John S. Dyson. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions --- 19 unchanged lines hidden (view full) --- 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 * @(#)vfs_cluster.c 8.7 (Berkeley) 2/13/94 |
36 * $FreeBSD: head/sys/kern/vfs_cluster.c 58345 2000-03-20 10:44:49Z phk $ | 36 * $FreeBSD: head/sys/kern/vfs_cluster.c 58909 2000-04-02 00:55:28Z dillon $ |
37 */ 38 39#include "opt_debug_cluster.h" 40 41#include <sys/param.h> 42#include <sys/systm.h> 43#include <sys/kernel.h> 44#include <sys/proc.h> --- 483 unchanged lines hidden (view full) --- 528 * Three cases: 529 * 1. Write is not sequential (write asynchronously) 530 * Write is sequential: 531 * 2. beginning of cluster - begin cluster 532 * 3. middle of a cluster - add to cluster 533 * 4. end of a cluster - asynchronously write cluster 534 */ 535void | 37 */ 38 39#include "opt_debug_cluster.h" 40 41#include <sys/param.h> 42#include <sys/systm.h> 43#include <sys/kernel.h> 44#include <sys/proc.h> --- 483 unchanged lines hidden (view full) --- 528 * Three cases: 529 * 1. Write is not sequential (write asynchronously) 530 * Write is sequential: 531 * 2. beginning of cluster - begin cluster 532 * 3. middle of a cluster - add to cluster 533 * 4. end of a cluster - asynchronously write cluster 534 */ 535void |
536cluster_write(bp, filesize) | 536cluster_write(bp, filesize, seqcount) |
537 struct buf *bp; 538 u_quad_t filesize; | 537 struct buf *bp; 538 u_quad_t filesize; |
539 int seqcount; |
|
539{ 540 struct vnode *vp; 541 daddr_t lbn; 542 int maxclen, cursize; 543 int lblocksize; 544 int async; 545 546 vp = bp->b_vp; --- 18 unchanged lines hidden (view full) --- 565 /* 566 * Next block is not sequential. 567 * 568 * If we are not writing at end of file, the process 569 * seeked to another point in the file since its last 570 * write, or we have reached our maximum cluster size, 571 * then push the previous cluster. Otherwise try 572 * reallocating to make it sequential. | 540{ 541 struct vnode *vp; 542 daddr_t lbn; 543 int maxclen, cursize; 544 int lblocksize; 545 int async; 546 547 vp = bp->b_vp; --- 18 unchanged lines hidden (view full) --- 566 /* 567 * Next block is not sequential. 568 * 569 * If we are not writing at end of file, the process 570 * seeked to another point in the file since its last 571 * write, or we have reached our maximum cluster size, 572 * then push the previous cluster. Otherwise try 573 * reallocating to make it sequential. |
574 * 575 * Change to algorithm: only push previous cluster if 576 * it was sequential from the point of view of the 577 * seqcount heuristic, otherwise leave the buffer 578 * intact so we can potentially optimize the I/O 579 * later on in the buf_daemon or update daemon 580 * flush. |
|
573 */ 574 cursize = vp->v_lastw - vp->v_cstart + 1; 575 if (((u_quad_t) bp->b_offset + lblocksize) != filesize || 576 lbn != vp->v_lastw + 1 || vp->v_clen <= cursize) { | 581 */ 582 cursize = vp->v_lastw - vp->v_cstart + 1; 583 if (((u_quad_t) bp->b_offset + lblocksize) != filesize || 584 lbn != vp->v_lastw + 1 || vp->v_clen <= cursize) { |
577 if (!async) | 585 if (!async && seqcount > 0) { |
578 cluster_wbuild_wb(vp, lblocksize, 579 vp->v_cstart, cursize); | 586 cluster_wbuild_wb(vp, lblocksize, 587 vp->v_cstart, cursize); |
588 } |
|
580 } else { 581 struct buf **bpp, **endbp; 582 struct cluster_save *buflist; 583 584 buflist = cluster_collectbufs(vp, bp); 585 endbp = &buflist->bs_children 586 [buflist->bs_nchildren - 1]; 587 if (VOP_REALLOCBLKS(vp, buflist)) { 588 /* | 589 } else { 590 struct buf **bpp, **endbp; 591 struct cluster_save *buflist; 592 593 buflist = cluster_collectbufs(vp, bp); 594 endbp = &buflist->bs_children 595 [buflist->bs_nchildren - 1]; 596 if (VOP_REALLOCBLKS(vp, buflist)) { 597 /* |
589 * Failed, push the previous cluster. | 598 * Failed, push the previous cluster 599 * if *really* writing sequentially 600 * in the logical file (seqcount > 1), 601 * otherwise delay it in the hopes that 602 * the low level disk driver can 603 * optimize the write ordering. |
590 */ 591 for (bpp = buflist->bs_children; 592 bpp < endbp; bpp++) 593 brelse(*bpp); 594 free(buflist, M_SEGMENT); | 604 */ 605 for (bpp = buflist->bs_children; 606 bpp < endbp; bpp++) 607 brelse(*bpp); 608 free(buflist, M_SEGMENT); |
595 cluster_wbuild_wb(vp, lblocksize, 596 vp->v_cstart, cursize); | 609 if (seqcount > 1) { 610 cluster_wbuild_wb(vp, 611 lblocksize, vp->v_cstart, 612 cursize); 613 } |
597 } else { 598 /* 599 * Succeeded, keep building cluster. 600 */ 601 for (bpp = buflist->bs_children; 602 bpp <= endbp; bpp++) 603 bdwrite(*bpp); 604 free(buflist, M_SEGMENT); --- 25 unchanged lines hidden (view full) --- 630 vp->v_cstart = lbn + 1; 631 bawrite(bp); 632 } else { /* Wait for rest of cluster */ 633 vp->v_cstart = lbn; 634 bdwrite(bp); 635 } 636 } else if (lbn == vp->v_cstart + vp->v_clen) { 637 /* | 614 } else { 615 /* 616 * Succeeded, keep building cluster. 617 */ 618 for (bpp = buflist->bs_children; 619 bpp <= endbp; bpp++) 620 bdwrite(*bpp); 621 free(buflist, M_SEGMENT); --- 25 unchanged lines hidden (view full) --- 647 vp->v_cstart = lbn + 1; 648 bawrite(bp); 649 } else { /* Wait for rest of cluster */ 650 vp->v_cstart = lbn; 651 bdwrite(bp); 652 } 653 } else if (lbn == vp->v_cstart + vp->v_clen) { 654 /* |
638 * At end of cluster, write it out. | 655 * At end of cluster, write it out if seqcount tells us we 656 * are operating sequentially, otherwise let the buf or 657 * update daemon handle it. |
639 */ 640 bdwrite(bp); | 658 */ 659 bdwrite(bp); |
641 cluster_wbuild_wb(vp, lblocksize, vp->v_cstart, vp->v_clen + 1); | 660 if (seqcount > 1) 661 cluster_wbuild_wb(vp, lblocksize, vp->v_cstart, vp->v_clen + 1); |
642 vp->v_clen = 0; 643 vp->v_cstart = lbn + 1; | 662 vp->v_clen = 0; 663 vp->v_cstart = lbn + 1; |
644 } else | 664 } else { |
645 /* 646 * In the middle of a cluster, so just delay the I/O for now. 647 */ 648 bdwrite(bp); | 665 /* 666 * In the middle of a cluster, so just delay the I/O for now. 667 */ 668 bdwrite(bp); |
669 } |
|
649 vp->v_lastw = lbn; 650 vp->v_lasta = bp->b_blkno; 651} 652 653 654/* 655 * This is an awful lot like cluster_rbuild...wish they could be combined. 656 * The last lbn argument is the current block on which I/O is being --- 223 unchanged lines hidden --- | 670 vp->v_lastw = lbn; 671 vp->v_lasta = bp->b_blkno; 672} 673 674 675/* 676 * This is an awful lot like cluster_rbuild...wish they could be combined. 677 * The last lbn argument is the current block on which I/O is being --- 223 unchanged lines hidden --- |