Date: Mon, 30 Mar 2015 11:05:18 -0400 From: John Baldwin <jhb@freebsd.org> To: Konstantin Belousov <kib@freebsd.org> Cc: svn-src-head@freebsd.org, svn-src-all@freebsd.org, src-committers@freebsd.org Subject: Re: svn commit: r280760 - head/sys/ufs/ffs Message-ID: <1562745.HBh4GIei5X@ralph.baldwin.cx> In-Reply-To: <201503271355.t2RDtuLt071068@svn.freebsd.org> References: <201503271355.t2RDtuLt071068@svn.freebsd.org>
next in thread | previous in thread | raw e-mail | index | archive | help
On Friday, March 27, 2015 01:55:56 PM Konstantin Belousov wrote: > Author: kib > Date: Fri Mar 27 13:55:56 2015 > New Revision: 280760 > URL: https://svnweb.freebsd.org/changeset/base/280760 > > Log: > Fix the hand after the immediate reboot when the following command > sequence is performed on UFS SU+J rootfs: > cp -Rp /sbin/init /sbin/init.old > mv -f /sbin/init.old /sbin/init > > Hang occurs on the rootfs unmount. There are two issues: > > 1. Removed init binary, which is still mapped, creates a reference to > the removed vnode. The inodeblock for such vnode must have active > inodedep, which is (eventually) linked through the unlinked list. This > means that ffs_sync(MNT_SUSPEND) cannot succeed, because number of > softdep workitems for the mp is always > 0. FFS is suspended during > unmount, so unmount just hangs. > > 2. As noted above, the inodedep is linked eventually. It is not > linked until the superblock is written. But at the vfs_unmountall() > time, when the rootfs is unmounted, the call is made to > ffs_unmount()->ffs_sync() before vflush(), and ffs_sync() only calls > ffs_sbupdate() after all workitems are flushed. It is masked for > normal system operations, because syncer works in parallel and > eventually flushes superblock. Syncer is stopped when rootfs > unmounted, so ffs_sync() must do sb update on its own. > > Correct the issues listed above. For MNT_SUSPEND, count the number of > linked unlinked inodedeps (this is not a typo) and substract the count > of such workitems from the total. For the second issue, the > ffs_sbupdate() is called right after device sync in ffs_sync() loop. > > There is third problem, occuring with both SU and SU+J. The > softdep_waitidle() loop, which waits for softdep_flush() thread to > clear the worklist, only waits 20ms max. It seems that the 1 tick, > specified for msleep(9), was a typo. > > Add fsync(devvp, MNT_WAIT) call to softdep_waitidle(), which seems to > significantly help the softdep thread, and change the MNT_LAZY update > at the reboot time to MNT_WAIT for similar reasons. Note that > userspace cannot create more work while devvp is flushed, since the > mount point is always suspended before the call to softdep_waitidle() > in unmount or remount path. Nice find! -- John Baldwin
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?1562745.HBh4GIei5X>