summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorpjd <pjd@FreeBSD.org>2006-08-09 12:47:30 +0000
committerpjd <pjd@FreeBSD.org>2006-08-09 12:47:30 +0000
commit7f9e892ea9ffc1021556a11a2be7eae73baeafe9 (patch)
tree6d56390527abd51a3456f3f71dc3f12987a17907 /sys
parentce06f7617ef0d5b29477cad26df20a4dea7d581c (diff)
downloadFreeBSD-src-7f9e892ea9ffc1021556a11a2be7eae73baeafe9.zip
FreeBSD-src-7f9e892ea9ffc1021556a11a2be7eae73baeafe9.tar.gz
Add a bandaid to avoid a deadlock in a situation, when we are trying to suspend
a file system, but need to obtain a vnode. We may not be able to do it, because all vnodes could be already in use and other processes cannot release them, because they are waiting in "suspfs" state. In such situation, we allow to allocate a vnode anyway. This is a temporary fix - there is no backpressure to free vnodes allocated in those circumstances. MFC after: 1 week Reviewed by: tegge
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/vfs_subr.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c
index d3963fe..1710ad1 100644
--- a/sys/kern/vfs_subr.c
+++ b/sys/kern/vfs_subr.c
@@ -869,6 +869,15 @@ getnewvnode(const char *tag, struct mount *mp, struct vop_vector *vops,
* Wait for available vnodes.
*/
if (numvnodes > desiredvnodes) {
+ if (mp->mnt_kern_flag & MNTK_SUSPEND) {
+ /*
+ * File system is beeing suspended, we cannot risk a
+ * deadlock here, so allocate new vnode anyway.
+ */
+ if (freevnodes > wantfreevnodes)
+ vnlru_free(freevnodes - wantfreevnodes);
+ goto alloc;
+ }
if (vnlruproc_sig == 0) {
vnlruproc_sig = 1; /* avoid unnecessary wakeups */
wakeup(vnlruproc);
@@ -882,6 +891,7 @@ getnewvnode(const char *tag, struct mount *mp, struct vop_vector *vops,
}
#endif
}
+alloc:
numvnodes++;
mtx_unlock(&vnode_free_list_mtx);
vp = (struct vnode *) uma_zalloc(vnode_zone, M_WAITOK|M_ZERO);
OpenPOWER on IntegriCloud