Author: kib
Date: Mon Apr  8 15:20:05 2019
New Revision: 346031
URL: https://svnweb.freebsd.org/changeset/base/346031

Log:
  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

Modified:
  head/sys/ufs/ffs/ffs_vfsops.c

Modified: head/sys/ufs/ffs/ffs_vfsops.c
==============================================================================
--- head/sys/ufs/ffs/ffs_vfsops.c       Mon Apr  8 14:31:07 2019        
(r346030)
+++ head/sys/ufs/ffs/ffs_vfsops.c       Mon Apr  8 15:20:05 2019        
(r346031)
@@ -154,7 +154,7 @@ ffs_mount(struct mount *mp)
        struct fs *fs;
        pid_t fsckpid = 0;
        int error, error1, flags;
-       uint64_t mntorflags;
+       uint64_t mntorflags, saved_mnt_flag;
        accmode_t accmode;
        struct nameidata ndp;
        char *fspec;
@@ -371,25 +371,40 @@ ffs_mount(struct mount *mp)
                                return (error);
                        if ((error = vn_start_write(NULL, &mp, V_WAIT)) != 0)
                                return (error);
+                       error = vfs_write_suspend_umnt(mp);
+                       if (error != 0)
+                               return (error);
                        fs->fs_ronly = 0;
                        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);
                        fs->fs_mtime = time_second;
                        /* check to see if we need to start softdep */
                        if ((fs->fs_flags & FS_DOSOFTDEP) &&
                            (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);
                        }
                        fs->fs_clean = 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);
                        }
                        if (fs->fs_snapinum[0] != 0)
                                ffs_snapshot_mount(mp);
-                       vn_finished_write(mp);
+                       vfs_write_resume(mp, 0);
                }
                /*
                 * Soft updates is incompatible with "async",


_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to