diff --git a/sys/kern/vfs_lookup.c b/sys/kern/vfs_lookup.c index c1363c0104d..5d66070ca14 100644 --- a/sys/kern/vfs_lookup.c +++ b/sys/kern/vfs_lookup.c @@ -113,7 +113,7 @@ SDT_PROBE_DEFINE4(vfs, namei, lookup, return, "int", "struct vnode *", "bool", uma_zone_t namei_zone; /* Placeholder vnode for mp traversal. */ -static struct vnode *vp_crossmp; +struct vnode *vp_crossmp; static int crossmp_vop_islocked(struct vop_islocked_args *ap) diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index 71d37e08c65..7ca7ccd582e 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -3823,6 +3823,15 @@ kern_renameat(struct thread *td, int oldfd, const char *old, int newfd, } tdvp = tond.ni_dvp; tvp = tond.ni_vp; + if (tdvp == vp_crossmp) { + /* + * Rename of the root vnode of the mounted + * filesystem. It is possible to get there with the + * nullfs mount over the regular file. + */ + error = EBUSY; + goto out; + } if (tvp != NULL && (flags & AT_RENAME_NOREPLACE) != 0) { /* * Often filesystems need to relock the vnodes in diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h index 41b5e21fb87..99e90aa4187 100644 --- a/sys/sys/vnode.h +++ b/sys/sys/vnode.h @@ -462,6 +462,7 @@ extern struct mount *rootdevmp; /* "/dev" mount */ extern u_long desiredvnodes; /* number of vnodes desired */ extern struct uma_zone *namei_zone; extern struct vattr va_null; /* predefined null vattr structure */ +extern struct vnode *vp_crossmp; extern u_int vn_lock_pair_pause_max;