FFS: allow sendfile(2) to work with block sizes greater than the page size
Implement ffs_getpages_async(), which when possible calls the asynchronous flavor of the generic pager's getpages function. When the underlying block size is larger than the system page size, however, it will invoke the (synchronous) buffer cache pager, followed by a call to the client completion routine. This retains true asynchronous completion in the most common (block size <= page size) case, which is important for the performance of the new sendfile(2). The behavior in the larger block size case mirrors the default implementation of VOP_GETPAGES_ASYNC, which most other filesystems use anyway as they do not override the getpages_async method. PR: 235708 Reported by: pho Reviewed by: kib, glebius MFC after: 2 weeks Differential Revision: https://reviews.freebsd.org/D19340
This commit is contained in:
parent
40a5168449
commit
4775b07ebd
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=344562
@ -111,6 +111,7 @@ extern int ffs_rawread(struct vnode *vp, struct uio *uio, int *workdone);
|
||||
static vop_fdatasync_t ffs_fdatasync;
|
||||
static vop_fsync_t ffs_fsync;
|
||||
static vop_getpages_t ffs_getpages;
|
||||
static vop_getpages_async_t ffs_getpages_async;
|
||||
static vop_lock1_t ffs_lock;
|
||||
static vop_read_t ffs_read;
|
||||
static vop_write_t ffs_write;
|
||||
@ -132,7 +133,7 @@ struct vop_vector ffs_vnodeops1 = {
|
||||
.vop_fsync = ffs_fsync,
|
||||
.vop_fdatasync = ffs_fdatasync,
|
||||
.vop_getpages = ffs_getpages,
|
||||
.vop_getpages_async = vnode_pager_local_getpages_async,
|
||||
.vop_getpages_async = ffs_getpages_async,
|
||||
.vop_lock1 = ffs_lock,
|
||||
.vop_read = ffs_read,
|
||||
.vop_reallocblks = ffs_reallocblks,
|
||||
@ -154,7 +155,7 @@ struct vop_vector ffs_vnodeops2 = {
|
||||
.vop_fsync = ffs_fsync,
|
||||
.vop_fdatasync = ffs_fdatasync,
|
||||
.vop_getpages = ffs_getpages,
|
||||
.vop_getpages_async = vnode_pager_local_getpages_async,
|
||||
.vop_getpages_async = ffs_getpages_async,
|
||||
.vop_lock1 = ffs_lock,
|
||||
.vop_read = ffs_read,
|
||||
.vop_reallocblks = ffs_reallocblks,
|
||||
@ -1742,3 +1743,25 @@ ffs_getpages(struct vop_getpages_args *ap)
|
||||
return (vfs_bio_getpages(vp, ap->a_m, ap->a_count, ap->a_rbehind,
|
||||
ap->a_rahead, ffs_gbp_getblkno, ffs_gbp_getblksz));
|
||||
}
|
||||
|
||||
static int
|
||||
ffs_getpages_async(struct vop_getpages_async_args *ap)
|
||||
{
|
||||
struct vnode *vp;
|
||||
struct ufsmount *um;
|
||||
int error;
|
||||
|
||||
vp = ap->a_vp;
|
||||
um = VFSTOUFS(vp->v_mount);
|
||||
|
||||
if (um->um_devvp->v_bufobj.bo_bsize <= PAGE_SIZE)
|
||||
return (vnode_pager_generic_getpages(vp, ap->a_m, ap->a_count,
|
||||
ap->a_rbehind, ap->a_rahead, ap->a_iodone, ap->a_arg));
|
||||
|
||||
error = vfs_bio_getpages(vp, ap->a_m, ap->a_count, ap->a_rbehind,
|
||||
ap->a_rahead, ffs_gbp_getblkno, ffs_gbp_getblksz);
|
||||
ap->a_iodone(ap->a_arg, ap->a_m, ap->a_count, error);
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user