vfs_cluster.c (34630) | vfs_cluster.c (34694) |
---|---|
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 * $Id: vfs_cluster.c,v 1.58 1998/03/16 01:55:24 dyson Exp $ | 36 * $Id: vfs_cluster.c,v 1.59 1998/03/16 18:39:41 julian Exp $ |
37 */ 38 39#include "opt_debug_cluster.h" 40 41#include <sys/param.h> 42#include <sys/systm.h> 43#include <sys/proc.h> 44#include <sys/buf.h> --- 100 unchanged lines hidden (view full) --- 145 /* 146 * Set another read-ahead mark so we know to check 147 * again. 148 */ 149 if (((i % racluster) == (racluster - 1)) || 150 (i == (maxra - 1))) 151 tbp->b_flags |= B_RAM; 152 | 37 */ 38 39#include "opt_debug_cluster.h" 40 41#include <sys/param.h> 42#include <sys/systm.h> 43#include <sys/proc.h> 44#include <sys/buf.h> --- 100 unchanged lines hidden (view full) --- 145 /* 146 * Set another read-ahead mark so we know to check 147 * again. 148 */ 149 if (((i % racluster) == (racluster - 1)) || 150 (i == (maxra - 1))) 151 tbp->b_flags |= B_RAM; 152 |
153 if ((tbp->b_usecount < 5) && | 153 if ((tbp->b_usecount < 1) && |
154 ((tbp->b_flags & B_BUSY) == 0) && 155 (tbp->b_qindex == QUEUE_LRU)) { 156 TAILQ_REMOVE(&bufqueues[QUEUE_LRU], tbp, b_freelist); 157 TAILQ_INSERT_TAIL(&bufqueues[QUEUE_LRU], tbp, b_freelist); 158 } 159 } 160 splx(s); 161 if (i >= maxra) { 162 return 0; 163 } 164 lblkno += i; 165 } 166 reqbp = bp = NULL; 167 } else { 168 off_t firstread; 169 firstread = bp->b_offset; | 154 ((tbp->b_flags & B_BUSY) == 0) && 155 (tbp->b_qindex == QUEUE_LRU)) { 156 TAILQ_REMOVE(&bufqueues[QUEUE_LRU], tbp, b_freelist); 157 TAILQ_INSERT_TAIL(&bufqueues[QUEUE_LRU], tbp, b_freelist); 158 } 159 } 160 splx(s); 161 if (i >= maxra) { 162 return 0; 163 } 164 lblkno += i; 165 } 166 reqbp = bp = NULL; 167 } else { 168 off_t firstread; 169 firstread = bp->b_offset; |
170#ifdef DIAGNOSTIC 171 if (bp->b_offset == NOOFFSET) 172 panic("cluster_read: no buffer offset"); 173#endif |
|
170 if (firstread + totread > filesize) 171 totread = filesize - firstread; 172 if (totread > size) { 173 int nblks = 0; 174 int ncontigafter; 175 while (totread > 0) { 176 nblks++; 177 totread -= size; --- 11 unchanged lines hidden (view full) --- 189 goto single_block_read; 190 if (ncontigafter == 0) 191 goto single_block_read; 192 if (ncontigafter + 1 < nblks) 193 nblks = ncontigafter + 1; 194 195 bp = cluster_rbuild(vp, filesize, lblkno, 196 blkno, size, nblks, bp); | 174 if (firstread + totread > filesize) 175 totread = filesize - firstread; 176 if (totread > size) { 177 int nblks = 0; 178 int ncontigafter; 179 while (totread > 0) { 180 nblks++; 181 totread -= size; --- 11 unchanged lines hidden (view full) --- 193 goto single_block_read; 194 if (ncontigafter == 0) 195 goto single_block_read; 196 if (ncontigafter + 1 < nblks) 197 nblks = ncontigafter + 1; 198 199 bp = cluster_rbuild(vp, filesize, lblkno, 200 blkno, size, nblks, bp); |
197 lblkno += nblks; | 201 lblkno += (bp->b_bufsize / size); |
198 } else { 199single_block_read: 200 /* 201 * if it isn't in the cache, then get a chunk from 202 * disk if sequential, otherwise just get the block. 203 */ 204 bp->b_flags |= B_READ | B_RAM; 205 lblkno += 1; --- 137 unchanged lines hidden (view full) --- 343 return tbp; 344 345 (vm_offset_t) bp->b_data |= ((vm_offset_t) tbp->b_data) & PAGE_MASK; 346 bp->b_flags = B_ASYNC | B_READ | B_CALL | B_BUSY | B_CLUSTER | B_VMIO; 347 bp->b_iodone = cluster_callback; 348 bp->b_blkno = blkno; 349 bp->b_lblkno = lbn; 350 bp->b_offset = tbp->b_offset; | 202 } else { 203single_block_read: 204 /* 205 * if it isn't in the cache, then get a chunk from 206 * disk if sequential, otherwise just get the block. 207 */ 208 bp->b_flags |= B_READ | B_RAM; 209 lblkno += 1; --- 137 unchanged lines hidden (view full) --- 347 return tbp; 348 349 (vm_offset_t) bp->b_data |= ((vm_offset_t) tbp->b_data) & PAGE_MASK; 350 bp->b_flags = B_ASYNC | B_READ | B_CALL | B_BUSY | B_CLUSTER | B_VMIO; 351 bp->b_iodone = cluster_callback; 352 bp->b_blkno = blkno; 353 bp->b_lblkno = lbn; 354 bp->b_offset = tbp->b_offset; |
355#ifdef DIAGNOSTIC 356 if (bp->b_offset == NOOFFSET) 357 panic("cluster_rbuild: no buffer offset"); 358#endif |
|
351 pbgetvp(vp, bp); 352 353 TAILQ_INIT(&bp->b_cluster.cluster_head); 354 355 bp->b_bcount = 0; 356 bp->b_bufsize = 0; 357 bp->b_npages = 0; 358 --- 147 unchanged lines hidden (view full) --- 506 async = vp->v_mount->mnt_flag & MNT_ASYNC; 507 lblocksize = vp->v_mount->mnt_stat.f_iosize; 508 } else { 509 async = 0; 510 lblocksize = bp->b_bufsize; 511 } 512 lbn = bp->b_lblkno; 513 | 359 pbgetvp(vp, bp); 360 361 TAILQ_INIT(&bp->b_cluster.cluster_head); 362 363 bp->b_bcount = 0; 364 bp->b_bufsize = 0; 365 bp->b_npages = 0; 366 --- 147 unchanged lines hidden (view full) --- 514 async = vp->v_mount->mnt_flag & MNT_ASYNC; 515 lblocksize = vp->v_mount->mnt_stat.f_iosize; 516 } else { 517 async = 0; 518 lblocksize = bp->b_bufsize; 519 } 520 lbn = bp->b_lblkno; 521 |
522#ifdef DIAGNOSTIC 523 if (bp->b_offset == NOOFFSET) 524 panic("cluster_write: no buffer offset"); 525#endif 526 |
|
514 /* Initialize vnode to beginning of file. */ 515 if (lbn == 0) 516 vp->v_lasta = vp->v_clen = vp->v_cstart = vp->v_lastw = 0; 517 518 if (vp->v_clen == 0 || lbn != vp->v_lastw + 1 || 519 (bp->b_blkno != vp->v_lasta + btodb(lblocksize))) { 520 maxclen = vp->v_maxio / lblocksize - 1; 521 if (vp->v_clen != 0) { --- 160 unchanged lines hidden (view full) --- 682 } 683 684 bp->b_blkno = tbp->b_blkno; 685 bp->b_lblkno = tbp->b_lblkno; 686 bp->b_offset = tbp->b_offset; 687 (vm_offset_t) bp->b_data |= 688 ((vm_offset_t) tbp->b_data) & PAGE_MASK; 689 bp->b_flags |= B_CALL | B_BUSY | B_CLUSTER | | 527 /* Initialize vnode to beginning of file. */ 528 if (lbn == 0) 529 vp->v_lasta = vp->v_clen = vp->v_cstart = vp->v_lastw = 0; 530 531 if (vp->v_clen == 0 || lbn != vp->v_lastw + 1 || 532 (bp->b_blkno != vp->v_lasta + btodb(lblocksize))) { 533 maxclen = vp->v_maxio / lblocksize - 1; 534 if (vp->v_clen != 0) { --- 160 unchanged lines hidden (view full) --- 695 } 696 697 bp->b_blkno = tbp->b_blkno; 698 bp->b_lblkno = tbp->b_lblkno; 699 bp->b_offset = tbp->b_offset; 700 (vm_offset_t) bp->b_data |= 701 ((vm_offset_t) tbp->b_data) & PAGE_MASK; 702 bp->b_flags |= B_CALL | B_BUSY | B_CLUSTER | |
690 (tbp->b_flags & (B_VMIO|B_NEEDCOMMIT)); | 703 (tbp->b_flags & (B_VMIO | B_NEEDCOMMIT)); |
691 bp->b_iodone = cluster_callback; 692 pbgetvp(vp, bp); 693 /* 694 * From this location in the file, scan forward to see 695 * if there are buffers with adjacent data that need to 696 * be written as well. 697 */ 698 for (i = 0; i < len; ++i, ++start_lbn) { --- 8 unchanged lines hidden (view full) --- 707 break; 708 } 709 710 /* 711 * If it IS in core, but has different 712 * characteristics, don't cluster with it. 713 */ 714 if ((tbp->b_flags & | 704 bp->b_iodone = cluster_callback; 705 pbgetvp(vp, bp); 706 /* 707 * From this location in the file, scan forward to see 708 * if there are buffers with adjacent data that need to 709 * be written as well. 710 */ 711 for (i = 0; i < len; ++i, ++start_lbn) { --- 8 unchanged lines hidden (view full) --- 720 break; 721 } 722 723 /* 724 * If it IS in core, but has different 725 * characteristics, don't cluster with it. 726 */ 727 if ((tbp->b_flags & |
715 (B_VMIO|B_CLUSTEROK|B_INVAL|B_BUSY| 716 B_DELWRI|B_NEEDCOMMIT)) 717 != (B_DELWRI|B_CLUSTEROK| 718 (bp->b_flags & (B_VMIO|B_NEEDCOMMIT)))) { | 728 (B_VMIO | B_CLUSTEROK | B_INVAL | B_BUSY | 729 B_DELWRI | B_NEEDCOMMIT)) 730 != (B_DELWRI | B_CLUSTEROK | 731 (bp->b_flags & (B_VMIO | B_NEEDCOMMIT)))) { |
719 splx(s); 720 break; 721 } 722 723 if (tbp->b_wcred != bp->b_wcred) { 724 splx(s); 725 break; 726 } 727 728 /* 729 * Check that the combined cluster 730 * would make sense with regard to pages 731 * and would not be too large 732 */ 733 if ((tbp->b_bcount != size) || 734 ((bp->b_blkno + (dbsize * i)) != | 732 splx(s); 733 break; 734 } 735 736 if (tbp->b_wcred != bp->b_wcred) { 737 splx(s); 738 break; 739 } 740 741 /* 742 * Check that the combined cluster 743 * would make sense with regard to pages 744 * and would not be too large 745 */ 746 if ((tbp->b_bcount != size) || 747 ((bp->b_blkno + (dbsize * i)) != |
735 (tbp->b_blkno)) || | 748 tbp->b_blkno) || |
736 ((tbp->b_npages + bp->b_npages) > 737 (vp->v_maxio / PAGE_SIZE))) { 738 splx(s); 739 break; 740 } 741 /* 742 * Ok, it's passed all the tests, 743 * so remove it from the free list --- 35 unchanged lines hidden (view full) --- 779 } 780 } 781 bp->b_bcount += size; 782 bp->b_bufsize += size; 783 784 --numdirtybuffers; 785 tbp->b_flags &= ~(B_READ | B_DONE | B_ERROR | B_DELWRI); 786 tbp->b_flags |= B_ASYNC; | 749 ((tbp->b_npages + bp->b_npages) > 750 (vp->v_maxio / PAGE_SIZE))) { 751 splx(s); 752 break; 753 } 754 /* 755 * Ok, it's passed all the tests, 756 * so remove it from the free list --- 35 unchanged lines hidden (view full) --- 792 } 793 } 794 bp->b_bcount += size; 795 bp->b_bufsize += size; 796 797 --numdirtybuffers; 798 tbp->b_flags &= ~(B_READ | B_DONE | B_ERROR | B_DELWRI); 799 tbp->b_flags |= B_ASYNC; |
787 s = splbio(); | |
788 reassignbuf(tbp, tbp->b_vp); /* put on clean list */ 789 ++tbp->b_vp->v_numoutput; | 800 reassignbuf(tbp, tbp->b_vp); /* put on clean list */ 801 ++tbp->b_vp->v_numoutput; |
790 splx(s); | |
791 TAILQ_INSERT_TAIL(&bp->b_cluster.cluster_head, 792 tbp, b_cluster.cluster_entry); 793 } 794 finishcluster: 795 pmap_qenter(trunc_page((vm_offset_t) bp->b_data), 796 (vm_page_t *) bp->b_pages, bp->b_npages); 797 if (bp->b_bufsize > bp->b_kvasize) 798 panic("cluster_wbuild: b_bufsize(%d) > b_kvasize(%d)\n", --- 39 unchanged lines hidden --- | 802 TAILQ_INSERT_TAIL(&bp->b_cluster.cluster_head, 803 tbp, b_cluster.cluster_entry); 804 } 805 finishcluster: 806 pmap_qenter(trunc_page((vm_offset_t) bp->b_data), 807 (vm_page_t *) bp->b_pages, bp->b_npages); 808 if (bp->b_bufsize > bp->b_kvasize) 809 panic("cluster_wbuild: b_bufsize(%d) > b_kvasize(%d)\n", --- 39 unchanged lines hidden --- |