diff options
author | pjd <pjd@FreeBSD.org> | 2006-08-09 12:47:30 +0000 |
---|---|---|
committer | pjd <pjd@FreeBSD.org> | 2006-08-09 12:47:30 +0000 |
commit | 7f9e892ea9ffc1021556a11a2be7eae73baeafe9 (patch) | |
tree | 6d56390527abd51a3456f3f71dc3f12987a17907 /sys | |
parent | ce06f7617ef0d5b29477cad26df20a4dea7d581c (diff) | |
download | FreeBSD-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.c | 10 |
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); |