bread_cluster() can be called unconditionally. The sequential check is a leftover of the read-ahead mechanism that FFS no longer used since the introduction of the Dynamic Buffer cache.
ok? Index: ufs/ffs/ffs_vnops.c =================================================================== RCS file: /cvs/src/sys/ufs/ffs/ffs_vnops.c,v retrieving revision 1.80 diff -u -p -r1.80 ffs_vnops.c --- ufs/ffs/ffs_vnops.c 14 Mar 2015 03:38:52 -0000 1.80 +++ ufs/ffs/ffs_vnops.c 3 Jan 2016 21:42:22 -0000 @@ -242,14 +242,11 @@ ffs_read(void *v) if (lblktosize(fs, nextlbn) >= DIP(ip, size)) error = bread(vp, lbn, size, &bp); - else if (lbn - 1 == ip->i_ci.ci_lastr) { + else error = bread_cluster(vp, lbn, size, &bp); - } else - error = bread(vp, lbn, size, &bp); if (error) break; - ip->i_ci.ci_lastr = lbn; /* * We should only get non-zero b_resid when an I/O error