Page MenuHomeFreeBSD

D50648.1783919695.diff
No OneTemporary

Size
3 KB
Referenced Files
None
Subscribers
None

D50648.1783919695.diff

diff --git a/sys/kern/vfs_mount.c b/sys/kern/vfs_mount.c
--- a/sys/kern/vfs_mount.c
+++ b/sys/kern/vfs_mount.c
@@ -156,6 +156,7 @@
mtx_init(&mp->mnt_mtx, "struct mount mtx", NULL, MTX_DEF);
mtx_init(&mp->mnt_listmtx, "struct mount vlist mtx", NULL, MTX_DEF);
lockinit(&mp->mnt_explock, PVFS, "explock", 0, 0);
+ lockinit(&mp->mnt_renamelock, PVFS, "rename", 0, 0);
mp->mnt_pcpu = uma_zalloc_pcpu(pcpu_zone_16, M_WAITOK | M_ZERO);
mp->mnt_ref = 0;
mp->mnt_vfs_ops = 1;
@@ -170,6 +171,7 @@
mp = (struct mount *)mem;
uma_zfree_pcpu(pcpu_zone_16, mp->mnt_pcpu);
+ lockdestroy(&mp->mnt_renamelock);
lockdestroy(&mp->mnt_explock);
mtx_destroy(&mp->mnt_listmtx);
mtx_destroy(&mp->mnt_mtx);
diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c
--- a/sys/kern/vfs_subr.c
+++ b/sys/kern/vfs_subr.c
@@ -5853,6 +5853,8 @@
struct vop_rename_args *a = ap;
#ifdef DEBUG_VFS_LOCKS
+ struct mount *tmp;
+
if (a->a_tvp)
ASSERT_VI_UNLOCKED(a->a_tvp, "VOP_RENAME");
ASSERT_VI_UNLOCKED(a->a_tdvp, "VOP_RENAME");
@@ -5870,6 +5872,11 @@
if (a->a_tvp)
ASSERT_VOP_LOCKED(a->a_tvp, "vop_rename: tvp not locked");
ASSERT_VOP_LOCKED(a->a_tdvp, "vop_rename: tdvp not locked");
+
+ tmp = NULL;
+ VOP_GETWRITEMOUNT(a->a_tdvp, &tmp);
+ lockmgr_assert(&tmp->mnt_renamelock, KA_XLOCKED);
+ vfs_rel(tmp);
#endif
/*
* It may be tempting to add vn_seqc_write_begin/end calls here and
diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c
--- a/sys/kern/vfs_syscalls.c
+++ b/sys/kern/vfs_syscalls.c
@@ -3766,7 +3766,7 @@
kern_renameat(struct thread *td, int oldfd, const char *old, int newfd,
const char *new, enum uio_seg pathseg)
{
- struct mount *mp = NULL;
+ struct mount *mp, *tmp;
struct vnode *tvp, *fvp, *tdvp;
struct nameidata fromnd, tond;
uint64_t tondflags;
@@ -3774,6 +3774,7 @@
short irflag;
again:
+ tmp = mp = NULL;
bwillwrite();
#ifdef MAC
if (mac_vnode_check_rename_from_enabled()) {
@@ -3809,6 +3810,7 @@
tvp = tond.ni_vp;
error = vn_start_write(fvp, &mp, V_NOWAIT);
if (error != 0) {
+again1:
NDFREE_PNBUF(&fromnd);
NDFREE_PNBUF(&tond);
if (tvp != NULL)
@@ -3819,11 +3821,25 @@
vput(tdvp);
vrele(fromnd.ni_dvp);
vrele(fvp);
+ if (tmp != NULL) {
+ lockmgr(&tmp->mnt_renamelock, LK_EXCLUSIVE, NULL);
+ lockmgr(&tmp->mnt_renamelock, LK_RELEASE, NULL);
+ vfs_rel(tmp);
+ tmp = NULL;
+ }
error = vn_start_write(NULL, &mp, V_XSLEEP | V_PCATCH);
if (error != 0)
return (error);
goto again;
}
+ error = VOP_GETWRITEMOUNT(tdvp, &tmp);
+ if (error != 0 || tmp == NULL)
+ goto again1;
+ error = lockmgr(&tmp->mnt_renamelock, LK_EXCLUSIVE | LK_NOWAIT, NULL);
+ if (error != 0) {
+ vn_finished_write(mp);
+ goto again1;
+ }
irflag = vn_irflag_read(fvp);
if (((irflag & VIRF_NAMEDATTR) != 0 && tdvp != fromnd.ni_dvp) ||
(irflag & VIRF_NAMEDDIR) != 0) {
@@ -3884,6 +3900,8 @@
vrele(fromnd.ni_dvp);
vrele(fvp);
}
+ lockmgr(&tmp->mnt_renamelock, LK_RELEASE, 0);
+ vfs_rel(tmp);
vn_finished_write(mp);
out1:
if (error == ERESTART)
diff --git a/sys/sys/mount.h b/sys/sys/mount.h
--- a/sys/sys/mount.h
+++ b/sys/sys/mount.h
@@ -267,6 +267,7 @@
int mnt_lazyvnodelistsize; /* (l) # of lazy vnodes */
int mnt_upper_pending; /* (i) # of pending ops on mnt_uppers */
struct lock mnt_explock; /* vfs_export walkers lock */
+ struct lock mnt_renamelock; /* renames and O_RESOLVE_BENEATH */
TAILQ_HEAD(, mount_upper_node) mnt_uppers; /* (i) upper mounts over us */
TAILQ_HEAD(, mount_upper_node) mnt_notify; /* (i) upper mounts for notification */
STAILQ_ENTRY(mount) mnt_taskqueue_link; /* (d) our place in deferred unmount list */

File Metadata

Mime Type
text/plain
Expires
Mon, Jul 13, 5:14 AM (10 h, 53 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29106888
Default Alt Text
D50648.1783919695.diff (3 KB)

Event Timeline