Thu Apr 5 07:26:37 2012 UTC ()
Fix vn_lock() to return an invalid (dead, clean) vnode
only if the caller requested it by setting LK_RETRY.

Should fix PR #46221: Kernel panic in NFS server code


(hannken)
diff -r1.183 -r1.184 src/sys/kern/vfs_vnops.c

cvs diff -r1.183 -r1.184 src/sys/kern/vfs_vnops.c (expand / switch to unified diff)

--- src/sys/kern/vfs_vnops.c 2011/10/14 09:23:31 1.183
+++ src/sys/kern/vfs_vnops.c 2012/04/05 07:26:36 1.184
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: vfs_vnops.c,v 1.183 2011/10/14 09:23:31 hannken Exp $ */ 1/* $NetBSD: vfs_vnops.c,v 1.184 2012/04/05 07:26:36 hannken Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2009 The NetBSD Foundation, Inc. 4 * Copyright (c) 2009 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Andrew Doran. 8 * by Andrew Doran.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -56,27 +56,27 @@ @@ -56,27 +56,27 @@
56 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 56 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
57 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 57 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
58 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 58 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
59 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 59 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
60 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 60 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
61 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 61 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
62 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 62 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
63 * SUCH DAMAGE. 63 * SUCH DAMAGE.
64 * 64 *
65 * @(#)vfs_vnops.c 8.14 (Berkeley) 6/15/95 65 * @(#)vfs_vnops.c 8.14 (Berkeley) 6/15/95
66 */ 66 */
67 67
68#include <sys/cdefs.h> 68#include <sys/cdefs.h>
69__KERNEL_RCSID(0, "$NetBSD: vfs_vnops.c,v 1.183 2011/10/14 09:23:31 hannken Exp $"); 69__KERNEL_RCSID(0, "$NetBSD: vfs_vnops.c,v 1.184 2012/04/05 07:26:36 hannken Exp $");
70 70
71#include "veriexec.h" 71#include "veriexec.h"
72 72
73#include <sys/param.h> 73#include <sys/param.h>
74#include <sys/systm.h> 74#include <sys/systm.h>
75#include <sys/kernel.h> 75#include <sys/kernel.h>
76#include <sys/file.h> 76#include <sys/file.h>
77#include <sys/stat.h> 77#include <sys/stat.h>
78#include <sys/buf.h> 78#include <sys/buf.h>
79#include <sys/proc.h> 79#include <sys/proc.h>
80#include <sys/mount.h> 80#include <sys/mount.h>
81#include <sys/namei.h> 81#include <sys/namei.h>
82#include <sys/vnode.h> 82#include <sys/vnode.h>
@@ -795,26 +795,35 @@ vn_lock(struct vnode *vp, int flags) @@ -795,26 +795,35 @@ vn_lock(struct vnode *vp, int flags)
795 */ 795 */
796 mutex_enter(vp->v_interlock); 796 mutex_enter(vp->v_interlock);
797 if (vp->v_iflag & VI_XLOCK) { 797 if (vp->v_iflag & VI_XLOCK) {
798 if (flags & LK_NOWAIT) { 798 if (flags & LK_NOWAIT) {
799 mutex_exit(vp->v_interlock); 799 mutex_exit(vp->v_interlock);
800 return EBUSY; 800 return EBUSY;
801 } 801 }
802 vwait(vp, VI_XLOCK); 802 vwait(vp, VI_XLOCK);
803 mutex_exit(vp->v_interlock); 803 mutex_exit(vp->v_interlock);
804 error = ENOENT; 804 error = ENOENT;
805 } else { 805 } else {
806 mutex_exit(vp->v_interlock); 806 mutex_exit(vp->v_interlock);
807 error = VOP_LOCK(vp, (flags & ~LK_RETRY)); 807 error = VOP_LOCK(vp, (flags & ~LK_RETRY));
 808 if (error == 0 && (flags & LK_RETRY) == 0) {
 809 mutex_enter(vp->v_interlock);
 810 if ((vp->v_iflag & VI_CLEAN)) {
 811 mutex_exit(vp->v_interlock);
 812 VOP_UNLOCK(vp);
 813 return ENOENT;
 814 }
 815 mutex_exit(vp->v_interlock);
 816 }
808 if (error == 0 || error == EDEADLK || error == EBUSY) 817 if (error == 0 || error == EDEADLK || error == EBUSY)
809 return (error); 818 return (error);
810 } 819 }
811 } while (flags & LK_RETRY); 820 } while (flags & LK_RETRY);
812 return (error); 821 return (error);
813} 822}
814 823
815/* 824/*
816 * File table vnode close routine. 825 * File table vnode close routine.
817 */ 826 */
818static int 827static int
819vn_closefile(file_t *fp) 828vn_closefile(file_t *fp)
820{ 829{