Use mount interlock to protect all changes to mnt_flag and mnt_kern_flag.
This eliminates a race where MNT_UPDATE flag could be lost when nmount() raced against sync(), sync_fsync() or quotactl().
This commit is contained in:
parent
b14f05094a
commit
5da56ddb21
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=162647
@ -137,7 +137,9 @@ cd9660_mount(struct mount *mp, struct thread *td)
|
||||
/*
|
||||
* Unconditionally mount as read-only.
|
||||
*/
|
||||
MNT_ILOCK(mp);
|
||||
mp->mnt_flag |= MNT_RDONLY;
|
||||
MNT_IUNLOCK(mp);
|
||||
|
||||
fspec = vfs_getopts(mp->mnt_optnew, "from", &error);
|
||||
if (error)
|
||||
@ -378,7 +380,9 @@ iso_mountfs(devvp, mp, td)
|
||||
mp->mnt_stat.f_fsid.val[0] = dev2udev(dev);
|
||||
mp->mnt_stat.f_fsid.val[1] = mp->mnt_vfc->vfc_typenum;
|
||||
mp->mnt_maxsymlinklen = 0;
|
||||
MNT_ILOCK(mp);
|
||||
mp->mnt_flag |= MNT_LOCAL;
|
||||
MNT_IUNLOCK(mp);
|
||||
isomp->im_mountp = mp;
|
||||
isomp->im_dev = dev;
|
||||
isomp->im_devvp = devvp;
|
||||
@ -528,7 +532,9 @@ cd9660_unmount(mp, mntflags, td)
|
||||
vrele(isomp->im_devvp);
|
||||
free((caddr_t)isomp, M_ISOFSMNT);
|
||||
mp->mnt_data = (qaddr_t)0;
|
||||
MNT_ILOCK(mp);
|
||||
mp->mnt_flag &= ~MNT_LOCAL;
|
||||
MNT_IUNLOCK(mp);
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
@ -79,11 +79,13 @@ devfs_mount(struct mount *mp, struct thread *td)
|
||||
sx_init(&fmp->dm_lock, "devfsmount");
|
||||
fmp->dm_holdcnt = 1;
|
||||
|
||||
MNT_ILOCK(mp);
|
||||
mp->mnt_flag |= MNT_LOCAL;
|
||||
mp->mnt_kern_flag |= MNTK_MPSAFE;
|
||||
#ifdef MAC
|
||||
mp->mnt_flag |= MNT_MULTILABEL;
|
||||
#endif
|
||||
MNT_IUNLOCK(mp);
|
||||
fmp->dm_mount = mp;
|
||||
mp->mnt_data = (void *) fmp;
|
||||
vfs_getnewfsid(mp);
|
||||
|
@ -315,7 +315,9 @@ hpfs_mountfs(devvp, mp, td)
|
||||
mp->mnt_stat.f_fsid.val[0] = (long)dev2udev(dev);
|
||||
mp->mnt_stat.f_fsid.val[1] = mp->mnt_vfc->vfc_typenum;
|
||||
mp->mnt_maxsymlinklen = 0;
|
||||
MNT_ILOCK(mp);
|
||||
mp->mnt_flag |= MNT_LOCAL;
|
||||
MNT_IUNLOCK(mp);
|
||||
return (0);
|
||||
|
||||
failed:
|
||||
@ -359,7 +361,9 @@ hpfs_unmount(
|
||||
hpfs_cpdeinit(hpmp);
|
||||
hpfs_bmdeinit(hpmp);
|
||||
mp->mnt_data = (qaddr_t)0;
|
||||
MNT_ILOCK(mp);
|
||||
mp->mnt_flag &= ~MNT_LOCAL;
|
||||
MNT_IUNLOCK(mp);
|
||||
FREE(hpmp, M_HPFSMNT);
|
||||
|
||||
return (0);
|
||||
|
@ -706,7 +706,9 @@ mountmsdosfs(devvp, mp, td)
|
||||
mp->mnt_data = (qaddr_t) pmp;
|
||||
mp->mnt_stat.f_fsid.val[0] = dev2udev(dev);
|
||||
mp->mnt_stat.f_fsid.val[1] = mp->mnt_vfc->vfc_typenum;
|
||||
MNT_ILOCK(mp);
|
||||
mp->mnt_flag |= MNT_LOCAL;
|
||||
MNT_IUNLOCK(mp);
|
||||
|
||||
#ifdef MSDOSFS_LARGE
|
||||
msdosfs_fileno_init(mp);
|
||||
@ -798,7 +800,9 @@ msdosfs_unmount(mp, mntflags, td)
|
||||
#endif
|
||||
free(pmp, M_MSDOSFSMNT);
|
||||
mp->mnt_data = (qaddr_t)0;
|
||||
MNT_ILOCK(mp);
|
||||
mp->mnt_flag &= ~MNT_LOCAL;
|
||||
MNT_IUNLOCK(mp);
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
@ -430,7 +430,9 @@ ntfs_mountfs(devvp, mp, td)
|
||||
mp->mnt_stat.f_fsid.val[0] = dev2udev(dev);
|
||||
mp->mnt_stat.f_fsid.val[1] = mp->mnt_vfc->vfc_typenum;
|
||||
mp->mnt_maxsymlinklen = 0;
|
||||
MNT_ILOCK(mp);
|
||||
mp->mnt_flag |= MNT_LOCAL;
|
||||
MNT_IUNLOCK(mp);
|
||||
return (0);
|
||||
|
||||
out1:
|
||||
@ -507,7 +509,9 @@ ntfs_unmount(
|
||||
ntfs_u28_uninit(ntmp);
|
||||
ntfs_82u_uninit(ntmp);
|
||||
mp->mnt_data = (qaddr_t)0;
|
||||
MNT_ILOCK(mp);
|
||||
mp->mnt_flag &= ~MNT_LOCAL;
|
||||
MNT_IUNLOCK(mp);
|
||||
FREE(ntmp->ntm_ad, M_NTFSMNT);
|
||||
FREE(ntmp, M_NTFSMNT);
|
||||
return (error);
|
||||
|
@ -179,9 +179,14 @@ nullfs_mount(struct mount *mp, struct thread *td)
|
||||
*/
|
||||
VOP_UNLOCK(vp, 0, td);
|
||||
|
||||
if (NULLVPTOLOWERVP(nullm_rootvp)->v_mount->mnt_flag & MNT_LOCAL)
|
||||
if (NULLVPTOLOWERVP(nullm_rootvp)->v_mount->mnt_flag & MNT_LOCAL) {
|
||||
MNT_ILOCK(mp);
|
||||
mp->mnt_flag |= MNT_LOCAL;
|
||||
MNT_IUNLOCK(mp);
|
||||
}
|
||||
MNT_ILOCK(mp);
|
||||
mp->mnt_kern_flag |= lowerrootvp->v_mount->mnt_kern_flag & MNTK_MPSAFE;
|
||||
MNT_IUNLOCK(mp);
|
||||
mp->mnt_data = (qaddr_t) xmp;
|
||||
vfs_getnewfsid(mp);
|
||||
|
||||
|
@ -267,7 +267,9 @@ nwfs_unmount(struct mount *mp, int mntflags, struct thread *td)
|
||||
if (nmp->m.flags & NWFS_MOUNT_HAVE_NLS)
|
||||
free(nmp->m.nls.to_lower, M_NWFSDATA);
|
||||
free(nmp, M_NWFSDATA);
|
||||
MNT_ILOCK(mp);
|
||||
mp->mnt_flag &= ~MNT_LOCAL;
|
||||
MNT_IUNLOCK(mp);
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
@ -146,7 +146,9 @@ portal_mount(struct mount *mp, struct thread *td)
|
||||
fhold(fp);
|
||||
fmp->pm_server = fp;
|
||||
|
||||
MNT_ILOCK(mp);
|
||||
mp->mnt_flag |= MNT_LOCAL;
|
||||
MNT_IUNLOCK(mp);
|
||||
mp->mnt_data = (qaddr_t) fmp;
|
||||
vfs_getnewfsid(mp);
|
||||
|
||||
|
@ -318,7 +318,9 @@ smbfs_unmount(struct mount *mp, int mntflags, struct thread *td)
|
||||
#else
|
||||
free(smp, M_SMBFSDATA);
|
||||
#endif
|
||||
MNT_ILOCK(mp);
|
||||
mp->mnt_flag &= ~MNT_LOCAL;
|
||||
MNT_IUNLOCK(mp);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
@ -201,7 +201,9 @@ udf_mount(struct mount *mp, struct thread *td)
|
||||
/*
|
||||
* Unconditionally mount as read-only.
|
||||
*/
|
||||
MNT_ILOCK(mp);
|
||||
mp->mnt_flag |= MNT_RDONLY;
|
||||
MNT_IUNLOCK(mp);
|
||||
|
||||
/*
|
||||
* No root filesystem support. Probably not a big deal, since the
|
||||
@ -341,7 +343,9 @@ udf_mountfs(struct vnode *devvp, struct mount *mp, struct thread *td) {
|
||||
mp->mnt_data = (qaddr_t)udfmp;
|
||||
mp->mnt_stat.f_fsid.val[0] = dev2udev(devvp->v_rdev);
|
||||
mp->mnt_stat.f_fsid.val[1] = mp->mnt_vfc->vfc_typenum;
|
||||
MNT_ILOCK(mp);
|
||||
mp->mnt_flag |= MNT_LOCAL;
|
||||
MNT_IUNLOCK(mp);
|
||||
udfmp->im_mountp = mp;
|
||||
udfmp->im_dev = devvp->v_rdev;
|
||||
udfmp->im_devvp = devvp;
|
||||
@ -532,7 +536,9 @@ udf_unmount(struct mount *mp, int mntflags, struct thread *td)
|
||||
FREE(udfmp, M_UDFMOUNT);
|
||||
|
||||
mp->mnt_data = (qaddr_t)0;
|
||||
MNT_ILOCK(mp);
|
||||
mp->mnt_flag &= ~MNT_LOCAL;
|
||||
MNT_IUNLOCK(mp);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
@ -216,8 +216,11 @@ umapfs_omount(mp, path, data, ndp, td)
|
||||
umapm_rootvp = vp;
|
||||
umapm_rootvp->v_vflag |= VV_ROOT;
|
||||
amp->umapm_rootvp = umapm_rootvp;
|
||||
if (UMAPVPTOLOWERVP(umapm_rootvp)->v_mount->mnt_flag & MNT_LOCAL)
|
||||
if (UMAPVPTOLOWERVP(umapm_rootvp)->v_mount->mnt_flag & MNT_LOCAL) {
|
||||
MNT_ILOCK(mp);
|
||||
mp->mnt_flag |= MNT_LOCAL;
|
||||
MNT_IUNLOCK(mp);
|
||||
}
|
||||
mp->mnt_data = (qaddr_t) amp;
|
||||
vfs_getnewfsid(mp);
|
||||
|
||||
|
@ -86,7 +86,9 @@ union_mount(mp, td)
|
||||
/*
|
||||
* Disable clustered write, otherwise system becomes unstable.
|
||||
*/
|
||||
MNT_ILOCK(mp);
|
||||
mp->mnt_flag |= MNT_NOCLUSTERW;
|
||||
MNT_IUNLOCK(mp);
|
||||
|
||||
if (mp->mnt_flag & MNT_ROOTFS)
|
||||
return (EOPNOTSUPP);
|
||||
@ -246,8 +248,11 @@ union_mount(mp, td)
|
||||
if (um->um_op == UNMNT_ABOVE) {
|
||||
if (((um->um_lowervp == NULLVP) ||
|
||||
(um->um_lowervp->v_mount->mnt_flag & MNT_LOCAL)) &&
|
||||
(um->um_uppervp->v_mount->mnt_flag & MNT_LOCAL))
|
||||
(um->um_uppervp->v_mount->mnt_flag & MNT_LOCAL)) {
|
||||
MNT_ILOCK(mp);
|
||||
mp->mnt_flag |= MNT_LOCAL;
|
||||
MNT_IUNLOCK(mp);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -257,7 +262,9 @@ union_mount(mp, td)
|
||||
* mount of the underlying filesystem to go from rdonly to rdwr
|
||||
* will leave the unioned view as read-only.
|
||||
*/
|
||||
MNT_ILOCK(mp);
|
||||
mp->mnt_flag |= (um->um_uppervp->v_mount->mnt_flag & MNT_RDONLY);
|
||||
MNT_IUNLOCK(mp);
|
||||
|
||||
mp->mnt_data = (qaddr_t) um;
|
||||
vfs_getnewfsid(mp);
|
||||
|
@ -230,7 +230,9 @@ ext2_mount(mp, td)
|
||||
fs->s_es->s_state &= ~EXT2_VALID_FS;
|
||||
ext2_sbupdate(ump, MNT_WAIT);
|
||||
fs->s_rd_only = 0;
|
||||
MNT_ILOCK(mp);
|
||||
mp->mnt_flag &= ~MNT_RDONLY;
|
||||
MNT_IUNLOCK(mp);
|
||||
}
|
||||
if (vfs_flagopt(opts, "export", NULL, 0)) {
|
||||
/* Process export requests in vfs_mount.c. */
|
||||
@ -683,7 +685,9 @@ ext2_mountfs(devvp, mp, td)
|
||||
mp->mnt_stat.f_fsid.val[0] = dev2udev(dev);
|
||||
mp->mnt_stat.f_fsid.val[1] = mp->mnt_vfc->vfc_typenum;
|
||||
mp->mnt_maxsymlinklen = EXT2_MAXSYMLINKLEN;
|
||||
MNT_ILOCK(mp);
|
||||
mp->mnt_flag |= MNT_LOCAL;
|
||||
MNT_IUNLOCK(mp);
|
||||
ump->um_mountp = mp;
|
||||
ump->um_dev = dev;
|
||||
ump->um_devvp = devvp;
|
||||
@ -771,7 +775,9 @@ ext2_unmount(mp, mntflags, td)
|
||||
bsd_free(fs, M_EXT2MNT);
|
||||
bsd_free(ump, M_EXT2MNT);
|
||||
mp->mnt_data = (qaddr_t)0;
|
||||
MNT_ILOCK(mp);
|
||||
mp->mnt_flag &= ~MNT_LOCAL;
|
||||
MNT_IUNLOCK(mp);
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
@ -241,7 +241,9 @@ reiserfs_unmount(struct mount *mp, int mntflags, struct thread *td)
|
||||
}
|
||||
|
||||
mp->mnt_data = (qaddr_t)0;
|
||||
MNT_ILOCK(mp);
|
||||
mp->mnt_flag &= ~MNT_LOCAL;
|
||||
MNT_IUNLOCK(mp);
|
||||
|
||||
reiserfs_log(LOG_DEBUG, "done\n");
|
||||
return (error);
|
||||
@ -624,7 +626,9 @@ reiserfs_mountfs(struct vnode *devvp, struct mount *mp, struct thread *td)
|
||||
mp->mnt_data = (qaddr_t)rmp;
|
||||
mp->mnt_stat.f_fsid.val[0] = dev2udev(dev);
|
||||
mp->mnt_stat.f_fsid.val[1] = mp->mnt_vfc->vfc_typenum;
|
||||
MNT_ILOCK(mp);
|
||||
mp->mnt_flag |= MNT_LOCAL;
|
||||
MNT_IUNLOCK(mp);
|
||||
#if defined(si_mountpoint)
|
||||
devvp->v_rdev->si_mountpoint = mp;
|
||||
#endif
|
||||
|
@ -137,7 +137,9 @@ cd9660_mount(struct mount *mp, struct thread *td)
|
||||
/*
|
||||
* Unconditionally mount as read-only.
|
||||
*/
|
||||
MNT_ILOCK(mp);
|
||||
mp->mnt_flag |= MNT_RDONLY;
|
||||
MNT_IUNLOCK(mp);
|
||||
|
||||
fspec = vfs_getopts(mp->mnt_optnew, "from", &error);
|
||||
if (error)
|
||||
@ -378,7 +380,9 @@ iso_mountfs(devvp, mp, td)
|
||||
mp->mnt_stat.f_fsid.val[0] = dev2udev(dev);
|
||||
mp->mnt_stat.f_fsid.val[1] = mp->mnt_vfc->vfc_typenum;
|
||||
mp->mnt_maxsymlinklen = 0;
|
||||
MNT_ILOCK(mp);
|
||||
mp->mnt_flag |= MNT_LOCAL;
|
||||
MNT_IUNLOCK(mp);
|
||||
isomp->im_mountp = mp;
|
||||
isomp->im_dev = dev;
|
||||
isomp->im_devvp = devvp;
|
||||
@ -528,7 +532,9 @@ cd9660_unmount(mp, mntflags, td)
|
||||
vrele(isomp->im_devvp);
|
||||
free((caddr_t)isomp, M_ISOFSMNT);
|
||||
mp->mnt_data = (qaddr_t)0;
|
||||
MNT_ILOCK(mp);
|
||||
mp->mnt_flag &= ~MNT_LOCAL;
|
||||
MNT_IUNLOCK(mp);
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
@ -561,8 +561,10 @@ mqfs_mount(struct mount *mp, struct thread *td)
|
||||
return (EOPNOTSUPP);
|
||||
|
||||
mp->mnt_data = &mqfs_data;
|
||||
MNT_ILOCK(mp);
|
||||
mp->mnt_flag |= MNT_LOCAL;
|
||||
mp->mnt_kern_flag |= MNTK_MPSAFE;
|
||||
MNT_IUNLOCK(mp);
|
||||
vfs_getnewfsid(mp);
|
||||
|
||||
sbp = &mp->mnt_stat;
|
||||
|
@ -117,7 +117,9 @@ vfs_hang_addrlist(mp, nep, argp)
|
||||
bcopy(argp->ex_anon.cr_groups, np->netc_anon.cr_groups,
|
||||
sizeof(np->netc_anon.cr_groups));
|
||||
refcount_init(&np->netc_anon.cr_ref, 1);
|
||||
MNT_ILOCK(mp);
|
||||
mp->mnt_flag |= MNT_DEFEXPORTED;
|
||||
MNT_IUNLOCK(mp);
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -236,13 +238,17 @@ vfs_export(mp, argp)
|
||||
return (ENOENT);
|
||||
if (mp->mnt_flag & MNT_EXPUBLIC) {
|
||||
vfs_setpublicfs(NULL, NULL, NULL);
|
||||
MNT_ILOCK(mp);
|
||||
mp->mnt_flag &= ~MNT_EXPUBLIC;
|
||||
MNT_IUNLOCK(mp);
|
||||
}
|
||||
vfs_free_addrlist(nep);
|
||||
mp->mnt_export = NULL;
|
||||
free(nep, M_MOUNT);
|
||||
nep = NULL;
|
||||
MNT_ILOCK(mp);
|
||||
mp->mnt_flag &= ~(MNT_EXPORTED | MNT_DEFEXPORTED);
|
||||
MNT_IUNLOCK(mp);
|
||||
}
|
||||
if (argp->ex_flags & MNT_EXPORTED) {
|
||||
if (nep == NULL) {
|
||||
@ -252,11 +258,15 @@ vfs_export(mp, argp)
|
||||
if (argp->ex_flags & MNT_EXPUBLIC) {
|
||||
if ((error = vfs_setpublicfs(mp, nep, argp)) != 0)
|
||||
return (error);
|
||||
MNT_ILOCK(mp);
|
||||
mp->mnt_flag |= MNT_EXPUBLIC;
|
||||
MNT_IUNLOCK(mp);
|
||||
}
|
||||
if ((error = vfs_hang_addrlist(mp, nep, argp)))
|
||||
return (error);
|
||||
MNT_ILOCK(mp);
|
||||
mp->mnt_flag |= MNT_EXPORTED;
|
||||
MNT_IUNLOCK(mp);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
@ -133,11 +133,15 @@ sync(td, uap)
|
||||
vfslocked = VFS_LOCK_GIANT(mp);
|
||||
if ((mp->mnt_flag & MNT_RDONLY) == 0 &&
|
||||
vn_start_write(NULL, &mp, V_NOWAIT) == 0) {
|
||||
MNT_ILOCK(mp);
|
||||
asyncflag = mp->mnt_flag & MNT_ASYNC;
|
||||
mp->mnt_flag &= ~MNT_ASYNC;
|
||||
MNT_IUNLOCK(mp);
|
||||
vfs_msync(mp, MNT_NOWAIT);
|
||||
VFS_SYNC(mp, MNT_NOWAIT, td);
|
||||
MNT_ILOCK(mp);
|
||||
mp->mnt_flag |= asyncflag;
|
||||
MNT_IUNLOCK(mp);
|
||||
vn_finished_write(mp);
|
||||
}
|
||||
VFS_UNLOCK_GIANT(vfslocked);
|
||||
|
@ -471,7 +471,9 @@ vfs_mount_alloc(struct vnode *vp, struct vfsconf *vfsp,
|
||||
mp->mnt_vfc = vfsp;
|
||||
vfsp->vfc_refcount++; /* XXX Unlocked */
|
||||
mp->mnt_stat.f_type = vfsp->vfc_typenum;
|
||||
MNT_ILOCK(mp);
|
||||
mp->mnt_flag |= vfsp->vfc_flags & MNT_VISFLAGMASK;
|
||||
MNT_IUNLOCK(mp);
|
||||
strlcpy(mp->mnt_stat.f_fstypename, vfsp->vfc_name, MFSNAMELEN);
|
||||
mp->mnt_vnodecovered = vp;
|
||||
mp->mnt_cred = crdup(td->td_ucred);
|
||||
@ -848,6 +850,7 @@ vfs_domount(
|
||||
return (EINVAL);
|
||||
}
|
||||
mp = vp->v_mount;
|
||||
MNT_ILOCK(mp);
|
||||
flag = mp->mnt_flag;
|
||||
kern_flag = mp->mnt_kern_flag;
|
||||
/*
|
||||
@ -856,9 +859,11 @@ vfs_domount(
|
||||
*/
|
||||
if ((fsflags & MNT_RELOAD) &&
|
||||
((mp->mnt_flag & MNT_RDONLY) == 0)) {
|
||||
MNT_IUNLOCK(mp);
|
||||
vput(vp);
|
||||
return (EOPNOTSUPP); /* Needs translation */
|
||||
}
|
||||
MNT_IUNLOCK(mp);
|
||||
/*
|
||||
* Only privileged root, or (if MNT_USER is set) the user that
|
||||
* did the original mount is permitted to update it.
|
||||
@ -882,8 +887,10 @@ vfs_domount(
|
||||
}
|
||||
vp->v_iflag |= VI_MOUNT;
|
||||
VI_UNLOCK(vp);
|
||||
MNT_ILOCK(mp);
|
||||
mp->mnt_flag |= fsflags &
|
||||
(MNT_RELOAD | MNT_FORCE | MNT_UPDATE | MNT_SNAPSHOT | MNT_ROOTFS);
|
||||
MNT_IUNLOCK(mp);
|
||||
VOP_UNLOCK(vp, 0, td);
|
||||
mp->mnt_optnew = fsdata;
|
||||
vfs_mergeopts(mp->mnt_optnew, mp->mnt_opt);
|
||||
@ -935,10 +942,12 @@ vfs_domount(
|
||||
/*
|
||||
* Set the mount level flags.
|
||||
*/
|
||||
MNT_ILOCK(mp);
|
||||
if (fsflags & MNT_RDONLY)
|
||||
mp->mnt_flag |= MNT_RDONLY;
|
||||
mp->mnt_flag &=~ MNT_UPDATEMASK;
|
||||
mp->mnt_flag |= fsflags & (MNT_UPDATEMASK | MNT_FORCE | MNT_ROOTFS);
|
||||
MNT_IUNLOCK(mp);
|
||||
/*
|
||||
* Mount the filesystem.
|
||||
* XXX The final recipients of VFS_MOUNT just overwrite the ndp they
|
||||
@ -968,12 +977,14 @@ vfs_domount(
|
||||
*/
|
||||
mp->mnt_optnew = NULL;
|
||||
if (mp->mnt_flag & MNT_UPDATE) {
|
||||
MNT_ILOCK(mp);
|
||||
mp->mnt_flag &=
|
||||
~(MNT_UPDATE | MNT_RELOAD | MNT_FORCE | MNT_SNAPSHOT);
|
||||
if (error) {
|
||||
mp->mnt_flag = flag;
|
||||
mp->mnt_kern_flag = kern_flag;
|
||||
}
|
||||
MNT_IUNLOCK(mp);
|
||||
if ((mp->mnt_flag & MNT_RDONLY) == 0) {
|
||||
if (mp->mnt_syncer == NULL)
|
||||
error = vfs_allocate_syncvnode(mp);
|
||||
@ -1185,8 +1196,10 @@ dounmount(mp, flags, td)
|
||||
vfs_setpublicfs(NULL, NULL, NULL);
|
||||
|
||||
vfs_msync(mp, MNT_WAIT);
|
||||
MNT_ILOCK(mp);
|
||||
async_flag = mp->mnt_flag & MNT_ASYNC;
|
||||
mp->mnt_flag &= ~MNT_ASYNC;
|
||||
MNT_IUNLOCK(mp);
|
||||
cache_purgevfs(mp); /* remove cache entries for this file sys */
|
||||
if (mp->mnt_syncer != NULL)
|
||||
vrele(mp->mnt_syncer);
|
||||
|
@ -3081,12 +3081,16 @@ sync_fsync(struct vop_fsync_args *ap)
|
||||
vfs_unbusy(mp, td);
|
||||
return (0);
|
||||
}
|
||||
MNT_ILOCK(mp);
|
||||
asyncflag = mp->mnt_flag & MNT_ASYNC;
|
||||
mp->mnt_flag &= ~MNT_ASYNC;
|
||||
MNT_IUNLOCK(mp);
|
||||
vfs_msync(mp, MNT_NOWAIT);
|
||||
error = VFS_SYNC(mp, MNT_LAZY, td);
|
||||
MNT_ILOCK(mp);
|
||||
if (asyncflag)
|
||||
mp->mnt_flag |= MNT_ASYNC;
|
||||
MNT_IUNLOCK(mp);
|
||||
vn_finished_write(mp);
|
||||
vfs_unbusy(mp, td);
|
||||
return (error);
|
||||
|
@ -133,11 +133,15 @@ sync(td, uap)
|
||||
vfslocked = VFS_LOCK_GIANT(mp);
|
||||
if ((mp->mnt_flag & MNT_RDONLY) == 0 &&
|
||||
vn_start_write(NULL, &mp, V_NOWAIT) == 0) {
|
||||
MNT_ILOCK(mp);
|
||||
asyncflag = mp->mnt_flag & MNT_ASYNC;
|
||||
mp->mnt_flag &= ~MNT_ASYNC;
|
||||
MNT_IUNLOCK(mp);
|
||||
vfs_msync(mp, MNT_NOWAIT);
|
||||
VFS_SYNC(mp, MNT_NOWAIT, td);
|
||||
MNT_ILOCK(mp);
|
||||
mp->mnt_flag |= asyncflag;
|
||||
MNT_IUNLOCK(mp);
|
||||
vn_finished_write(mp);
|
||||
}
|
||||
VFS_UNLOCK_GIANT(vfslocked);
|
||||
|
@ -522,8 +522,10 @@ nfs_mountdiskless(char *path, int mountflag,
|
||||
struct sockaddr *nam;
|
||||
int error;
|
||||
|
||||
MNT_ILOCK(mp);
|
||||
mp->mnt_kern_flag = 0;
|
||||
mp->mnt_flag = mountflag;
|
||||
MNT_IUNLOCK(mp);
|
||||
nam = sodupsockaddr((struct sockaddr *)sin, M_WAITOK);
|
||||
if ((error = mountnfs(args, mp, nam, path, vpp,
|
||||
td->td_ucred)) != 0) {
|
||||
@ -548,10 +550,15 @@ nfs_decode_args(struct mount *mp, struct nfsmount *nmp, struct nfs_args *argp)
|
||||
* flag is already clear, or this is a root mount and it was set
|
||||
* intentionally at some previous point.
|
||||
*/
|
||||
if (vfs_getopt(mp->mnt_optnew, "ro", NULL, NULL) == 0)
|
||||
if (vfs_getopt(mp->mnt_optnew, "ro", NULL, NULL) == 0) {
|
||||
MNT_ILOCK(mp);
|
||||
mp->mnt_flag |= MNT_RDONLY;
|
||||
else if (mp->mnt_flag & MNT_UPDATE)
|
||||
MNT_IUNLOCK(mp);
|
||||
} else if (mp->mnt_flag & MNT_UPDATE) {
|
||||
MNT_ILOCK(mp);
|
||||
mp->mnt_flag &= ~MNT_RDONLY;
|
||||
MNT_IUNLOCK(mp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Silently clear NFSMNT_NOCONN if it's a TCP mount, it makes
|
||||
@ -784,8 +791,11 @@ nfs_mount(struct mount *mp, struct thread *td)
|
||||
args.fh = nfh;
|
||||
error = mountnfs(&args, mp, nam, hst, &vp, td->td_ucred);
|
||||
out:
|
||||
if (!error)
|
||||
if (!error) {
|
||||
MNT_ILOCK(mp);
|
||||
mp->mnt_kern_flag |= (MNTK_MPSAFE|MNTK_LOOKUP_SHARED);
|
||||
MNT_IUNLOCK(mp);
|
||||
}
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
@ -156,7 +156,7 @@ struct mount {
|
||||
int mnt_nvnodelistsize; /* (i) # of vnodes */
|
||||
int mnt_writeopcount; /* (i) write syscalls pending */
|
||||
int mnt_kern_flag; /* (i) kernel only flags */
|
||||
u_int mnt_flag; /* flags shared with user */
|
||||
u_int mnt_flag; /* (i) flags shared with user */
|
||||
struct vfsoptlist *mnt_opt; /* current mount options */
|
||||
struct vfsoptlist *mnt_optnew; /* new options passed to fs */
|
||||
int mnt_maxsymlinklen; /* max size of short symlink */
|
||||
|
@ -194,7 +194,7 @@ ffs_snapshot(mp, snapfile)
|
||||
ufs2_daddr_t numblks, blkno, *blkp, *snapblklist;
|
||||
int error, cg, snaploc;
|
||||
int i, size, len, loc;
|
||||
int flag = mp->mnt_flag;
|
||||
int flag;
|
||||
struct timespec starttime = {0, 0}, endtime;
|
||||
char saved_nice = 0;
|
||||
long redo = 0, snaplistsize = 0;
|
||||
@ -216,6 +216,9 @@ ffs_snapshot(mp, snapfile)
|
||||
ump = VFSTOUFS(mp);
|
||||
fs = ump->um_fs;
|
||||
sn = NULL;
|
||||
MNT_ILOCK(mp);
|
||||
flag = mp->mnt_flag;
|
||||
MNT_IUNLOCK(mp);
|
||||
|
||||
/*
|
||||
* Need to serialize access to snapshot code per filesystem.
|
||||
@ -828,7 +831,9 @@ ffs_snapshot(mp, snapfile)
|
||||
fs->fs_active = 0;
|
||||
}
|
||||
UFS_UNLOCK(ump);
|
||||
MNT_ILOCK(mp);
|
||||
mp->mnt_flag = flag;
|
||||
MNT_IUNLOCK(mp);
|
||||
if (error)
|
||||
(void) ffs_truncate(vp, (off_t)0, 0, NOCRED, td);
|
||||
(void) ffs_syncvnode(vp, MNT_WAIT);
|
||||
|
@ -1423,8 +1423,10 @@ softdep_mount(devvp, mp, fs, cred)
|
||||
struct buf *bp;
|
||||
int error, cyl;
|
||||
|
||||
MNT_ILOCK(mp);
|
||||
mp->mnt_flag &= ~MNT_ASYNC;
|
||||
mp->mnt_flag |= MNT_SOFTDEP;
|
||||
MNT_IUNLOCK(mp);
|
||||
ump = VFSTOUFS(mp);
|
||||
LIST_INIT(&ump->softdep_workitem_pending);
|
||||
ump->softdep_worklist_tail = NULL;
|
||||
|
@ -129,6 +129,7 @@ ffs_mount(struct mount *mp, struct thread *td)
|
||||
struct ufsmount *ump = 0;
|
||||
struct fs *fs;
|
||||
int error, flags;
|
||||
u_int mntorflags, mntandnotflags;
|
||||
mode_t accessmode;
|
||||
struct nameidata ndp;
|
||||
char *fspec;
|
||||
@ -151,33 +152,38 @@ ffs_mount(struct mount *mp, struct thread *td)
|
||||
if (error)
|
||||
return (error);
|
||||
|
||||
mntorflags = 0;
|
||||
mntandnotflags = 0;
|
||||
if (vfs_getopt(mp->mnt_optnew, "acls", NULL, NULL) == 0)
|
||||
mp->mnt_flag |= MNT_ACLS;
|
||||
mntorflags |= MNT_ACLS;
|
||||
|
||||
if (vfs_getopt(mp->mnt_optnew, "async", NULL, NULL) == 0)
|
||||
mp->mnt_flag |= MNT_ASYNC;
|
||||
mntorflags |= MNT_ASYNC;
|
||||
|
||||
if (vfs_getopt(mp->mnt_optnew, "force", NULL, NULL) == 0)
|
||||
mp->mnt_flag |= MNT_FORCE;
|
||||
mntorflags |= MNT_FORCE;
|
||||
|
||||
if (vfs_getopt(mp->mnt_optnew, "multilabel", NULL, NULL) == 0)
|
||||
mp->mnt_flag |= MNT_MULTILABEL;
|
||||
mntorflags |= MNT_MULTILABEL;
|
||||
|
||||
if (vfs_getopt(mp->mnt_optnew, "noasync", NULL, NULL) == 0)
|
||||
mp->mnt_flag &= ~MNT_ASYNC;
|
||||
mntandnotflags |= MNT_ASYNC;
|
||||
|
||||
if (vfs_getopt(mp->mnt_optnew, "noatime", NULL, NULL) == 0)
|
||||
mp->mnt_flag |= MNT_NOATIME;
|
||||
mntorflags |= MNT_NOATIME;
|
||||
|
||||
if (vfs_getopt(mp->mnt_optnew, "noclusterr", NULL, NULL) == 0)
|
||||
mp->mnt_flag |= MNT_NOCLUSTERR;
|
||||
mntorflags |= MNT_NOCLUSTERR;
|
||||
|
||||
if (vfs_getopt(mp->mnt_optnew, "noclusterw", NULL, NULL) == 0)
|
||||
mp->mnt_flag |= MNT_NOCLUSTERW;
|
||||
mntorflags |= MNT_NOCLUSTERW;
|
||||
|
||||
if (vfs_getopt(mp->mnt_optnew, "snapshot", NULL, NULL) == 0)
|
||||
mp->mnt_flag |= MNT_SNAPSHOT;
|
||||
mntorflags |= MNT_SNAPSHOT;
|
||||
|
||||
MNT_ILOCK(mp);
|
||||
mp->mnt_flag = (mp->mnt_flag | mntorflags) & ~mntandnotflags;
|
||||
MNT_IUNLOCK(mp);
|
||||
/*
|
||||
* If updating, check whether changing from read-only to
|
||||
* read/write; if there is no device name, that's all we do.
|
||||
@ -237,7 +243,9 @@ ffs_mount(struct mount *mp, struct thread *td)
|
||||
g_topology_unlock();
|
||||
PICKUP_GIANT();
|
||||
fs->fs_ronly = 1;
|
||||
MNT_ILOCK(mp);
|
||||
mp->mnt_flag |= MNT_RDONLY;
|
||||
MNT_IUNLOCK(mp);
|
||||
}
|
||||
if ((mp->mnt_flag & MNT_RELOAD) &&
|
||||
(error = ffs_reload(mp, td)) != 0)
|
||||
@ -289,7 +297,9 @@ ffs_mount(struct mount *mp, struct thread *td)
|
||||
if ((error = vn_start_write(NULL, &mp, V_WAIT)) != 0)
|
||||
return (error);
|
||||
fs->fs_ronly = 0;
|
||||
MNT_ILOCK(mp);
|
||||
mp->mnt_flag &= ~MNT_RDONLY;
|
||||
MNT_IUNLOCK(mp);
|
||||
fs->fs_clean = 0;
|
||||
if ((error = ffs_sbupdate(ump, MNT_WAIT, 0)) != 0) {
|
||||
vn_finished_write(mp);
|
||||
@ -312,13 +322,21 @@ ffs_mount(struct mount *mp, struct thread *td)
|
||||
* Softdep_mount() clears it in an initial mount
|
||||
* or ro->rw remount.
|
||||
*/
|
||||
if (mp->mnt_flag & MNT_SOFTDEP)
|
||||
if (mp->mnt_flag & MNT_SOFTDEP) {
|
||||
/* XXX: Reset too late ? */
|
||||
MNT_ILOCK(mp);
|
||||
mp->mnt_flag &= ~MNT_ASYNC;
|
||||
MNT_IUNLOCK(mp);
|
||||
}
|
||||
/*
|
||||
* Keep MNT_ACLS flag if it is stored in superblock.
|
||||
*/
|
||||
if ((fs->fs_flags & FS_ACLS) != 0)
|
||||
if ((fs->fs_flags & FS_ACLS) != 0) {
|
||||
/* XXX: Set too late ? */
|
||||
MNT_ILOCK(mp);
|
||||
mp->mnt_flag |= MNT_ACLS;
|
||||
MNT_IUNLOCK(mp);
|
||||
}
|
||||
|
||||
/*
|
||||
* If this is a snapshot request, take the snapshot.
|
||||
@ -745,23 +763,31 @@ ffs_mountfs(devvp, mp, td)
|
||||
vfs_getnewfsid(mp);
|
||||
}
|
||||
mp->mnt_maxsymlinklen = fs->fs_maxsymlinklen;
|
||||
MNT_ILOCK(mp);
|
||||
mp->mnt_flag |= MNT_LOCAL;
|
||||
if ((fs->fs_flags & FS_MULTILABEL) != 0)
|
||||
MNT_IUNLOCK(mp);
|
||||
if ((fs->fs_flags & FS_MULTILABEL) != 0) {
|
||||
#ifdef MAC
|
||||
MNT_ILOCK(mp);
|
||||
mp->mnt_flag |= MNT_MULTILABEL;
|
||||
MNT_IUNLOCK(mp);
|
||||
#else
|
||||
printf(
|
||||
"WARNING: %s: multilabel flag on fs but no MAC support\n",
|
||||
mp->mnt_stat.f_mntonname);
|
||||
#endif
|
||||
if ((fs->fs_flags & FS_ACLS) != 0)
|
||||
}
|
||||
if ((fs->fs_flags & FS_ACLS) != 0) {
|
||||
#ifdef UFS_ACL
|
||||
MNT_ILOCK(mp);
|
||||
mp->mnt_flag |= MNT_ACLS;
|
||||
MNT_IUNLOCK(mp);
|
||||
#else
|
||||
printf(
|
||||
"WARNING: %s: ACLs flag on fs but no ACLs support\n",
|
||||
mp->mnt_stat.f_mntonname);
|
||||
#endif
|
||||
}
|
||||
ump->um_mountp = mp;
|
||||
ump->um_dev = dev;
|
||||
ump->um_devvp = devvp;
|
||||
@ -825,7 +851,9 @@ ffs_mountfs(devvp, mp, td)
|
||||
*/
|
||||
devvp->v_bufobj.bo_flag |= BO_NEEDSGIANT;
|
||||
#else
|
||||
MNT_ILOCK(mp);
|
||||
mp->mnt_kern_flag |= MNTK_MPSAFE;
|
||||
MNT_IUNLOCK(mp);
|
||||
#endif
|
||||
return (0);
|
||||
out:
|
||||
@ -1003,7 +1031,9 @@ ffs_unmount(mp, mntflags, td)
|
||||
free(fs, M_UFSMNT);
|
||||
free(ump, M_UFSMNT);
|
||||
mp->mnt_data = (qaddr_t)0;
|
||||
MNT_ILOCK(mp);
|
||||
mp->mnt_flag &= ~MNT_LOCAL;
|
||||
MNT_IUNLOCK(mp);
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
@ -443,7 +443,9 @@ quotaon(td, mp, type, fname)
|
||||
if (*vpp != vp)
|
||||
quotaoff(td, mp, type);
|
||||
ump->um_qflags[type] |= QTF_OPENING;
|
||||
MNT_ILOCK(mp);
|
||||
mp->mnt_flag |= MNT_QUOTA;
|
||||
MNT_IUNLOCK(mp);
|
||||
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
|
||||
vp->v_vflag |= VV_SYSTEM;
|
||||
VOP_UNLOCK(vp, 0, td);
|
||||
@ -562,8 +564,11 @@ quotaoff(td, mp, type)
|
||||
for (type = 0; type < MAXQUOTAS; type++)
|
||||
if (ump->um_quotas[type] != NULLVP)
|
||||
break;
|
||||
if (type == MAXQUOTAS)
|
||||
if (type == MAXQUOTAS) {
|
||||
MNT_ILOCK(mp);
|
||||
mp->mnt_flag &= ~MNT_QUOTA;
|
||||
MNT_IUNLOCK(mp);
|
||||
}
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user