svn commit: r356714 - head/sys/ufs/ffs
Jeff Roberson
jeff at FreeBSD.org
Tue Jan 14 02:00:24 UTC 2020
Author: jeff
Date: Tue Jan 14 02:00:24 2020
New Revision: 356714
URL: https://svnweb.freebsd.org/changeset/base/356714
Log:
Fix a long standing bug in journaled soft-updates. The dirrem structure
needs to handle file removal, directory removal, file move, directory move,
etc. The code in handle_workitem_remove() needs to propagate any completed
journal entries to the write that will render the change stable. In the
case of a moved directory this means the new parent. However, for an
overwrite that frees a directory (DIRCHG) we must move the jsegdep to the
removed inode to be released when it is stable in the cg bitmap or the
unlinked inode list. This case was previously unhandled and caused a
panic.
Reported by: mckusick, pho
Reviewed by: mckusick
Tested by: pho
Modified:
head/sys/ufs/ffs/ffs_softdep.c
Modified: head/sys/ufs/ffs/ffs_softdep.c
==============================================================================
--- head/sys/ufs/ffs/ffs_softdep.c Tue Jan 14 01:43:04 2020 (r356713)
+++ head/sys/ufs/ffs/ffs_softdep.c Tue Jan 14 02:00:24 2020 (r356714)
@@ -9849,14 +9849,20 @@ handle_workitem_remove(dirrem, flags)
/*
* Move all dependencies waiting on the remove to complete
* from the dirrem to the inode inowait list to be completed
- * after the inode has been updated and written to disk. Any
- * marked MKDIR_PARENT are saved to be completed when the .. ref
- * is removed.
+ * after the inode has been updated and written to disk.
+ *
+ * Any marked MKDIR_PARENT are saved to be completed when the
+ * dotdot ref is removed unless DIRCHG is specified. For
+ * directory change operations there will be no further
+ * directory writes and the jsegdeps need to be moved along
+ * with the rest to be completed when the inode is free or
+ * stable in the inode free list.
*/
LIST_INIT(&dotdotwk);
while ((wk = LIST_FIRST(&dirrem->dm_jwork)) != NULL) {
WORKLIST_REMOVE(wk);
- if (wk->wk_state & MKDIR_PARENT) {
+ if ((dirrem->dm_state & DIRCHG) == 0 &&
+ wk->wk_state & MKDIR_PARENT) {
wk->wk_state &= ~MKDIR_PARENT;
WORKLIST_INSERT(&dotdotwk, wk);
continue;
More information about the svn-src-head
mailing list