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
This commit is contained in:
Jeff Roberson 2020-01-14 02:00:24 +00:00
parent 46d29cab25
commit 815b74866a

View File

@ -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;