Date: Sat, 11 Feb 2023 03:36:00 GMT From: Rick Macklem <rmacklem@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Subject: git: 3e230e0cc4ad - main - nfsd: Fix handling of the error case for nfsvno_open some more Message-ID: <202302110336.31B3a04F047400@gitrepo.freebsd.org>
next in thread | raw e-mail | index | archive | help
The branch main has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=3e230e0cc4ad822554afaaa07369ca5ccb62054d commit 3e230e0cc4ad822554afaaa07369ca5ccb62054d Author: Rick Macklem <rmacklem@FreeBSD.org> AuthorDate: 2023-02-11 03:34:57 +0000 Commit: Rick Macklem <rmacklem@FreeBSD.org> CommitDate: 2023-02-11 03:34:57 +0000 nfsd: Fix handling of the error case for nfsvno_open some more Commit ded5f2954e1a defined done_namei to indicate that nd_repstat was set after a successful nfsvno_namei(), so that a cleanup needs to be done in nfsvno_open(). However, it missed the case where a call to nfsrv_opencheck() in nfsvno_open() sets nd_repstat non-zero. This would cause panics due to a dangling locked vnode when nfsrv_opencheck() set nd_repstat, such as during grace just after a server boot. This patch fixes the problem. PR: 268971 --- sys/fs/nfsserver/nfs_nfsdport.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/sys/fs/nfsserver/nfs_nfsdport.c b/sys/fs/nfsserver/nfs_nfsdport.c index 7305ae6a84fe..daa57222fe22 100644 --- a/sys/fs/nfsserver/nfs_nfsdport.c +++ b/sys/fs/nfsserver/nfs_nfsdport.c @@ -1842,10 +1842,19 @@ nfsvno_open(struct nfsrv_descript *nd, struct nameidata *ndp, u_quad_t tempsize; struct nfsexstuff nes; struct thread *p = curthread; + uint32_t oldrepstat; - if (ndp->ni_vp == NULL) + if (ndp->ni_vp == NULL) { + /* + * If nfsrv_opencheck() sets nd_repstat, done_namei needs to be + * set true, since cleanup after nfsvno_namei() is needed. + */ + oldrepstat = nd->nd_repstat; nd->nd_repstat = nfsrv_opencheck(clientid, stateidp, stp, NULL, nd, p, nd->nd_repstat); + if (nd->nd_repstat != 0 && oldrepstat == 0) + done_namei = true; + } if (!nd->nd_repstat) { if (ndp->ni_vp == NULL) { nd->nd_repstat = VOP_CREATE(ndp->ni_dvp,
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202302110336.31B3a04F047400>