summaryrefslogtreecommitdiffstats
path: root/sys/kern/vfs_cluster.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/kern/vfs_cluster.c')
-rw-r--r--sys/kern/vfs_cluster.c66
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);
OpenPOWER on IntegriCloud