In the author's words:
These diffs implement the first stage of a VOP_{GET|PUT}PAGES pushdown for local media FS's. See ffs_putpages in /sys/ufs/ufs/ufs_readwrite.c for implementation details for generic *_{get|put}pages for local media FS's. Support is trivial to add for any FS that formerly relied on the default behaviour of the vnode_pager in in EOPNOTSUPP cases (just copy the ffs_getpages() code for the FS in question's *_{get|put}pages). Obviously, it would be better if each local media FS implemented a more optimal method, instead of calling an exported interface from the /sys/vm/vnode_pager.c, but this is a necessary first step in getting the FS's to a point where they can be supplied with better implementations on a case-by-case basis. Obviously, the cd9660_putpages() can be rather trivial (since it is a read-only FS type 8-)). A slight (temporary) modification is made to print a diagnostic message in the case where the underlying filesystem attempts to engage in the previous behaviour. Failure is likely to be ungraceful. Submitted by: terry@freebsd.org (Terry Lambert)
This commit is contained in:
parent
f498eeeead
commit
ce75f2c365
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=33847
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)ffs_vnops.c 8.15 (Berkeley) 5/14/95
|
||||
* $Id: ffs_vnops.c,v 1.41 1998/02/04 22:33:33 eivind Exp $
|
||||
* $Id: ffs_vnops.c,v 1.42 1998/02/06 12:14:16 eivind Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -62,6 +62,7 @@
|
||||
|
||||
static int ffs_fsync __P((struct vop_fsync_args *));
|
||||
static int ffs_getpages __P((struct vop_getpages_args *));
|
||||
static int ffs_putpages __P((struct vop_putpages_args *));
|
||||
static int ffs_read __P((struct vop_read_args *));
|
||||
static int ffs_write __P((struct vop_write_args *));
|
||||
|
||||
@ -71,6 +72,7 @@ static struct vnodeopv_entry_desc ffs_vnodeop_entries[] = {
|
||||
{ &vop_default_desc, (vop_t *) ufs_vnoperate },
|
||||
{ &vop_fsync_desc, (vop_t *) ffs_fsync },
|
||||
{ &vop_getpages_desc, (vop_t *) ffs_getpages },
|
||||
{ &vop_putpages_desc, (vop_t *) ffs_putpages },
|
||||
{ &vop_read_desc, (vop_t *) ffs_read },
|
||||
{ &vop_reallocblks_desc, (vop_t *) ffs_reallocblks },
|
||||
{ &vop_write_desc, (vop_t *) ffs_write },
|
||||
|
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)ufs_readwrite.c 8.11 (Berkeley) 5/8/95
|
||||
* $Id: ufs_readwrite.c,v 1.41 1998/01/30 11:34:05 phk Exp $
|
||||
* $Id: ufs_readwrite.c,v 1.42 1998/02/05 03:32:33 dyson Exp $
|
||||
*/
|
||||
|
||||
#define BLKSIZE(a, b, c) blksize(a, b, c)
|
||||
@ -539,3 +539,17 @@ ffs_getpages(ap)
|
||||
|
||||
return (rtval);
|
||||
}
|
||||
|
||||
/*
|
||||
* put page routine
|
||||
*
|
||||
* XXX By default, wimp out... note that a_offset is ignored (and always
|
||||
* XXX has been).
|
||||
*/
|
||||
int
|
||||
ffs_putpages(ap)
|
||||
struct vop_putpages_args *ap;
|
||||
{
|
||||
return vnode_pager_generic_putpages(ap->a_vp, ap->a_m, ap->a_count,
|
||||
ap->a_sync, ap->a_rtvals);
|
||||
}
|
||||
|
@ -38,7 +38,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)vnode_pager.c 7.5 (Berkeley) 4/20/91
|
||||
* $Id: vnode_pager.c,v 1.85 1998/02/23 08:22:48 dyson Exp $
|
||||
* $Id: vnode_pager.c,v 1.86 1998/02/25 03:55:53 dyson Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -88,11 +88,6 @@ struct pagerops vnodepagerops = {
|
||||
NULL
|
||||
};
|
||||
|
||||
static int vnode_pager_leaf_getpages __P((vm_object_t object, vm_page_t *m,
|
||||
int count, int reqpage));
|
||||
static int vnode_pager_leaf_putpages __P((vm_object_t object, vm_page_t *m,
|
||||
int count, boolean_t sync,
|
||||
int *rtvals));
|
||||
|
||||
/*
|
||||
* Allocate (or lookup) pager for a vnode.
|
||||
@ -519,6 +514,14 @@ vnode_pager_input_old(object, m)
|
||||
* generic vnode pager input routine
|
||||
*/
|
||||
|
||||
/*
|
||||
* EOPNOTSUPP is no longer legal. For local media VFS's that do not
|
||||
* implement their own VOP_GETPAGES, their VOP_GETPAGES should call to
|
||||
* vnode_pager_generic_getpages() to implement the previous behaviour.
|
||||
*
|
||||
* All other FS's should use the bypass to get to the local media
|
||||
* backing vp's VOP_GETPAGES.
|
||||
*/
|
||||
static int
|
||||
vnode_pager_getpages(object, m, count, reqpage)
|
||||
vm_object_t object;
|
||||
@ -530,31 +533,43 @@ vnode_pager_getpages(object, m, count, reqpage)
|
||||
struct vnode *vp;
|
||||
|
||||
vp = object->handle;
|
||||
/*
|
||||
* XXX temporary diagnostic message to help track stale FS code,
|
||||
* Returning EOPNOTSUPP from here may make things unhappy.
|
||||
*/
|
||||
rtval = VOP_GETPAGES(vp, m, count*PAGE_SIZE, reqpage, 0);
|
||||
if (rtval == EOPNOTSUPP)
|
||||
return vnode_pager_leaf_getpages(object, m, count, reqpage);
|
||||
else
|
||||
return rtval;
|
||||
printf("vnode_pager: *** WARNING *** stale FS code in system.\n");
|
||||
return rtval;
|
||||
}
|
||||
|
||||
static int
|
||||
vnode_pager_leaf_getpages(object, m, count, reqpage)
|
||||
vm_object_t object;
|
||||
|
||||
/*
|
||||
* This is now called from local media FS's to operate against their
|
||||
* own vnodes if they fail to implement VOP_GETPAGES.
|
||||
*/
|
||||
int
|
||||
vnode_pager_generic_getpages(vp, m, bytecount, reqpage)
|
||||
struct vnode *vp;
|
||||
vm_page_t *m;
|
||||
int count;
|
||||
int bytecount;
|
||||
int reqpage;
|
||||
{
|
||||
vm_object_t object;
|
||||
vm_offset_t kva;
|
||||
off_t foff;
|
||||
int i, size, bsize, first, firstaddr;
|
||||
struct vnode *dp, *vp;
|
||||
struct vnode *dp;
|
||||
int runpg;
|
||||
int runend;
|
||||
struct buf *bp;
|
||||
int s;
|
||||
int count;
|
||||
int error = 0;
|
||||
|
||||
vp = object->handle;
|
||||
object = vp->v_object;
|
||||
count = bytecount / PAGE_SIZE;
|
||||
|
||||
if (vp->v_mount == NULL)
|
||||
return VM_PAGER_BAD;
|
||||
|
||||
@ -770,6 +785,14 @@ vnode_pager_leaf_getpages(object, m, count, reqpage)
|
||||
return (error ? VM_PAGER_ERROR : VM_PAGER_OK);
|
||||
}
|
||||
|
||||
/*
|
||||
* EOPNOTSUPP is no longer legal. For local media VFS's that do not
|
||||
* implement their own VOP_PUTPAGES, their VOP_PUTPAGES should call to
|
||||
* vnode_pager_generic_putpages() to implement the previous behaviour.
|
||||
*
|
||||
* All other FS's should use the bypass to get to the local media
|
||||
* backing vp's VOP_PUTPAGES.
|
||||
*/
|
||||
static int
|
||||
vnode_pager_putpages(object, m, count, sync, rtvals)
|
||||
vm_object_t object;
|
||||
@ -782,34 +805,35 @@ vnode_pager_putpages(object, m, count, sync, rtvals)
|
||||
struct vnode *vp;
|
||||
|
||||
vp = object->handle;
|
||||
rtval = VOP_PUTPAGES(vp, m, count*PAGE_SIZE, sync, rtvals, 0);
|
||||
if (rtval == EOPNOTSUPP)
|
||||
return vnode_pager_leaf_putpages(object, m, count, sync, rtvals);
|
||||
else
|
||||
return rtval;
|
||||
return VOP_PUTPAGES(vp, m, count*PAGE_SIZE, sync, rtvals, 0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* generic vnode pager output routine
|
||||
* This is now called from local media FS's to operate against their
|
||||
* own vnodes if they fail to implement VOP_GETPAGES.
|
||||
*/
|
||||
static int
|
||||
vnode_pager_leaf_putpages(object, m, count, sync, rtvals)
|
||||
vm_object_t object;
|
||||
int
|
||||
vnode_pager_generic_putpages(vp, m, bytecount, sync, rtvals)
|
||||
struct vnode *vp;
|
||||
vm_page_t *m;
|
||||
int count;
|
||||
int bytecount;
|
||||
boolean_t sync;
|
||||
int *rtvals;
|
||||
{
|
||||
int i;
|
||||
vm_object_t object;
|
||||
int count;
|
||||
|
||||
struct vnode *vp;
|
||||
int maxsize, ncount;
|
||||
vm_ooffset_t poffset;
|
||||
struct uio auio;
|
||||
struct iovec aiov;
|
||||
int error;
|
||||
|
||||
vp = object->handle;;
|
||||
object = vp->v_object;
|
||||
count = bytecount / PAGE_SIZE;
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
rtvals[i] = VM_PAGER_AGAIN;
|
||||
|
||||
|
@ -36,7 +36,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)vnode_pager.h 8.1 (Berkeley) 6/11/93
|
||||
* $Id$
|
||||
* $Id: vnode_pager.h,v 1.10 1997/02/22 09:48:43 peter Exp $
|
||||
*/
|
||||
|
||||
#ifndef _VNODE_PAGER_
|
||||
@ -46,6 +46,16 @@
|
||||
vm_object_t vnode_pager_alloc __P((void *, vm_size_t, vm_prot_t, vm_ooffset_t));
|
||||
void vnode_pager_freepage __P((vm_page_t m));
|
||||
struct vnode *vnode_pager_lock __P((vm_object_t));
|
||||
|
||||
/*
|
||||
* XXX Generic routines; currently called by badly written FS code; these
|
||||
* XXX should go away soon.
|
||||
*/
|
||||
int vnode_pager_generic_getpages __P((struct vnode *vp, vm_page_t *m,
|
||||
int count, int reqpage));
|
||||
int vnode_pager_generic_putpages __P((struct vnode *vp, vm_page_t *m,
|
||||
int count, boolean_t sync,
|
||||
int *rtvals));
|
||||
#endif
|
||||
|
||||
#endif /* _VNODE_PAGER_ */
|
||||
|
Loading…
Reference in New Issue
Block a user