aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Dowse <iedowse@FreeBSD.org>2002-10-27 23:23:51 +0000
committerIan Dowse <iedowse@FreeBSD.org>2002-10-27 23:23:51 +0000
commit4e08ccb2ffe596eee3a388d9c51876938b94682c (patch)
tree108cb2e5b8eb5d44010c40e8836f65148d1d8565
parent36cb272078b1b91f2736480a8f45c9ae764fccdf (diff)
downloadsrc-4e08ccb2ffe596eee3a388d9c51876938b94682c.tar.gz
src-4e08ccb2ffe596eee3a388d9c51876938b94682c.zip
Fix a case in kern_rename() where a vn_finished_write() call was
missed. This bug has been present since the vn_start_write() and vn_finished_write() calls were first added in revision 1.159. When the case is triggered, any attempts to create snapshots on the filesystem will deadlock and also prevent further write activity on that filesystem.
Notes
Notes: svn path=/head/; revision=106064
-rw-r--r--sys/kern/vfs_extattr.c4
-rw-r--r--sys/kern/vfs_syscalls.c4
2 files changed, 4 insertions, 4 deletions
diff --git a/sys/kern/vfs_extattr.c b/sys/kern/vfs_extattr.c
index 55aea6e9dd65..8e2d60599cd9 100644
--- a/sys/kern/vfs_extattr.c
+++ b/sys/kern/vfs_extattr.c
@@ -2755,7 +2755,7 @@ rename(td, uap)
int
kern_rename(struct thread *td, char *from, char *to, enum uio_seg pathseg)
{
- struct mount *mp;
+ struct mount *mp = NULL;
struct vnode *tvp, *fvp, *tdvp;
struct nameidata fromnd, tond;
int error;
@@ -2847,12 +2847,12 @@ out:
vrele(fvp);
}
vrele(tond.ni_startdir);
- vn_finished_write(mp);
ASSERT_VOP_UNLOCKED(fromnd.ni_dvp, "rename");
ASSERT_VOP_UNLOCKED(fromnd.ni_vp, "rename");
ASSERT_VOP_UNLOCKED(tond.ni_dvp, "rename");
ASSERT_VOP_UNLOCKED(tond.ni_vp, "rename");
out1:
+ vn_finished_write(mp);
if (fromnd.ni_startdir)
vrele(fromnd.ni_startdir);
if (error == -1)
diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c
index 55aea6e9dd65..8e2d60599cd9 100644
--- a/sys/kern/vfs_syscalls.c
+++ b/sys/kern/vfs_syscalls.c
@@ -2755,7 +2755,7 @@ rename(td, uap)
int
kern_rename(struct thread *td, char *from, char *to, enum uio_seg pathseg)
{
- struct mount *mp;
+ struct mount *mp = NULL;
struct vnode *tvp, *fvp, *tdvp;
struct nameidata fromnd, tond;
int error;
@@ -2847,12 +2847,12 @@ out:
vrele(fvp);
}
vrele(tond.ni_startdir);
- vn_finished_write(mp);
ASSERT_VOP_UNLOCKED(fromnd.ni_dvp, "rename");
ASSERT_VOP_UNLOCKED(fromnd.ni_vp, "rename");
ASSERT_VOP_UNLOCKED(tond.ni_dvp, "rename");
ASSERT_VOP_UNLOCKED(tond.ni_vp, "rename");
out1:
+ vn_finished_write(mp);
if (fromnd.ni_startdir)
vrele(fromnd.ni_startdir);
if (error == -1)