summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/kern/vfs_vnops.c33
1 files changed, 20 insertions, 13 deletions
diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c
index c7df6ad..4826b08 100644
--- a/sys/kern/vfs_vnops.c
+++ b/sys/kern/vfs_vnops.c
@@ -298,35 +298,42 @@ vn_close(vp, flags, file_cred, td)
}
/*
- * Sequential heuristic - detect sequential operation
+ * Heuristic to detect sequential operation.
*/
-static __inline
-int
+static int
sequential_heuristic(struct uio *uio, struct file *fp)
{
+ /*
+ * Offset 0 is handled specially. open() sets f_seqcount to 1 so
+ * that the first I/O is normally considered to be slightly
+ * sequential. Seeking to offset 0 doesn't change sequentiality
+ * unless previous seeks have reduced f_seqcount to 0, in which
+ * case offset 0 is not special.
+ */
if ((uio->uio_offset == 0 && fp->f_seqcount > 0) ||
uio->uio_offset == fp->f_nextoff) {
/*
- * XXX we assume that the filesystem block size is
- * the default. Not true, but still gives us a pretty
- * good indicator of how sequential the read operations
- * are.
+ * f_seqcount is in units of fixed-size blocks so that it
+ * depends mainly on the amount of sequential I/O and not
+ * much on the number of sequential I/O's. The fixed size
+ * of 16384 is hard-coded here since it is (not quite) just
+ * a magic size that works well here. This size is more
+ * closely related to the best I/O size for real disks than
+ * to any block size used by software.
*/
- fp->f_seqcount += (uio->uio_resid + BKVASIZE - 1) / BKVASIZE;
+ fp->f_seqcount += howmany(uio->uio_resid, 16384);
if (fp->f_seqcount > IO_SEQMAX)
fp->f_seqcount = IO_SEQMAX;
- return(fp->f_seqcount << IO_SEQSHIFT);
+ return (fp->f_seqcount << IO_SEQSHIFT);
}
- /*
- * Not sequential, quick draw-down of seqcount
- */
+ /* Not sequential. Quickly draw-down sequentiality. */
if (fp->f_seqcount > 1)
fp->f_seqcount = 1;
else
fp->f_seqcount = 0;
- return(0);
+ return (0);
}
/*
OpenPOWER on IntegriCloud