When the Dynamic Buffer Cache has been introduced bread_cluster()
became the replacement of cluster_read().  However this function,
currently used by ffs_read() only, does not consider the B_CACHE
flag of the first buffer of a cluster like its predecessor did.

This basically mean that the kernel might ends up fetching the
same block(s) multiple times if bread_cluster() is used to read
sequential blocks.

The simplest change to improve this situation is to not perform
any read-ahead when the first block has been found in the cache.

This change allows me to read files on cheap USB sticks with a
MSDOSFS using bread_cluster() (see next diff) as fast as doing
physio(9).

Index: kern/vfs_bio.c
===================================================================
RCS file: /cvs/src/sys/kern/vfs_bio.c,v
retrieving revision 1.171
diff -u -p -r1.171 vfs_bio.c
--- kern/vfs_bio.c      28 Nov 2015 21:52:02 -0000      1.171
+++ kern/vfs_bio.c      3 Jan 2016 19:07:26 -0000
@@ -461,13 +461,19 @@ bread_cluster(struct vnode *vp, daddr_t 
 
        *rbpp = bio_doread(vp, blkno, size, 0);
 
+       /*
+        * If the buffer is in the cache skip any I/O operation.
+        */
+       if (ISSET((*rbpp)->b_flags, B_CACHE))
+               goto out;
+
        if (size != round_page(size))
                goto out;
 
        if (VOP_BMAP(vp, blkno + 1, NULL, &sblkno, &maxra))
                goto out;
 
-       maxra++; 
+       maxra++;
        if (sblkno == -1 || maxra < 2)
                goto out;
 

Reply via email to