Handle missing jremrefs when a directory is renamed overtop of

another, deleting it.  If the directory is removed, UFS always need to
remove the .. ref, even if the ultimate ref on the parent would not
change. The new directory must have a new journal entry for that ref.
Otherwise journal processing would not properly account for the
parent's reference since it will belong to a removed directory entry.

Change ufs_rename()'s dotdot rename section to always
setup_dotdot_link(). In the tip != NULL case SUJ needs the newref dependency
allocated via setup_dotdot_link().

Stop setting isrmdir to 2 for newdirrem() in softdep_setup_remove().
Remove the isdirrem > 1 checks from newdirrem().

Reported by:	many
Submitted by:	jeff
Tested by:	pho
This commit is contained in:
Konstantin Belousov 2010-12-30 10:52:07 +00:00
parent 42a6fc4385
commit 465e3ccdbb
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=216818
2 changed files with 8 additions and 8 deletions

View File

@ -6918,7 +6918,7 @@ softdep_setup_remove(bp, dp, ip, isrmdir)
* newdirrem() to setup the full directory remove which requires
* isrmdir > 1.
*/
dirrem = newdirrem(bp, dp, ip, isrmdir?2:0, &prevdirrem);
dirrem = newdirrem(bp, dp, ip, isrmdir, &prevdirrem);
/*
* Add the dirrem to the inodedep's pending remove list for quick
* discovery later.
@ -7152,14 +7152,12 @@ newdirrem(bp, dp, ip, isrmdir, prevdirremp)
ip->i_effnlink + 2);
dotremref = newjremref(dirrem, ip, ip, DOT_OFFSET,
ip->i_effnlink + 1);
} else
jremref = newjremref(dirrem, dp, ip, dp->i_offset,
ip->i_effnlink + 1);
if (isrmdir > 1) {
dotdotremref = newjremref(dirrem, ip, dp, DOTDOT_OFFSET,
dp->i_effnlink + 1);
dotdotremref->jr_state |= MKDIR_PARENT;
}
} else
jremref = newjremref(dirrem, dp, ip, dp->i_offset,
ip->i_effnlink + 1);
}
ACQUIRE_LOCK(&lk);
lbn = lblkno(dp->i_fs, dp->i_offset);
@ -7184,7 +7182,7 @@ newdirrem(bp, dp, ip, isrmdir, prevdirremp)
* cancel it. Any pending journal work will be added to the dirrem
* to be completed when the workitem remove completes.
*/
if (isrmdir > 1)
if (isrmdir)
dotdotremref = cancel_diradd_dotdot(ip, dirrem, dotdotremref);
/*
* Check for a diradd dependency for the same directory entry.

View File

@ -1497,7 +1497,9 @@ ufs_rename(ap)
/* Don't go to bad here as the new link exists. */
if (error)
goto unlockout;
}
} else if (DOINGSUJ(tdvp))
/* Journal must account for each new link. */
softdep_setup_dotdot_link(tdp, fip);
fip->i_offset = mastertemplate.dot_reclen;
ufs_dirrewrite(fip, fdp, newparent, DT_DIR, 0);
cache_purge(fdvp);