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:
parent
46d29cab25
commit
815b74866a
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user