Problem to avoid processes getting stuck in "vmopar". From Ian's

mail:

	The problem seems to originate with NFS's postop_attr
	information that is returned with a read or write RPC.
	Within a vm_fault context, the code cannot deal with
	vnode_pager_setsize() shrinking a vnode.

	The workaround in the patch below stops the nfsm_postop_attr()
	macro from ever shrinking a vnode. If the new size in the
	postop_attr information is smaller, then it just sets the
	nfsnode n_attrstamp to 0 to stop the wrong size getting
	used in the future. This change only affects postop_attr
	attributes; the nfsm_loadattr() macro works as normal.

	The change is implemented by adding a new argument to
	nfs_loadattrcache() called 'dontshrink'. When this is
	non-zero, nfs_loadattrcache() will never reduce the
	vnode/nfsnode size; instead it zeros n_attrstamp.

There remain other was processes can get stuck in vmopar.

Submitted by:	Ian Dowse <iedowse@maths.tcd.ie>
Reviewed by:	dillon
Tested by:	Vadim Belman <voland@lflat.org>
This commit is contained in:
dwmalone 2000-10-24 10:13:36 +00:00
parent 79719d2ea5
commit 23aacadb39
14 changed files with 62 additions and 26 deletions

View File

@ -616,7 +616,7 @@ int nfs_request __P((struct vnode *, struct mbuf *, int, struct proc *,
struct ucred *, struct mbuf **, struct mbuf **,
caddr_t *));
int nfs_loadattrcache __P((struct vnode **, struct mbuf **, caddr_t *,
struct vattr *));
struct vattr *, int));
int nfs_namei __P((struct nameidata *, fhandle_t *, int,
struct nfssvc_sock *, struct sockaddr *, struct mbuf **,
caddr_t *, struct vnode **, struct proc *, int, int));

View File

