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