summaryrefslogtreecommitdiffstats
path: root/sys/ufs
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2010-12-30 10:52:07 +0000
committerkib <kib@FreeBSD.org>2010-12-30 10:52:07 +0000
commit64276929dedf9abcecfe35b21f4aff714a4f8c13 (patch)
tree8baa9f0f863df31eb1ae1b208aa471e1be6b2c2b /sys/ufs
parent44467ec2f88fce3274351522ab7c5e3b5be0845a (diff)
downloadFreeBSD-src-64276929dedf9abcecfe35b21f4aff714a4f8c13.zip
FreeBSD-src-64276929dedf9abcecfe35b21f4aff714a4f8c13.tar.gz
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
Diffstat (limited to 'sys/ufs')
-rw-r--r--sys/ufs/ffs/ffs_softdep.c12
-rw-r--r--sys/ufs/ufs/ufs_vnops.c4
2 files changed, 8 insertions, 8 deletions
diff --git a/sys/ufs/ffs/ffs_softdep.c b/sys/ufs/ffs/ffs_softdep.c
index 22b6404..4b1204a 100644
--- a/sys/ufs/ffs/ffs_softdep.c
+++ b/sys/ufs/ffs/ffs_softdep.c
@@ -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.
diff --git a/sys/ufs/ufs/ufs_vnops.c b/sys/ufs/ufs/ufs_vnops.c
index 794c2f3..c396910 100644
--- a/sys/ufs/ufs/ufs_vnops.c
+++ b/sys/ufs/ufs/ufs_vnops.c
@@ -1497,7 +1497,9 @@ relock:
/* 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);
OpenPOWER on IntegriCloud