Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 15 Jan 2020 18:53:32 +0000 (UTC)
From:      Kirk McKusick <mckusick@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r356763 - head/sys/kern
Message-ID:  <202001151853.00FIrW61077469@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mckusick
Date: Wed Jan 15 18:53:32 2020
New Revision: 356763
URL: https://svnweb.freebsd.org/changeset/base/356763

Log:
  Peter Holm reports that his test that does an umount(8) on an active
  mount point while numerous tests are running that are writing to
  files on that mount point cause the unmount(8) to hang forever.
  
  The unmount(8) system call is handled in the kernel by the dounmount()
  function. The cause of the hang is that prior to dounmount() calling
  VFS_UNMOUNT() it is calling VFS_SYNC(mp, MNT_WAIT). The MNT_WAIT
  flag indicates that VFS_SYNC() should not return until all the dirty
  buffers associated with the mount point have been written to disk.
  Because user processes are allowed to continue writing and can do
  so faster than the data can be written to disk, the call to VFS_SYNC()
  can never finish.
  
  Unlike VFS_SYNC(), the VFS_UNMOUNT() routine can suspend all processes
  when they request to do a write thus having a finite number of dirty
  buffers to write that cannot be expanded. There is no need to call
  VFS_SYNC() before calling VFS_UNMOUNT(), because VFS_UNMOUNT() needs
  to flush everything again anyway after suspending writes, to catch
  anything that was dirtied between the VFS_SYNC() and writes being
  suspended.
  
  The fix is to simply remove the unnecessary call to VFS_SYNC() from
  dounmount().
  
  Reported by:  Peter Holm
  Analysis by:  Chuck Silvers
  Tested by:    Peter Holm
  MFC after:    7 days
  Sponsored by: Netflix

Modified:
  head/sys/kern/vfs_mount.c

Modified: head/sys/kern/vfs_mount.c
==============================================================================
--- head/sys/kern/vfs_mount.c	Wed Jan 15 16:47:44 2020	(r356762)
+++ head/sys/kern/vfs_mount.c	Wed Jan 15 18:53:32 2020	(r356763)
@@ -1696,9 +1696,7 @@ dounmount(struct mount *mp, int flags, struct thread *
 	MNT_IUNLOCK(mp);
 	cache_purgevfs(mp, false); /* remove cache entries for this file sys */
 	vfs_deallocate_syncvnode(mp);
-	if ((mp->mnt_flag & MNT_RDONLY) != 0 || (flags & MNT_FORCE) != 0 ||
-	    (error = VFS_SYNC(mp, MNT_WAIT)) == 0)
-		error = VFS_UNMOUNT(mp, flags);
+	error = VFS_UNMOUNT(mp, flags);
 	vn_finished_write(mp);
 	/*
 	 * If we failed to flush the dirty blocks for this mount point,



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202001151853.00FIrW61077469>