vfs_cluster.c (47967) | vfs_cluster.c (48225) |
---|---|
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.82 1999/06/16 15:54:30 dg Exp $ | 36 * $Id: vfs_cluster.c,v 1.83 1999/06/17 01:25:25 julian Exp $ |
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> --- 89 unchanged lines hidden (view full) --- 134 bp->b_flags &= ~B_RAM; 135 /* 136 * We do the spl here so that there is no window 137 * between the incore and the b_usecount increment 138 * below. We opt to keep the spl out of the loop 139 * for efficiency. 140 */ 141 s = splbio(); | 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> --- 89 unchanged lines hidden (view full) --- 134 bp->b_flags &= ~B_RAM; 135 /* 136 * We do the spl here so that there is no window 137 * between the incore and the b_usecount increment 138 * below. We opt to keep the spl out of the loop 139 * for efficiency. 140 */ 141 s = splbio(); |
142 for(i=1;i<maxra;i++) { | 142 for (i = 1; i < maxra; i++) { |
143 144 if (!(tbp = incore(vp, lblkno+i))) { 145 break; 146 } 147 148 /* 149 * Set another read-ahead mark so we know to check 150 * again. 151 */ 152 if (((i % racluster) == (racluster - 1)) || 153 (i == (maxra - 1))) 154 tbp->b_flags |= B_RAM; 155 156 if ((tbp->b_usecount < 1) && | 143 144 if (!(tbp = incore(vp, lblkno+i))) { 145 break; 146 } 147 148 /* 149 * Set another read-ahead mark so we know to check 150 * again. 151 */ 152 if (((i % racluster) == (racluster - 1)) || 153 (i == (maxra - 1))) 154 tbp->b_flags |= B_RAM; 155 156 if ((tbp->b_usecount < 1) && |
157 ((tbp->b_flags & B_BUSY) == 0) && | 157 BUF_REFCNT(tbp) == 0 && |
158 (tbp->b_qindex == QUEUE_LRU)) { 159 TAILQ_REMOVE(&bufqueues[QUEUE_LRU], tbp, b_freelist); 160 TAILQ_INSERT_TAIL(&bufqueues[QUEUE_LRU], tbp, b_freelist); 161 } 162 } 163 splx(s); 164 if (i >= maxra) { 165 return 0; --- 81 unchanged lines hidden (view full) --- 247#if defined(CLUSTERDEBUG) 248 if (rcluster) 249 printf("S(%ld,%ld,%d) ", 250 (long)bp->b_lblkno, bp->b_bcount, seqcount); 251#endif 252 if ((bp->b_flags & B_CLUSTER) == 0) 253 vfs_busy_pages(bp, 0); 254 bp->b_flags &= ~(B_ERROR|B_INVAL); | 158 (tbp->b_qindex == QUEUE_LRU)) { 159 TAILQ_REMOVE(&bufqueues[QUEUE_LRU], tbp, b_freelist); 160 TAILQ_INSERT_TAIL(&bufqueues[QUEUE_LRU], tbp, b_freelist); 161 } 162 } 163 splx(s); 164 if (i >= maxra) { 165 return 0; --- 81 unchanged lines hidden (view full) --- 247#if defined(CLUSTERDEBUG) 248 if (rcluster) 249 printf("S(%ld,%ld,%d) ", 250 (long)bp->b_lblkno, bp->b_bcount, seqcount); 251#endif 252 if ((bp->b_flags & B_CLUSTER) == 0) 253 vfs_busy_pages(bp, 0); 254 bp->b_flags &= ~(B_ERROR|B_INVAL); |
255 BUF_KERNPROC(bp); |
|
255 error = VOP_STRATEGY(vp, bp); 256 curproc->p_stats->p_ru.ru_inblock++; 257 } 258 259 /* 260 * and if we have read-aheads, do them too 261 */ 262 if (rbp) { --- 17 unchanged lines hidden (view full) --- 280 (long)(rbp->b_lblkno - origblkno), 281 seqcount); 282 } 283#endif 284 285 if ((rbp->b_flags & B_CLUSTER) == 0) 286 vfs_busy_pages(rbp, 0); 287 rbp->b_flags &= ~(B_ERROR|B_INVAL); | 256 error = VOP_STRATEGY(vp, bp); 257 curproc->p_stats->p_ru.ru_inblock++; 258 } 259 260 /* 261 * and if we have read-aheads, do them too 262 */ 263 if (rbp) { --- 17 unchanged lines hidden (view full) --- 281 (long)(rbp->b_lblkno - origblkno), 282 seqcount); 283 } 284#endif 285 286 if ((rbp->b_flags & B_CLUSTER) == 0) 287 vfs_busy_pages(rbp, 0); 288 rbp->b_flags &= ~(B_ERROR|B_INVAL); |
289 BUF_KERNPROC(rbp); |
|
288 (void) VOP_STRATEGY(vp, rbp); 289 curproc->p_stats->p_ru.ru_inblock++; 290 } 291 } 292 if (reqbp) 293 return (biowait(reqbp)); 294 else 295 return (error); --- 45 unchanged lines hidden (view full) --- 341 return tbp; 342 343 bp = trypbuf(&cluster_pbuf_freecnt); 344 if (bp == 0) 345 return tbp; 346 347 bp->b_data = (char *)((vm_offset_t)bp->b_data | 348 ((vm_offset_t)tbp->b_data & PAGE_MASK)); | 290 (void) VOP_STRATEGY(vp, rbp); 291 curproc->p_stats->p_ru.ru_inblock++; 292 } 293 } 294 if (reqbp) 295 return (biowait(reqbp)); 296 else 297 return (error); --- 45 unchanged lines hidden (view full) --- 343 return tbp; 344 345 bp = trypbuf(&cluster_pbuf_freecnt); 346 if (bp == 0) 347 return tbp; 348 349 bp->b_data = (char *)((vm_offset_t)bp->b_data | 350 ((vm_offset_t)tbp->b_data & PAGE_MASK)); |
349 bp->b_flags = B_ASYNC | B_READ | B_CALL | B_BUSY | B_CLUSTER | B_VMIO; | 351 bp->b_flags = B_ASYNC | B_READ | B_CALL | B_CLUSTER | B_VMIO; |
350 bp->b_iodone = cluster_callback; 351 bp->b_blkno = blkno; 352 bp->b_lblkno = lbn; 353 bp->b_offset = tbp->b_offset; 354 KASSERT(bp->b_offset != NOOFFSET, ("cluster_rbuild: no buffer offset")); 355 pbgetvp(vp, bp); 356 357 TAILQ_INIT(&bp->b_cluster.cluster_head); --- 7 unchanged lines hidden (view full) --- 365 inc = btodb(size); 366 for (bn = blkno, i = 0; i < run; ++i, bn += inc) { 367 if (i != 0) { 368 if ((bp->b_npages * PAGE_SIZE) + 369 round_page(size) > vp->v_maxio) 370 break; 371 372 if ((tbp = incore(vp, lbn + i)) != NULL) { | 352 bp->b_iodone = cluster_callback; 353 bp->b_blkno = blkno; 354 bp->b_lblkno = lbn; 355 bp->b_offset = tbp->b_offset; 356 KASSERT(bp->b_offset != NOOFFSET, ("cluster_rbuild: no buffer offset")); 357 pbgetvp(vp, bp); 358 359 TAILQ_INIT(&bp->b_cluster.cluster_head); --- 7 unchanged lines hidden (view full) --- 367 inc = btodb(size); 368 for (bn = blkno, i = 0; i < run; ++i, bn += inc) { 369 if (i != 0) { 370 if ((bp->b_npages * PAGE_SIZE) + 371 round_page(size) > vp->v_maxio) 372 break; 373 374 if ((tbp = incore(vp, lbn + i)) != NULL) { |
373 if (tbp->b_flags & B_BUSY) | 375 if (BUF_LOCK(tbp, LK_EXCLUSIVE | LK_NOWAIT)) |
374 break; | 376 break; |
377 BUF_UNLOCK(tbp); |
|
375 376 for (j = 0; j < tbp->b_npages; j++) 377 if (tbp->b_pages[j]->valid) 378 break; 379 380 if (j != tbp->b_npages) 381 break; 382 --- 250 unchanged lines hidden (view full) --- 633 int totalwritten = 0; 634 int dbsize = btodb(size); 635 636 if (vp->v_maxio == 0) 637 vp->v_maxio = DFLTPHYS; 638 while (len > 0) { 639 s = splbio(); 640 if (((tbp = gbincore(vp, start_lbn)) == NULL) || | 378 379 for (j = 0; j < tbp->b_npages; j++) 380 if (tbp->b_pages[j]->valid) 381 break; 382 383 if (j != tbp->b_npages) 384 break; 385 --- 250 unchanged lines hidden (view full) --- 636 int totalwritten = 0; 637 int dbsize = btodb(size); 638 639 if (vp->v_maxio == 0) 640 vp->v_maxio = DFLTPHYS; 641 while (len > 0) { 642 s = splbio(); 643 if (((tbp = gbincore(vp, start_lbn)) == NULL) || |
641 ((tbp->b_flags & (B_INVAL|B_BUSY|B_DELWRI)) != B_DELWRI)) { | 644 ((tbp->b_flags & (B_INVAL | B_DELWRI)) != B_DELWRI) || 645 BUF_LOCK(tbp, LK_EXCLUSIVE | LK_NOWAIT)) { |
642 ++start_lbn; 643 --len; 644 splx(s); 645 continue; 646 } 647 bremfree(tbp); | 646 ++start_lbn; 647 --len; 648 splx(s); 649 continue; 650 } 651 bremfree(tbp); |
648 tbp->b_flags |= B_BUSY; | |
649 tbp->b_flags &= ~B_DONE; 650 splx(s); 651 652 /* 653 * Extra memory in the buffer, punt on this buffer. 654 * XXX we could handle this in most cases, but we would 655 * have to push the extra memory down to after our max 656 * possible cluster size and then potentially pull it back --- 25 unchanged lines hidden (view full) --- 682 crhold(bp->b_wcred); 683 } 684 685 bp->b_blkno = tbp->b_blkno; 686 bp->b_lblkno = tbp->b_lblkno; 687 bp->b_offset = tbp->b_offset; 688 bp->b_data = (char *)((vm_offset_t)bp->b_data | 689 ((vm_offset_t)tbp->b_data & PAGE_MASK)); | 652 tbp->b_flags &= ~B_DONE; 653 splx(s); 654 655 /* 656 * Extra memory in the buffer, punt on this buffer. 657 * XXX we could handle this in most cases, but we would 658 * have to push the extra memory down to after our max 659 * possible cluster size and then potentially pull it back --- 25 unchanged lines hidden (view full) --- 685 crhold(bp->b_wcred); 686 } 687 688 bp->b_blkno = tbp->b_blkno; 689 bp->b_lblkno = tbp->b_lblkno; 690 bp->b_offset = tbp->b_offset; 691 bp->b_data = (char *)((vm_offset_t)bp->b_data | 692 ((vm_offset_t)tbp->b_data & PAGE_MASK)); |
690 bp->b_flags |= B_CALL | B_BUSY | B_CLUSTER | | 693 bp->b_flags |= B_CALL | B_CLUSTER | |
691 (tbp->b_flags & (B_VMIO | B_NEEDCOMMIT)); 692 bp->b_iodone = cluster_callback; 693 pbgetvp(vp, bp); 694 /* 695 * From this location in the file, scan forward to see 696 * if there are buffers with adjacent data that need to 697 * be written as well. 698 */ --- 8 unchanged lines hidden (view full) --- 707 splx(s); 708 break; 709 } 710 711 /* 712 * If it IS in core, but has different 713 * characteristics, don't cluster with it. 714 */ | 694 (tbp->b_flags & (B_VMIO | B_NEEDCOMMIT)); 695 bp->b_iodone = cluster_callback; 696 pbgetvp(vp, bp); 697 /* 698 * From this location in the file, scan forward to see 699 * if there are buffers with adjacent data that need to 700 * be written as well. 701 */ --- 8 unchanged lines hidden (view full) --- 710 splx(s); 711 break; 712 } 713 714 /* 715 * If it IS in core, but has different 716 * characteristics, don't cluster with it. 717 */ |
715 if ((tbp->b_flags & 716 (B_VMIO | B_CLUSTEROK | B_INVAL | B_BUSY | 717 B_DELWRI | B_NEEDCOMMIT)) | 718 if ((tbp->b_flags & (B_VMIO | B_CLUSTEROK | 719 B_INVAL | B_DELWRI | B_NEEDCOMMIT)) |
718 != (B_DELWRI | B_CLUSTEROK | | 720 != (B_DELWRI | B_CLUSTEROK | |
719 (bp->b_flags & (B_VMIO | B_NEEDCOMMIT)))) { | 721 (bp->b_flags & (B_VMIO | B_NEEDCOMMIT))) || 722 tbp->b_wcred != bp->b_wcred || 723 BUF_LOCK(tbp, LK_EXCLUSIVE | LK_NOWAIT)) { |
720 splx(s); 721 break; 722 } 723 | 724 splx(s); 725 break; 726 } 727 |
724 if (tbp->b_wcred != bp->b_wcred) { 725 splx(s); 726 break; 727 } 728 | |
729 /* 730 * Check that the combined cluster 731 * would make sense with regard to pages 732 * and would not be too large 733 */ 734 if ((tbp->b_bcount != size) || 735 ((bp->b_blkno + (dbsize * i)) != 736 tbp->b_blkno) || 737 ((tbp->b_npages + bp->b_npages) > 738 (vp->v_maxio / PAGE_SIZE))) { | 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)) != 735 tbp->b_blkno) || 736 ((tbp->b_npages + bp->b_npages) > 737 (vp->v_maxio / PAGE_SIZE))) { |
738 BUF_UNLOCK(tbp); |
|
739 splx(s); 740 break; 741 } 742 /* 743 * Ok, it's passed all the tests, 744 * so remove it from the free list 745 * and mark it busy. We will use it. 746 */ 747 bremfree(tbp); | 739 splx(s); 740 break; 741 } 742 /* 743 * Ok, it's passed all the tests, 744 * so remove it from the free list 745 * and mark it busy. We will use it. 746 */ 747 bremfree(tbp); |
748 tbp->b_flags |= B_BUSY; | |
749 tbp->b_flags &= ~B_DONE; 750 splx(s); 751 } /* end of code for non-first buffers only */ 752 /* check for latent dependencies to be handled */ 753 if ((LIST_FIRST(&tbp->b_dep)) != NULL && 754 bioops.io_start) 755 (*bioops.io_start)(tbp); 756 /* --- 89 unchanged lines hidden --- | 748 tbp->b_flags &= ~B_DONE; 749 splx(s); 750 } /* end of code for non-first buffers only */ 751 /* check for latent dependencies to be handled */ 752 if ((LIST_FIRST(&tbp->b_dep)) != NULL && 753 bioops.io_start) 754 (*bioops.io_start)(tbp); 755 /* --- 89 unchanged lines hidden --- |