Handle races when remounting UFS volume from ro to rw.
In particular, ensure that writers are not unleashed before SU structures are initialized. Also, correctly handle MNT_ASYNC before this. Reported and tested by: pho Reviewed by: mckusick Sponsored by: The FreeBSD Foundation MFC after: 1 week
This commit is contained in:
parent
9274fb3599
commit
5ffc99e2e4
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=346031
@ -154,7 +154,7 @@ ffs_mount(struct mount *mp)
|
|||||||
struct fs *fs;
|
struct fs *fs;
|
||||||
pid_t fsckpid = 0;
|
pid_t fsckpid = 0;
|
||||||
int error, error1, flags;
|
int error, error1, flags;
|
||||||
uint64_t mntorflags;
|
uint64_t mntorflags, saved_mnt_flag;
|
||||||
accmode_t accmode;
|
accmode_t accmode;
|
||||||
struct nameidata ndp;
|
struct nameidata ndp;
|
||||||
char *fspec;
|
char *fspec;
|
||||||
@ -371,25 +371,40 @@ ffs_mount(struct mount *mp)
|
|||||||
return (error);
|
return (error);
|
||||||
if ((error = vn_start_write(NULL, &mp, V_WAIT)) != 0)
|
if ((error = vn_start_write(NULL, &mp, V_WAIT)) != 0)
|
||||||
return (error);
|
return (error);
|
||||||
|
error = vfs_write_suspend_umnt(mp);
|
||||||
|
if (error != 0)
|
||||||
|
return (error);
|
||||||
fs->fs_ronly = 0;
|
fs->fs_ronly = 0;
|
||||||
MNT_ILOCK(mp);
|
MNT_ILOCK(mp);
|
||||||
mp->mnt_flag &= ~MNT_RDONLY;
|
saved_mnt_flag = MNT_RDONLY;
|
||||||
|
if (MOUNTEDSOFTDEP(mp) && (mp->mnt_flag &
|
||||||
|
MNT_ASYNC) != 0)
|
||||||
|
saved_mnt_flag |= MNT_ASYNC;
|
||||||
|
mp->mnt_flag &= ~saved_mnt_flag;
|
||||||
MNT_IUNLOCK(mp);
|
MNT_IUNLOCK(mp);
|
||||||
fs->fs_mtime = time_second;
|
fs->fs_mtime = time_second;
|
||||||
/* check to see if we need to start softdep */
|
/* check to see if we need to start softdep */
|
||||||
if ((fs->fs_flags & FS_DOSOFTDEP) &&
|
if ((fs->fs_flags & FS_DOSOFTDEP) &&
|
||||||
(error = softdep_mount(devvp, mp, fs, td->td_ucred))){
|
(error = softdep_mount(devvp, mp, fs, td->td_ucred))){
|
||||||
vn_finished_write(mp);
|
fs->fs_ronly = 1;
|
||||||
|
MNT_ILOCK(mp);
|
||||||
|
mp->mnt_flag |= saved_mnt_flag;
|
||||||
|
MNT_IUNLOCK(mp);
|
||||||
|
vfs_write_resume(mp, 0);
|
||||||
return (error);
|
return (error);
|
||||||
}
|
}
|
||||||
fs->fs_clean = 0;
|
fs->fs_clean = 0;
|
||||||
if ((error = ffs_sbupdate(ump, MNT_WAIT, 0)) != 0) {
|
if ((error = ffs_sbupdate(ump, MNT_WAIT, 0)) != 0) {
|
||||||
vn_finished_write(mp);
|
fs->fs_ronly = 1;
|
||||||
|
MNT_ILOCK(mp);
|
||||||
|
mp->mnt_flag |= saved_mnt_flag;
|
||||||
|
MNT_IUNLOCK(mp);
|
||||||
|
vfs_write_resume(mp, 0);
|
||||||
return (error);
|
return (error);
|
||||||
}
|
}
|
||||||
if (fs->fs_snapinum[0] != 0)
|
if (fs->fs_snapinum[0] != 0)
|
||||||
ffs_snapshot_mount(mp);
|
ffs_snapshot_mount(mp);
|
||||||
vn_finished_write(mp);
|
vfs_write_resume(mp, 0);
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* Soft updates is incompatible with "async",
|
* Soft updates is incompatible with "async",
|
||||||
|
Loading…
Reference in New Issue
Block a user