svn commit: r317132 - stable/11/sys/fs/nfsclient
Konstantin Belousov
kib at FreeBSD.org
Wed Apr 19 11:10:03 UTC 2017
Author: kib
Date: Wed Apr 19 11:10:02 2017
New Revision: 317132
URL: https://svnweb.freebsd.org/changeset/base/317132
Log:
MFC r316529:
Handle possible vnode reclamation after ncl_vinvalbuf() call.
Modified:
stable/11/sys/fs/nfsclient/nfs_clbio.c
stable/11/sys/fs/nfsclient/nfs_clvnops.c
Directory Properties:
stable/11/ (props changed)
Modified: stable/11/sys/fs/nfsclient/nfs_clbio.c
==============================================================================
--- stable/11/sys/fs/nfsclient/nfs_clbio.c Wed Apr 19 10:57:57 2017 (r317131)
+++ stable/11/sys/fs/nfsclient/nfs_clbio.c Wed Apr 19 11:10:02 2017 (r317132)
@@ -394,8 +394,8 @@ nfs_bioread_check_cons(struct vnode *vp,
*/
old_lock = ncl_upgrade_vnlock(vp);
if (vp->v_iflag & VI_DOOMED) {
- ncl_downgrade_vnlock(vp, old_lock);
- return (EBADF);
+ error = EBADF;
+ goto out;
}
mtx_lock(&np->n_mtx);
@@ -406,7 +406,9 @@ nfs_bioread_check_cons(struct vnode *vp,
panic("nfs: bioread, not dir");
ncl_invaldir(vp);
error = ncl_vinvalbuf(vp, V_SAVE, td, 1);
- if (error)
+ if (error == 0 && (vp->v_iflag & VI_DOOMED) != 0)
+ error = EBADF;
+ if (error != 0)
goto out;
}
np->n_attrstamp = 0;
@@ -429,7 +431,9 @@ nfs_bioread_check_cons(struct vnode *vp,
if (vp->v_type == VDIR)
ncl_invaldir(vp);
error = ncl_vinvalbuf(vp, V_SAVE, td, 1);
- if (error)
+ if (error == 0 && (vp->v_iflag & VI_DOOMED) != 0)
+ error = EBADF;
+ if (error != 0)
goto out;
mtx_lock(&np->n_mtx);
np->n_mtime = vattr.va_mtime;
@@ -439,7 +443,7 @@ nfs_bioread_check_cons(struct vnode *vp,
}
out:
ncl_downgrade_vnlock(vp, old_lock);
- return error;
+ return (error);
}
/*
@@ -623,6 +627,9 @@ ncl_bioread(struct vnode *vp, struct uio
while (error == NFSERR_BAD_COOKIE) {
ncl_invaldir(vp);
error = ncl_vinvalbuf(vp, 0, td, 1);
+ if (error == 0 && (vp->v_iflag & VI_DOOMED) != 0)
+ return (EBADF);
+
/*
* Yuck! The directory has been modified on the
* server. The only way to get the block is by
@@ -943,8 +950,11 @@ ncl_write(struct vop_write_args *ap)
#endif
np->n_attrstamp = 0;
KDTRACE_NFS_ATTRCACHE_FLUSH_DONE(vp);
- error = ncl_vinvalbuf(vp, V_SAVE, td, 1);
- if (error)
+ error = ncl_vinvalbuf(vp, V_SAVE | ((ioflag &
+ IO_VMIO) != 0 ? V_VMIO : 0), td, 1);
+ if (error == 0 && (vp->v_iflag & VI_DOOMED) != 0)
+ error = EBADF;
+ if (error != 0)
return (error);
} else
mtx_unlock(&np->n_mtx);
@@ -1023,8 +1033,12 @@ ncl_write(struct vop_write_args *ap)
if (wouldcommit > nmp->nm_wcommitsize) {
np->n_attrstamp = 0;
KDTRACE_NFS_ATTRCACHE_FLUSH_DONE(vp);
- error = ncl_vinvalbuf(vp, V_SAVE, td, 1);
- if (error)
+ error = ncl_vinvalbuf(vp, V_SAVE | ((ioflag &
+ IO_VMIO) != 0 ? V_VMIO : 0), td, 1);
+ if (error == 0 &&
+ (vp->v_iflag & VI_DOOMED) != 0)
+ error = EBADF;
+ if (error != 0)
return (error);
wouldcommit = biosize;
}
Modified: stable/11/sys/fs/nfsclient/nfs_clvnops.c
==============================================================================
--- stable/11/sys/fs/nfsclient/nfs_clvnops.c Wed Apr 19 10:57:57 2017 (r317131)
+++ stable/11/sys/fs/nfsclient/nfs_clvnops.c Wed Apr 19 11:10:02 2017 (r317132)
@@ -520,6 +520,8 @@ nfs_open(struct vop_open_args *ap)
if (np->n_flag & NMODIFIED) {
mtx_unlock(&np->n_mtx);
error = ncl_vinvalbuf(vp, V_SAVE, ap->a_td, 1);
+ if (error == 0 && (vp->v_iflag & VI_DOOMED) != 0)
+ return (EBADF);
if (error == EINTR || error == EIO) {
if (NFS_ISV4(vp))
(void) nfsrpc_close(vp, 0, ap->a_td);
@@ -556,6 +558,8 @@ nfs_open(struct vop_open_args *ap)
np->n_direofoffset = 0;
mtx_unlock(&np->n_mtx);
error = ncl_vinvalbuf(vp, V_SAVE, ap->a_td, 1);
+ if (error == 0 && (vp->v_iflag & VI_DOOMED) != 0)
+ return (EBADF);
if (error == EINTR || error == EIO) {
if (NFS_ISV4(vp))
(void) nfsrpc_close(vp, 0, ap->a_td);
@@ -576,6 +580,8 @@ nfs_open(struct vop_open_args *ap)
if (np->n_directio_opens == 0) {
mtx_unlock(&np->n_mtx);
error = ncl_vinvalbuf(vp, V_SAVE, ap->a_td, 1);
+ if (error == 0 && (vp->v_iflag & VI_DOOMED) != 0)
+ return (EBADF);
if (error) {
if (NFS_ISV4(vp))
(void) nfsrpc_close(vp, 0, ap->a_td);
@@ -714,8 +720,11 @@ nfs_close(struct vop_close_args *ap)
* np->n_flag &= ~NMODIFIED;
*/
}
- } else
- error = ncl_vinvalbuf(vp, V_SAVE, ap->a_td, 1);
+ } else {
+ error = ncl_vinvalbuf(vp, V_SAVE, ap->a_td, 1);
+ if (error == 0 && (vp->v_iflag & VI_DOOMED) != 0)
+ return (EBADF);
+ }
mtx_lock(&np->n_mtx);
}
/*
@@ -931,13 +940,13 @@ nfs_setattr(struct vop_setattr_args *ap)
if (np->n_flag & NMODIFIED) {
tsize = np->n_size;
mtx_unlock(&np->n_mtx);
- if (vap->va_size == 0)
- error = ncl_vinvalbuf(vp, 0, td, 1);
- else
- error = ncl_vinvalbuf(vp, V_SAVE, td, 1);
- if (error) {
- vnode_pager_setsize(vp, tsize);
- return (error);
+ error = ncl_vinvalbuf(vp, vap->va_size == 0 ?
+ 0 : V_SAVE, td, 1);
+ if (error == 0 && (vp->v_iflag & VI_DOOMED) != 0)
+ error = EBADF;
+ if (error != 0) {
+ vnode_pager_setsize(vp, tsize);
+ return (error);
}
/*
* Call nfscl_delegmodtime() to set the modify time
@@ -961,8 +970,10 @@ nfs_setattr(struct vop_setattr_args *ap)
if ((vap->va_mtime.tv_sec != VNOVAL || vap->va_atime.tv_sec != VNOVAL) &&
(np->n_flag & NMODIFIED) && vp->v_type == VREG) {
mtx_unlock(&np->n_mtx);
- if ((error = ncl_vinvalbuf(vp, V_SAVE, td, 1)) != 0 &&
- (error == EINTR || error == EIO))
+ error = ncl_vinvalbuf(vp, V_SAVE, td, 1);
+ if (error == 0 && (vp->v_iflag & VI_DOOMED) != 0)
+ return (EBADF);
+ if (error == EINTR || error == EIO)
return (error);
} else
mtx_unlock(&np->n_mtx);
@@ -1665,8 +1676,10 @@ nfs_remove(struct vop_remove_args *ap)
* unnecessary delayed writes later.
*/
error = ncl_vinvalbuf(vp, 0, cnp->cn_thread, 1);
- /* Do the rpc */
- if (error != EINTR && error != EIO)
+ if (error == 0 && (vp->v_iflag & VI_DOOMED) != 0)
+ error = EBADF;
+ else if (error != EINTR && error != EIO)
+ /* Do the rpc */
error = nfs_removerpc(dvp, vp, cnp->cn_nameptr,
cnp->cn_namelen, cnp->cn_cred, cnp->cn_thread);
/*
@@ -3055,6 +3068,10 @@ nfs_advlock(struct vop_advlock_args *ap)
if ((np->n_flag & NMODIFIED) || ret ||
np->n_change != va.va_filerev) {
(void) ncl_vinvalbuf(vp, V_SAVE, td, 1);
+ if ((vp->v_iflag & VI_DOOMED) != 0) {
+ NFSVOPUNLOCK(vp, 0);
+ return (EBADF);
+ }
np->n_attrstamp = 0;
KDTRACE_NFS_ATTRCACHE_FLUSH_DONE(vp);
ret = VOP_GETATTR(vp, &va, cred);
More information about the svn-src-stable-11
mailing list