diff options
Diffstat (limited to 'sys/kern/vfs_cluster.c')
-rw-r--r-- | sys/kern/vfs_cluster.c | 66 |
1 files changed, 38 insertions, 28 deletions
diff --git a/sys/kern/vfs_cluster.c b/sys/kern/vfs_cluster.c index c34fbc3..e01d24f 100644 --- a/sys/kern/vfs_cluster.c +++ b/sys/kern/vfs_cluster.c @@ -30,7 +30,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)vfs_cluster.c 8.7 (Berkeley) 2/13/94 + * @(#)vfs_cluster.c 8.10 (Berkeley) 3/28/95 */ #include <sys/param.h> @@ -43,16 +43,6 @@ #include <sys/resourcevar.h> #include <libkern/libkern.h> -#ifdef DEBUG -#include <vm/vm.h> -#include <sys/sysctl.h> -int doreallocblks = 1; -struct ctldebug debug13 = { "doreallocblks", &doreallocblks }; -#else -/* XXX for cluster_write */ -#define doreallocblks 1 -#endif - /* * Local declarations */ @@ -135,7 +125,7 @@ cluster_read(vp, filesize, lblkno, size, cred, bpp) trace(TR_BREADHIT, pack(vp, size), lblkno); flags |= B_ASYNC; ioblkno = lblkno + (vp->v_ralen ? vp->v_ralen : 1); - alreadyincore = (int)incore(vp, ioblkno); + alreadyincore = incore(vp, ioblkno) != NULL; bp = NULL; } else { /* Block wasn't in cache, case 3, 4, 5. */ @@ -202,10 +192,12 @@ cluster_read(vp, filesize, lblkno, size, cred, bpp) ioblkno, NULL, &blkno, &num_ra)) || blkno == -1) goto skip_readahead; /* - * Adjust readahead as above + * Adjust readahead as above. + * Don't check alreadyincore, we know it is 0 from + * the previous conditional. */ if (num_ra) { - if (!alreadyincore && ioblkno <= vp->v_maxra) + if (ioblkno <= vp->v_maxra) vp->v_ralen = max(vp->v_ralen >> 1, 1); else if (num_ra > vp->v_ralen && lblkno != vp->v_lastr) @@ -318,17 +310,12 @@ cluster_rbuild(vp, filesize, bp, lbn, blkno, size, run, flags) inc = btodb(size); for (bn = blkno + inc, i = 1; i <= run; ++i, bn += inc) { - if (incore(vp, lbn + i)) { - if (i == 1) { - bp->b_saveaddr = b_save->bs_saveaddr; - bp->b_flags &= ~B_CALL; - bp->b_iodone = NULL; - allocbuf(bp, size); - free(b_save, M_SEGMENT); - } else - allocbuf(bp, size * i); + /* + * A component of the cluster is already in core, + * terminate the cluster early. + */ + if (incore(vp, lbn + i)) break; - } tbp = getblk(vp, lbn + i, 0, 0, 0); /* * getblk may return some memory in the buffer if there were @@ -341,8 +328,18 @@ cluster_rbuild(vp, filesize, bp, lbn, blkno, size, run, flags) if (tbp->b_bufsize != 0) { caddr_t bdata = (char *)tbp->b_data; - if (tbp->b_bufsize + size > MAXBSIZE) - panic("cluster_rbuild: too much memory"); + /* + * No room in the buffer to add another page, + * terminate the cluster early. + */ + if (tbp->b_bufsize + size > MAXBSIZE) { +#ifdef DIAGNOSTIC + if (tbp->b_bufsize != MAXBSIZE) + panic("cluster_rbuild: too much memory"); +#endif + brelse(tbp); + break; + } if (tbp->b_bufsize > size) { /* * XXX if the source and destination regions @@ -364,6 +361,20 @@ cluster_rbuild(vp, filesize, bp, lbn, blkno, size, run, flags) ++b_save->bs_nchildren; b_save->bs_children[i - 1] = tbp; } + /* + * The cluster may have been terminated early, adjust the cluster + * buffer size accordingly. If no cluster could be formed, + * deallocate the cluster save info. + */ + if (i <= run) { + if (i == 1) { + bp->b_saveaddr = b_save->bs_saveaddr; + bp->b_flags &= ~B_CALL; + bp->b_iodone = NULL; + free(b_save, M_SEGMENT); + } + allocbuf(bp, size * i); + } return(bp); } @@ -498,8 +509,7 @@ cluster_write(bp, filesize) * Otherwise try reallocating to make it sequential. */ cursize = vp->v_lastw - vp->v_cstart + 1; - if (!doreallocblks || - (lbn + 1) * bp->b_bcount != filesize || + if ((lbn + 1) * bp->b_bcount != filesize || lbn != vp->v_lastw + 1 || vp->v_clen <= cursize) { cluster_wbuild(vp, NULL, bp->b_bcount, vp->v_cstart, cursize, lbn); |