@ -1203,11 +1203,12 @@ nfs_uninit(vfsp)
* copy the attributes to *vaper
*/
int
nfs_loadattrcache(vpp, mdp, dposp, vaper)
nfs_loadattrcache(vpp, mdp, dposp, vaper, dontshrink)
struct vnode **vpp;
struct mbuf **mdp;
caddr_t *dposp;
struct vattr *vaper;
int dontshrink;
{
register struct vnode *vp = *vpp;
register struct vattr *vap;
@ -1323,9 +1324,18 @@ nfs_loadattrcache(vpp, mdp, dposp, vaper)
vap->va_gen = fxdr_unsigned(u_int32_t,fp->fa2_ctime.nfsv2_usec);
vap->va_filerev = 0;
}
np->n_attrstamp = time_second;
if (vap->va_size != np->n_size) {
if (vap->va_type == VREG) {
if (np->n_flag & NMODIFIED) {
if (dontshrink && vap->va_size < np->n_size) {
/*
* We've been told not to shrink the file;
* zero np->n_attrstamp to indicate that
* the attributes are stale.
*/
vap->va_size = np->n_size;
np->n_attrstamp = 0;
} else if (np->n_flag & NMODIFIED) {
if (vap->va_size < np->n_size)
vap->va_size = np->n_size;
else
@ -1338,7 +1348,6 @@ nfs_loadattrcache(vpp, mdp, dposp, vaper)
np->n_size = vap->va_size;
}
}
np->n_attrstamp = time_second;
if (vaper != NULL) {
bcopy((caddr_t)vap, (caddr_t)vaper, sizeof(*vap));
if (np->n_flag & NCHG) {

View File

@ -212,7 +212,7 @@ struct mbuf *nfsm_rpchead __P((struct ucred *cr, int nmflag, int procid,
#define nfsm_loadattr(v, a) \
do { \
struct vnode *ttvp = (v); \
if ((t1 = nfs_loadattrcache(&ttvp, &md, &dpos, (a))) != 0) { \
if ((t1 = nfs_loadattrcache(&ttvp, &md, &dpos, (a), 0)) != 0) { \
error = t1; \
m_freem(mrep); \
goto nfsmout; \
@ -226,7 +226,7 @@ struct mbuf *nfsm_rpchead __P((struct ucred *cr, int nmflag, int procid,
nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \
if (((f) = fxdr_unsigned(int, *tl)) != 0) { \
if ((t1 = nfs_loadattrcache(&ttvp, &md, &dpos, \
(struct vattr *)0)) != 0) { \
(struct vattr *)0, 1)) != 0) { \
error = t1; \
(f) = 0; \
m_freem(mrep); \

View File

@ -1203,11 +1203,12 @@ nfs_uninit(vfsp)
* copy the attributes to *vaper
*/
int
nfs_loadattrcache(vpp, mdp, dposp, vaper)
nfs_loadattrcache(vpp, mdp, dposp, vaper, dontshrink)
struct vnode **vpp;
struct mbuf **mdp;
caddr_t *dposp;
struct vattr *vaper;
int dontshrink;
{
register struct vnode *vp = *vpp;
register struct vattr *vap;
@ -1323,9 +1324,18 @@ nfs_loadattrcache(vpp, mdp, dposp, vaper)
vap->va_gen = fxdr_unsigned(u_int32_t,fp->fa2_ctime.nfsv2_usec);
vap->va_filerev = 0;
}
np->n_attrstamp = time_second;
if (vap->va_size != np->n_size) {
if (vap->va_type == VREG) {
if (np->n_flag & NMODIFIED) {
if (dontshrink && vap->va_size < np->n_size) {
/*
* We've been told not to shrink the file;
* zero np->n_attrstamp to indicate that
* the attributes are stale.
*/
vap->va_size = np->n_size;
np->n_attrstamp = 0;
} else if (np->n_flag & NMODIFIED) {
if (vap->va_size < np->n_size)
vap->va_size = np->n_size;
else
@ -1338,7 +1348,6 @@ nfs_loadattrcache(vpp, mdp, dposp, vaper)
np->n_size = vap->va_size;
}
}
np->n_attrstamp = time_second;
if (vaper != NULL) {
bcopy((caddr_t)vap, (caddr_t)vaper, sizeof(*vap));
if (np->n_flag & NCHG) {

View File

@ -212,7 +212,7 @@ struct mbuf *nfsm_rpchead __P((struct ucred *cr, int nmflag, int procid,
#define nfsm_loadattr(v, a) \
do { \
struct vnode *ttvp = (v); \
if ((t1 = nfs_loadattrcache(&ttvp, &md, &dpos, (a))) != 0) { \
if ((t1 = nfs_loadattrcache(&ttvp, &md, &dpos, (a), 0)) != 0) { \
error = t1; \
m_freem(mrep); \
goto nfsmout; \
@ -226,7 +226,7 @@ struct mbuf *nfsm_rpchead __P((struct ucred *cr, int nmflag, int procid,
nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \
if (((f) = fxdr_unsigned(int, *tl)) != 0) { \
if ((t1 = nfs_loadattrcache(&ttvp, &md, &dpos, \
(struct vattr *)0)) != 0) { \
(struct vattr *)0, 1)) != 0) { \
error = t1; \
(f) = 0; \
m_freem(mrep); \

View File

@ -616,7 +616,7 @@ int nfs_request __P((struct vnode *, struct mbuf *, int, struct proc *,
struct ucred *, struct mbuf **, struct mbuf **,
caddr_t *));
int nfs_loadattrcache __P((struct vnode **, struct mbuf **, caddr_t *,
struct vattr *));
struct vattr *, int));
int nfs_namei __P((struct nameidata *, fhandle_t *, int,
struct nfssvc_sock *, struct sockaddr *, struct mbuf **,
caddr_t *, struct vnode **, struct proc *, int, int));

View File

@ -1203,11 +1203,12 @@ nfs_uninit(vfsp)
* copy the attributes to *vaper
*/
int
nfs_loadattrcache(vpp, mdp, dposp, vaper)
nfs_loadattrcache(vpp, mdp, dposp, vaper, dontshrink)
struct vnode **vpp;
struct mbuf **mdp;
caddr_t *dposp;
struct vattr *vaper;
int dontshrink;
{
register struct vnode *vp = *vpp;
register struct vattr *vap;
@ -1323,9 +1324,18 @@ nfs_loadattrcache(vpp, mdp, dposp, vaper)
vap->va_gen = fxdr_unsigned(u_int32_t,fp->fa2_ctime.nfsv2_usec);
vap->va_filerev = 0;
}
np->n_attrstamp = time_second;
if (vap->va_size != np->n_size) {
if (vap->va_type == VREG) {
if (np->n_flag & NMODIFIED) {
if (dontshrink && vap->va_size < np->n_size) {
/*
* We've been told not to shrink the file;
* zero np->n_attrstamp to indicate that
* the attributes are stale.
*/
vap->va_size = np->n_size;
np->n_attrstamp = 0;
} else if (np->n_flag & NMODIFIED) {
if (vap->va_size < np->n_size)
vap->va_size = np->n_size;
else
@ -1338,7 +1348,6 @@ nfs_loadattrcache(vpp, mdp, dposp, vaper)
np->n_size = vap->va_size;
}
}
np->n_attrstamp = time_second;
if (vaper != NULL) {
bcopy((caddr_t)vap, (caddr_t)vaper, sizeof(*vap));
if (np->n_flag & NCHG) {

View File

@ -616,7 +616,7 @@ int nfs_request __P((struct vnode *, struct mbuf *, int, struct proc *,
struct ucred *, struct mbuf **, struct mbuf **,
caddr_t *));
int nfs_loadattrcache __P((struct vnode **, struct mbuf **, caddr_t *,
struct vattr *));
struct vattr *, int));
int nfs_namei __P((struct nameidata *, fhandle_t *, int,
struct nfssvc_sock *, struct sockaddr *, struct mbuf **,
caddr_t *, struct vnode **, struct proc *, int, int));

View File

@ -212,7 +212,7 @@ struct mbuf *nfsm_rpchead __P((struct ucred *cr, int nmflag, int procid,
#define nfsm_loadattr(v, a) \
do { \
struct vnode *ttvp = (v); \
if ((t1 = nfs_loadattrcache(&ttvp, &md, &dpos, (a))) != 0) { \
if ((t1 = nfs_loadattrcache(&ttvp, &md, &dpos, (a), 0)) != 0) { \
error = t1; \
m_freem(mrep); \
goto nfsmout; \
@ -226,7 +226,7 @@ struct mbuf *nfsm_rpchead __P((struct ucred *cr, int nmflag, int procid,
nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \
if (((f) = fxdr_unsigned(int, *tl)) != 0) { \
if ((t1 = nfs_loadattrcache(&ttvp, &md, &dpos, \
(struct vattr *)0)) != 0) { \
(struct vattr *)0, 1)) != 0) { \
error = t1; \
(f) = 0; \
m_freem(mrep); \

View File

@ -616,7 +616,7 @@ int nfs_request __P((struct vnode *, struct mbuf *, int, struct proc *,
struct ucred *, struct mbuf **, struct mbuf **,
caddr_t *));
int nfs_loadattrcache __P((struct vnode **, struct mbuf **, caddr_t *,
struct vattr *));
struct vattr *, int));
int nfs_namei __P((struct nameidata *, fhandle_t *, int,
struct nfssvc_sock *, struct sockaddr *, struct mbuf **,
caddr_t *, struct vnode **, struct proc *, int, int));

View File

@ -616,7 +616,7 @@ int nfs_request __P((struct vnode *, struct mbuf *, int, struct proc *,
struct ucred *, struct mbuf **, struct mbuf **,
caddr_t *));
int nfs_loadattrcache __P((struct vnode **, struct mbuf **, caddr_t *,
struct vattr *));
struct vattr *, int));
int nfs_namei __P((struct nameidata *, fhandle_t *, int,
struct nfssvc_sock *, struct sockaddr *, struct mbuf **,
caddr_t *, struct vnode **, struct proc *, int, int));

View File

@ -1203,11 +1203,12 @@ nfs_uninit(vfsp)
* copy the attributes to *vaper
*/
int
nfs_loadattrcache(vpp, mdp, dposp, vaper)
nfs_loadattrcache(vpp, mdp, dposp, vaper, dontshrink)
struct vnode **vpp;
struct mbuf **mdp;
caddr_t *dposp;
struct vattr *vaper;
int dontshrink;
{
register struct vnode *vp = *vpp;
register struct vattr *vap;
@ -1323,9 +1324,18 @@ nfs_loadattrcache(vpp, mdp, dposp, vaper)
vap->va_gen = fxdr_unsigned(u_int32_t,fp->fa2_ctime.nfsv2_usec);
vap->va_filerev = 0;
}
np->n_attrstamp = time_second;
if (vap->va_size != np->n_size) {
if (vap->va_type == VREG) {
if (np->n_flag & NMODIFIED) {
if (dontshrink && vap->va_size < np->n_size) {
/*
* We've been told not to shrink the file;
* zero np->n_attrstamp to indicate that
* the attributes are stale.
*/
vap->va_size = np->n_size;
np->n_attrstamp = 0;
} else if (np->n_flag & NMODIFIED) {
if (vap->va_size < np->n_size)
vap->va_size = np->n_size;
else
@ -1338,7 +1348,6 @@ nfs_loadattrcache(vpp, mdp, dposp, vaper)
np->n_size = vap->va_size;
}
}
np->n_attrstamp = time_second;
if (vaper != NULL) {
bcopy((caddr_t)vap, (caddr_t)vaper, sizeof(*vap));
if (np->n_flag & NCHG) {

View File

@ -212,7 +212,7 @@ struct mbuf *nfsm_rpchead __P((struct ucred *cr, int nmflag, int procid,
#define nfsm_loadattr(v, a) \
do { \
struct vnode *ttvp = (v); \
if ((t1 = nfs_loadattrcache(&ttvp, &md, &dpos, (a))) != 0) { \
if ((t1 = nfs_loadattrcache(&ttvp, &md, &dpos, (a), 0)) != 0) { \
error = t1; \
m_freem(mrep); \
goto nfsmout; \
@ -226,7 +226,7 @@ struct mbuf *nfsm_rpchead __P((struct ucred *cr, int nmflag, int procid,
nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \
if (((f) = fxdr_unsigned(int, *tl)) != 0) { \
if ((t1 = nfs_loadattrcache(&ttvp, &md, &dpos, \
(struct vattr *)0)) != 0) { \
(struct vattr *)0, 1)) != 0) { \
error = t1; \
(f) = 0; \
m_freem(mrep); \

View File

@ -616,7 +616,7 @@ int nfs_request __P((struct vnode *, struct mbuf *, int, struct proc *,
struct ucred *, struct mbuf **, struct mbuf **,
caddr_t *));
int nfs_loadattrcache __P((struct vnode **, struct mbuf **, caddr_t *,
struct vattr *));
struct vattr *, int));
int nfs_namei __P((struct nameidata *, fhandle_t *, int,
struct nfssvc_sock *, struct sockaddr *, struct mbuf **,
caddr_t *, struct vnode **, struct proc *, int, int));