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:
Tor Egge 2006-09-26 04:12:49 +00:00
parent b14f05094a
commit 5da56ddb21
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=162647
27 changed files with 174 additions and 22 deletions

View File

@ -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);
}

View File

@ -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);

View File

@ -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);

View File

@ -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);
}

View File

@ -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);

View File

@ -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);

View File

@ -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);
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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);

View File

@ -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);

View File

@ -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);
}

View File

@ -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

View File

@ -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);
}

View File

@ -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;

View File

@ -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);
}

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);
}

View File

@ -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 */

View File

@ -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);

View File

@ -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;

View File

@ -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);
}

View File

@ -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);
}