vfs_domount_update(): postpone setting MNT_UNION until VFS_MOUNT() is done

The file system that handles updating the mount point might do lookups
during the update, in which case it could find the flag MNT_UNION set on
the mp while mount point is still not updated.  In particular, the
rootvp->v_mount->mnt_vnodecovered is not yet set.

Delay setting MNT_UNION until the mount is performed.

PR:	265311
Reported by:	Robert Morris <rtm@lcs.mit.edu>
Reviewed by:	mckusick, olce
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
Differential revision:	https://reviews.freebsd.org/D45208
This commit is contained in:
Konstantin Belousov 2024-05-15 12:54:49 +03:00
parent 5a061a38cd
commit 21ccdb4119

View file

@ -1313,7 +1313,7 @@ vfs_domount_update(
void *bufp;
struct mount *mp;
int error, export_error, i, len, fsid_up_len;
uint64_t flag;
uint64_t flag, mnt_union;
gid_t *grps;
fsid_t *fsid_up;
bool vfs_suser_failed;
@ -1395,6 +1395,7 @@ vfs_domount_update(
vfs_deleteopt(*optlist, "fsid");
}
mnt_union = 0;
MNT_ILOCK(mp);
if ((mp->mnt_kern_flag & MNTK_UNMOUNT) != 0) {
MNT_IUNLOCK(mp);
@ -1416,6 +1417,11 @@ vfs_domount_update(
mp->mnt_flag |= MNT_UPDATE;
} else {
mp->mnt_flag &= ~MNT_UPDATEMASK;
if ((mp->mnt_flag & MNT_UNION) == 0 &&
(fsflags & MNT_UNION) != 0) {
fsflags &= ~MNT_UNION;
mnt_union = MNT_UNION;
}
mp->mnt_flag |= fsflags & (MNT_RELOAD | MNT_FORCE | MNT_UPDATE |
MNT_SNAPSHOT | MNT_ROOTFS | MNT_UPDATEMASK | MNT_RDONLY);
if ((mp->mnt_flag & MNT_ASYNC) == 0)
@ -1519,6 +1525,7 @@ vfs_domount_update(
if (error == 0) {
mp->mnt_flag &= ~(MNT_UPDATE | MNT_RELOAD | MNT_FORCE |
MNT_SNAPSHOT);
mp->mnt_flag |= mnt_union;
} else {
/*
* If we fail, restore old mount flags. MNT_QUOTA is special,