Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/ufs/ufs Clean up handling of ufs_lookup_results in rename.
details: https://anonhg.NetBSD.org/src/rev/6b954aaa0c69
branches: trunk
changeset: 767288:6b954aaa0c69
user: dholland <dholland%NetBSD.org@localhost>
date: Thu Jul 14 16:27:43 2011 +0000
description:
Clean up handling of ufs_lookup_results in rename.
diffstat:
sys/ufs/ufs/ufs_vnops.c | 30 +++++--
sys/ufs/ufs/ufs_wapbl.c | 175 +++++++++++++++++++++++++++++------------------
2 files changed, 129 insertions(+), 76 deletions(-)
diffs (truncated from 414 to 300 lines):
diff -r 68c7768bd8e7 -r 6b954aaa0c69 sys/ufs/ufs/ufs_vnops.c
--- a/sys/ufs/ufs/ufs_vnops.c Thu Jul 14 16:27:11 2011 +0000
+++ b/sys/ufs/ufs/ufs_vnops.c Thu Jul 14 16:27:43 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ufs_vnops.c,v 1.192 2011/07/12 16:59:49 dholland Exp $ */
+/* $NetBSD: ufs_vnops.c,v 1.193 2011/07/14 16:27:43 dholland Exp $ */
/*-
* Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -66,7 +66,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ufs_vnops.c,v 1.192 2011/07/12 16:59:49 dholland Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ufs_vnops.c,v 1.193 2011/07/14 16:27:43 dholland Exp $");
#if defined(_KERNEL_OPT)
#include "opt_ffs.h"
@@ -989,6 +989,7 @@
struct mount *mp;
struct direct *newdir;
int doingdirectory, oldparent, newparent, error;
+ struct ufs_lookup_results from_ulr, to_ulr;
#ifdef WAPBL
if (ap->a_tdvp->v_mount->mnt_wapbl)
@@ -1003,6 +1004,12 @@
fcnp = ap->a_fcnp;
doingdirectory = oldparent = newparent = error = 0;
+ /* save the supplemental lookup results as they currently exist */
+ from_ulr = VTOI(fdvp)->i_crap;
+ to_ulr = VTOI(tdvp)->i_crap;
+ UFS_CHECK_CRAPCOUNTER(VTOI(fdvp));
+ UFS_CHECK_CRAPCOUNTER(VTOI(tdvp));
+
/*
* Check for cross-device rename.
*/
@@ -1145,6 +1152,11 @@
goto out;
}
dp = VTOI(tdvp);
+
+ /* update the supplemental reasults */
+ to_ulr = dp->i_crap;
+ UFS_CHECK_CRAPCOUNTER(dp);
+
xp = NULL;
if (tvp)
xp = VTOI(tvp);
@@ -1182,7 +1194,7 @@
}
newdir = pool_cache_get(ufs_direct_cache, PR_WAITOK);
ufs_makedirentry(ip, tcnp, newdir);
- error = ufs_direnter(tdvp, &VTOI(tdvp)->i_crap,
+ error = ufs_direnter(tdvp, &to_ulr,
NULL, newdir, tcnp, NULL);
pool_cache_put(ufs_direct_cache, newdir);
if (error != 0) {
@@ -1239,7 +1251,7 @@
error = EISDIR;
goto bad;
}
- if ((error = ufs_dirrewrite(dp, dp->i_crap.ulr_offset,
+ if ((error = ufs_dirrewrite(dp, to_ulr.ulr_offset,
xp, ip->i_number,
IFTODT(ip->i_mode), doingdirectory && newparent ?
newparent : doingdirectory, IN_CHANGE | IN_UPDATE)) != 0)
@@ -1282,6 +1294,10 @@
vrele(ap->a_fvp);
goto out2;
}
+ /* update supplemental lookup results */
+ from_ulr = VTOI(fdvp)->i_crap;
+ UFS_CHECK_CRAPCOUNTER(VTOI(fdvp));
+
if (fvp != NULL) {
xp = VTOI(fvp);
dp = VTOI(fdvp);
@@ -1316,15 +1332,11 @@
*/
if (doingdirectory && newparent) {
KASSERT(dp != NULL);
-
- /* match old behavior; probably dead assignment XXX */
- xp->i_crap.ulr_offset = mastertemplate.dot_reclen;
-
ufs_dirrewrite(xp, mastertemplate.dot_reclen,
dp, newparent, DT_DIR, 0, IN_CHANGE);
cache_purge(fdvp);
}
- error = ufs_dirremove(fdvp, &VTOI(fdvp)->i_crap,
+ error = ufs_dirremove(fdvp, &from_ulr,
xp, fcnp->cn_flags, 0);
xp->i_flag &= ~IN_RENAME;
}
diff -r 68c7768bd8e7 -r 6b954aaa0c69 sys/ufs/ufs/ufs_wapbl.c
--- a/sys/ufs/ufs/ufs_wapbl.c Thu Jul 14 16:27:11 2011 +0000
+++ b/sys/ufs/ufs/ufs_wapbl.c Thu Jul 14 16:27:43 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ufs_wapbl.c,v 1.15 2011/07/12 16:59:49 dholland Exp $ */
+/* $NetBSD: ufs_wapbl.c,v 1.16 2011/07/14 16:27:43 dholland Exp $ */
/*-
* Copyright (c) 2003,2006,2008 The NetBSD Foundation, Inc.
@@ -66,7 +66,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ufs_wapbl.c,v 1.15 2011/07/12 16:59:49 dholland Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ufs_wapbl.c,v 1.16 2011/07/14 16:27:43 dholland Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -113,6 +113,41 @@
};
/*
+ * Check if either entry referred to by FROM_ULR is within the range
+ * of entries named by TO_ULR.
+ */
+static int
+ulr_overlap(const struct ufs_lookup_results *from_ulr,
+ const struct ufs_lookup_results *to_ulr)
+{
+ doff_t from_start, from_prevstart;
+ doff_t to_start, to_end;
+
+ /*
+ * FROM is a DELETE result; offset points to the entry to
+ * remove and subtracting count gives the previous entry.
+ */
+ from_start = from_ulr->ulr_offset - from_ulr->ulr_count;
+ from_prevstart = from_ulr->ulr_offset;
+
+ /*
+ * TO is a RENAME (thus non-DELETE) result; offset points
+ * to the beginning of a region to write in, and adding
+ * count gives the end of the region.
+ */
+ to_start = to_ulr->ulr_offset;
+ to_end = to_ulr->ulr_offset + to_ulr->ulr_count;
+
+ if (from_prevstart >= to_start && from_prevstart < to_end) {
+ return 1;
+ }
+ if (from_start >= to_start && from_start < to_end) {
+ return 1;
+ }
+ return 0;
+}
+
+/*
* Rename vnode operation
* rename("foo", "bar");
* is essentially
@@ -160,10 +195,7 @@
struct direct *newdir;
int doingdirectory, oldparent, newparent, error;
- struct ufs_lookup_results saved_f_crap;
- struct ufs_lookup_results saved_t_crap;
- unsigned saved_f_crapcounter;
- unsigned saved_t_crapcounter;
+ struct ufs_lookup_results from_ulr, to_ulr;
tvp = ap->a_tvp;
tdvp = ap->a_tdvp;
@@ -173,6 +205,12 @@
fcnp = ap->a_fcnp;
doingdirectory = oldparent = newparent = error = 0;
+ /* save the supplemental lookup results as they currently exist */
+ from_ulr = VTOI(fdvp)->i_crap;
+ to_ulr = VTOI(tdvp)->i_crap;
+ UFS_CHECK_CRAPCOUNTER(VTOI(fdvp));
+ UFS_CHECK_CRAPCOUNTER(VTOI(tdvp));
+
/*
* Check for cross-device rename.
*/
@@ -304,6 +342,11 @@
goto out;
}
tdp = VTOI(tdvp);
+
+ /* update the supplemental reasults */
+ to_ulr = tdp->i_crap;
+ UFS_CHECK_CRAPCOUNTER(tdp);
+
if (tvp)
txp = VTOI(tvp);
}
@@ -313,10 +356,6 @@
* by unlocking tdvp and regrabbing it with vget after?
*/
- /* save directory lookup information in case tdvp == fdvp */
- saved_t_crap = tdp->i_crap;
- saved_t_crapcounter = tdp->i_crapcounter;
-
/*
* This was moved up to before the journal lock to
* avoid potential deadlock
@@ -335,6 +374,10 @@
vrele(ap->a_fvp);
goto out2;
}
+
+ /* update supplemental lookup results */
+ from_ulr = VTOI(fdvp)->i_crap;
+ UFS_CHECK_CRAPCOUNTER(VTOI(fdvp));
} else {
error = VOP_LOOKUP(fdvp, &fvp, fcnp);
if (error && (error != EJUSTRETURN)) {
@@ -343,6 +386,10 @@
goto out2;
}
error = 0;
+
+ /* update supplemental lookup results */
+ from_ulr = VTOI(fdvp)->i_crap;
+ UFS_CHECK_CRAPCOUNTER(VTOI(fdvp));
}
if (fvp != NULL) {
fxp = VTOI(fvp);
@@ -363,17 +410,6 @@
*/
vrele(ap->a_fvp);
- /* save directory lookup information in case tdvp == fdvp */
- saved_f_crap = fdp->i_crap;
- saved_f_crapcounter = fdp->i_crapcounter;
-
- /* before the introduction of _crap this didn't save endoff (XXX?) */
- saved_f_crap.ulr_endoff = 0;
-
- /* restore directory lookup information in case tdvp == fdvp */
- tdp->i_crap = saved_t_crap;
- tdp->i_crapcounter = saved_t_crapcounter;
-
error = UFS_WAPBL_BEGIN(fdvp->v_mount);
if (error)
goto out2;
@@ -424,7 +460,7 @@
}
newdir = pool_cache_get(ufs_direct_cache, PR_WAITOK);
ufs_makedirentry(ip, tcnp, newdir);
- error = ufs_direnter(tdvp, &VTOI(tdvp)->i_crap,
+ error = ufs_direnter(tdvp, &to_ulr,
NULL, newdir, tcnp, NULL);
pool_cache_put(ufs_direct_cache, newdir);
if (error != 0) {
@@ -480,7 +516,7 @@
error = EISDIR;
goto bad;
}
- if ((error = ufs_dirrewrite(tdp, tdp->i_crap.ulr_offset,
+ if ((error = ufs_dirrewrite(tdp, to_ulr.ulr_offset,
txp, ip->i_number,
IFTODT(ip->i_mode), doingdirectory && newparent ?
newparent : doingdirectory, IN_CHANGE | IN_UPDATE)) != 0)
@@ -510,27 +546,22 @@
VN_KNOTE(tvp, NOTE_DELETE);
}
- /* restore directory lookup information in case tdvp == fdvp */
- /* before the introduction of _crap this didn't restore endoff (XXX?)*/
- saved_f_crap.ulr_endoff = fdp->i_crap.ulr_endoff;
- fdp->i_crap = saved_f_crap;
- fdp->i_crapcounter = saved_f_crapcounter;
+ /*
+ * Handle case where the directory entry we need to remove,
+ * which is/was at from_ulr.ulr_offset, or the one before it,
+ * which is/was at from_ulr.ulr_offset - from_ulr.ulr_count,
+ * may have been moved when the directory insertion above
+ * performed compaction.
+ */
+ if (tdp->i_number == fdp->i_number &&
+ ulr_overlap(&from_ulr, &to_ulr)) {
- /*
- * Handle case where the directory we need to remove may have
- * been moved when the directory insertion above performed compaction.
- * or when i_count may be wrong due to insertion before this entry.
- */
- if ((tdp->i_number == fdp->i_number) &&
- (((saved_f_crap.ulr_offset >= saved_t_crap.ulr_offset) &&
- (saved_f_crap.ulr_offset < saved_t_crap.ulr_offset + saved_t_crap.ulr_count)) ||
- ((saved_f_crap.ulr_offset - saved_f_crap.ulr_count >= saved_t_crap.ulr_offset) &&
- (saved_f_crap.ulr_offset - saved_f_crap.ulr_count <
- saved_t_crap.ulr_offset + saved_t_crap.ulr_count)))) {
struct buf *bp;
struct direct *ep;
struct ufsmount *ump = fdp->i_ump;
+ doff_t curpos;
doff_t endsearch; /* offset to end directory search */
+ uint32_t prev_reclen;
int dirblksiz = ump->um_dirblksiz;
Home |
Main Index |
Thread Index |
Old Index