svn commit: r280760 - head/sys/ufs/ffs
Konstantin Belousov
kostikbel at gmail.com
Fri Mar 27 15:46:00 UTC 2015
On Fri, Mar 27, 2015 at 09:43:15AM -0600, Ian Lepore wrote:
> On Fri, 2015-03-27 at 13:55 +0000, 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.
> >
> > PR: 195458
> > In collaboration with: gjb, pho
> > Reviewed by: mckusick
> > Sponsored by: The FreeBSD Foundation
> > MFC after: 2 weeks
> >
> > Modified:
> > head/sys/ufs/ffs/ffs_softdep.c
> > head/sys/ufs/ffs/ffs_vfsops.c
>
> This is causing warning: function declaration isn't a prototype on
> platforms that still compile with old gcc. Simple fix, but I thought
> you might want to do the commit so you can get an mfc reminder along
> with the main commit.
>
> -- Ian
>
> Index: sys/ufs/ffs/ffs_softdep.c
> ===================================================================
> --- sys/ufs/ffs/ffs_softdep.c (revision 280761)
> +++ sys/ufs/ffs/ffs_softdep.c (working copy)
> @@ -804,6 +804,7 @@ static struct indirdep *indirdep_lookup(struct mou
> struct buf *);
> static void cancel_indirdep(struct indirdep *, struct buf *,
> struct freeblks *);
> +static int check_inodedep_free(struct inodedep *);
> static void free_indirdep(struct indirdep *);
> static void free_diradd(struct diradd *, struct workhead *);
> static void merge_diradd(struct inodedep *, struct diradd *);
>
Yes, thank you. I was already notified and trying to compile ppc GENERIC64
kernel to confirm the same fix.
Did you compile-tested the change on arm with gcc ? If so, I will just
commit it.
More information about the svn-src-head
mailing list