| @@ -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 | */ |
977 | void | | 977 | void |
978 | vgone(vnode_t *vp) | | 978 | vgone(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 | |
991 | static inline uint32_t | | 990 | static inline uint32_t |
992 | vcache_hash(const struct vcache_key *key) | | 991 | vcache_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 | |