Mon Mar 6 10:07:52 2017 UTC ()
Change vrecycle() and vgone() to lock with LK_RETRY.  If this node is
a layerfs node the lower node(s) may already be reclaimed.


(hannken)
diff -r1.75 -r1.76 src/sys/kern/vfs_vnode.c

cvs diff -r1.75 -r1.76 src/sys/kern/vfs_vnode.c (expand / switch to unified diff)

--- src/sys/kern/vfs_vnode.c 2017/02/17 08:30:00 1.75
+++ src/sys/kern/vfs_vnode.c 2017/03/06 10:07:52 1.76
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: vfs_vnode.c,v 1.75 2017/02/17 08:30:00 hannken Exp $ */ 1/* $NetBSD: vfs_vnode.c,v 1.76 2017/03/06 10:07:52 hannken Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1997-2011 The NetBSD Foundation, Inc. 4 * Copyright (c) 1997-2011 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 Jason R. Thorpe of the Numerical Aerospace Simulation Facility, 8 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
9 * NASA Ames Research Center, by Charles M. Hannum, and by Andrew Doran. 9 * NASA Ames Research Center, by Charles M. Hannum, and by Andrew Doran.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions 12 * modification, are permitted provided that the following conditions
13 * are met: 13 * are met:
14 * 1. Redistributions of source code must retain the above copyright 14 * 1. Redistributions of source code must retain the above copyright
@@ -146,27 +146,27 @@ @@ -146,27 +146,27 @@
146 * Note on v_usecount and its locking 146 * Note on v_usecount and its locking
147 * 147 *
148 * At nearly all points it is known that v_usecount could be zero, 148 * At nearly all points it is known that v_usecount could be zero,
149 * the vnode_t::v_interlock will be held. To change v_usecount away 149 * the vnode_t::v_interlock will be held. To change v_usecount away
150 * from zero, the interlock must be held. To change from a non-zero 150 * from zero, the interlock must be held. To change from a non-zero
151 * value to zero, again the interlock must be held. 151 * value to zero, again the interlock must be held.
152 * 152 *
153 * Changing the usecount from a non-zero value to a non-zero value can 153 * Changing the usecount from a non-zero value to a non-zero value can
154 * safely be done using atomic operations, without the interlock held. 154 * safely be done using atomic operations, without the interlock held.
155 * 155 *
156 */ 156 */
157 157
158#include <sys/cdefs.h> 158#include <sys/cdefs.h>
159__KERNEL_RCSID(0, "$NetBSD: vfs_vnode.c,v 1.75 2017/02/17 08:30:00 hannken Exp $"); 159__KERNEL_RCSID(0, "$NetBSD: vfs_vnode.c,v 1.76 2017/03/06 10:07:52 hannken Exp $");
160 160
161#include <sys/param.h> 161#include <sys/param.h>
162#include <sys/kernel.h> 162#include <sys/kernel.h>
163 163
164#include <sys/atomic.h> 164#include <sys/atomic.h>
165#include <sys/buf.h> 165#include <sys/buf.h>
166#include <sys/conf.h> 166#include <sys/conf.h>
167#include <sys/device.h> 167#include <sys/device.h>
168#include <sys/hash.h> 168#include <sys/hash.h>
169#include <sys/kauth.h> 169#include <sys/kauth.h>
170#include <sys/kmem.h> 170#include <sys/kmem.h>
171#include <sys/kthread.h> 171#include <sys/kthread.h>
172#include <sys/module.h> 172#include <sys/module.h>
@@ -909,27 +909,27 @@ vrecycle(vnode_t *vp) @@ -909,27 +909,27 @@ vrecycle(vnode_t *vp)
909 return true; 909 return true;
910 } 910 }
911 911
912 /* Prevent further references until the vnode is locked. */ 912 /* Prevent further references until the vnode is locked. */
913 VSTATE_CHANGE(vp, VS_ACTIVE, VS_BLOCKED); 913 VSTATE_CHANGE(vp, VS_ACTIVE, VS_BLOCKED);
914 mutex_exit(vp->v_interlock); 914 mutex_exit(vp->v_interlock);
915 915
916 /* 916 /*
917 * On a leaf file system this lock will always succeed as we hold 917 * On a leaf file system this lock will always succeed as we hold
918 * the last reference and prevent further references. 918 * the last reference and prevent further references.
919 * On layered file systems waiting for the lock would open a can of 919 * On layered file systems waiting for the lock would open a can of
920 * deadlocks as the lower vnodes may have other active references. 920 * deadlocks as the lower vnodes may have other active references.
921 */ 921 */
922 error = vn_lock(vp, LK_EXCLUSIVE | LK_NOWAIT); 922 error = vn_lock(vp, LK_EXCLUSIVE | LK_RETRY | LK_NOWAIT);
923 923
924 mutex_enter(vp->v_interlock); 924 mutex_enter(vp->v_interlock);
925 VSTATE_CHANGE(vp, VS_BLOCKED, VS_ACTIVE); 925 VSTATE_CHANGE(vp, VS_BLOCKED, VS_ACTIVE);
926 926
927 if (error) { 927 if (error) {
928 mutex_exit(vp->v_interlock); 928 mutex_exit(vp->v_interlock);
929 return false; 929 return false;
930 } 930 }
931 931
932 KASSERT(vp->v_usecount == 1); 932 KASSERT(vp->v_usecount == 1);
933 vcache_reclaim(vp); 933 vcache_reclaim(vp);
934 vrelel(vp, 0); 934 vrelel(vp, 0);
935 935
@@ -968,33 +968,32 @@ vrevoke(vnode_t *vp) @@ -968,33 +968,32 @@ vrevoke(vnode_t *vp)
968 while (spec_node_lookup_by_dev(type, dev, &vq) == 0) { 968 while (spec_node_lookup_by_dev(type, dev, &vq) == 0) {
969 vgone(vq); 969 vgone(vq);
970 } 970 }
971} 971}
972 972
973/* 973/*
974 * Eliminate all activity associated with a vnode in preparation for 974 * Eliminate all activity associated with a vnode in preparation for
975 * reuse. Drops a reference from the vnode. 975 * reuse. Drops a reference from the vnode.
976 */ 976 */
977void 977void
978vgone(vnode_t *vp) 978vgone(vnode_t *vp)
979{ 979{
980 980
981 if (vn_lock(vp, LK_EXCLUSIVE) != 0) { 981 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
982 VSTATE_ASSERT(vp, VS_RECLAIMED); 
983 vrele(vp); 
984 } 
985 
986 mutex_enter(vp->v_interlock); 982 mutex_enter(vp->v_interlock);
987 vcache_reclaim(vp); 983 VSTATE_WAIT_STABLE(vp);
 984 if (VSTATE_GET(vp) == VS_ACTIVE)
 985 vcache_reclaim(vp);
 986 VSTATE_ASSERT(vp, VS_RECLAIMED);
988 vrelel(vp, 0); 987 vrelel(vp, 0);
989} 988}
990 989
991static inline uint32_t 990static inline uint32_t
992vcache_hash(const struct vcache_key *key) 991vcache_hash(const struct vcache_key *key)
993{ 992{
994 uint32_t hash = HASH32_BUF_INIT; 993 uint32_t hash = HASH32_BUF_INIT;
995 994
996 hash = hash32_buf(&key->vk_mount, sizeof(struct mount *), hash); 995 hash = hash32_buf(&key->vk_mount, sizeof(struct mount *), hash);
997 hash = hash32_buf(key->vk_key, key->vk_key_len, hash); 996 hash = hash32_buf(key->vk_key, key->vk_key_len, hash);
998 return hash; 997 return hash;
999} 998}
1000 999