Index: sys/kern/vfs_vnops.c =================================================================== --- sys/kern/vfs_vnops.c +++ sys/kern/vfs_vnops.c @@ -3268,8 +3268,8 @@ outvp->v_mount->mnt_stat.f_iosize); if (blksize < 4096) blksize = 4096; - else if (blksize > 1024 * 1024) - blksize = 1024 * 1024; + else if (blksize > maxphys) + blksize = maxphys; dat = malloc(blksize, M_TEMP, M_WAITOK); /* @@ -3377,14 +3377,21 @@ error = 0; } - xfer = blksize; - if (cantseek) { + /* + * We only need to copy in chunks of size _PC_MIN_HOLE_SIZE if + * FIOSEEKDATA or FIOSEEKHOLE return an error and we are going + * to fall back on the "all bytes 0" method. + */ + if (__predict_false(cantseek)) { + xfer = blksize; /* * Set first xfer to end at a block boundary, so that * holes are more likely detected in the loop below via * the for all bytes 0 method. */ xfer -= (*inoffp % blksize); + } else { + xfer = maxphys; } /* Loop copying the data block. */ while (copylen > 0 && error == 0 && !eof && interrupted == 0) { @@ -3441,7 +3448,11 @@ } } } - xfer = blksize; + if (__predict_false(cantseek)) { + xfer = blksize; + } else { + xfer = maxphys; + } } } out: