Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/ufs/ufs - Collect the slot-related variables in their ow...



details:   https://anonhg.NetBSD.org/src/rev/1272780888a3
branches:  trunk
changeset: 344710:1272780888a3
user:      christos <christos%NetBSD.org@localhost>
date:      Tue Apr 12 14:40:16 2016 +0000

description:
- Collect the slot-related variables in their own structure and extract
  some of the slot finding and updating code into their own function.
- Add a new label "next" in the main search loop to avoid nesting and
  code duplication.
- Cache some reclen and ino variables for better readability and efficiency.

diffstat:

 sys/ufs/ufs/ufs_lookup.c |  346 +++++++++++++++++++++++++---------------------
 1 files changed, 187 insertions(+), 159 deletions(-)

diffs (truncated from 536 to 300 lines):

diff -r 753ec1a0e148 -r 1272780888a3 sys/ufs/ufs/ufs_lookup.c
--- a/sys/ufs/ufs/ufs_lookup.c  Tue Apr 12 11:51:08 2016 +0000
+++ b/sys/ufs/ufs/ufs_lookup.c  Tue Apr 12 14:40:16 2016 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ufs_lookup.c,v 1.137 2016/04/12 00:36:29 christos Exp $        */
+/*     $NetBSD: ufs_lookup.c,v 1.138 2016/04/12 14:40:16 christos Exp $        */
 
 /*
  * Copyright (c) 1989, 1993
@@ -37,7 +37,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ufs_lookup.c,v 1.137 2016/04/12 00:36:29 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ufs_lookup.c,v 1.138 2016/04/12 14:40:16 christos Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_ffs.h"
@@ -93,6 +93,111 @@
        dirp->d_type = tmp;
 }
 
+struct slotinfo {
+       enum {
+               NONE,           /* need to search a slot for our new entry */
+               COMPACT,        /* a compaction can make a slot in the current
+                                  DIRBLKSIZ block */
+               FOUND,          /* found a slot (or no need to search) */
+       } status;
+       doff_t offset;          /* offset of area with free space.
+                                  a special value -1 for invalid */
+       int size;               /* size of area at slotoffset */
+       int freespace;          /* accumulated amount of space free in
+                                  the current DIRBLKSIZ block */
+       int needed;             /* size of the entry we're seeking */
+};
+
+static void
+slot_init(struct slotinfo *slot)
+{
+       slot->status = FOUND;
+       slot->offset = -1;
+       slot->freespace = slot->size = slot->needed = 0;
+}
+
+#ifdef UFS_DIRHASH
+static doff_t
+slot_findfree(struct slotinfo *slot, struct inode *dp)
+{
+       if (slot->status == FOUND)
+               return dp->i_size;
+
+       slot->offset = ufsdirhash_findfree(dp, slot->needed, &slot->size);
+       if (slot->offset < 0)
+               return dp->i_size;
+
+       slot->status = COMPACT;
+       doff_t enduseful = ufsdirhash_enduseful(dp);
+       if (enduseful < 0)
+               return dp->i_size;
+       return enduseful;
+}
+#endif
+
+static void
+slot_white(struct slotinfo *slot, uint16_t reclen,
+    struct ufs_lookup_results *results)
+{
+       slot->status = FOUND;
+       slot->offset = results->ulr_offset;
+       slot->size = reclen;
+       results->ulr_reclen = slot->size;
+}
+
+static void
+slot_update(struct slotinfo *slot, int size, uint16_t reclen, doff_t offset)
+{
+       if (size >= slot->needed) {
+               slot->status = FOUND;
+               slot->offset = offset;
+               slot->size = reclen;
+       } else if (slot->status == NONE) {
+               slot->freespace += size;
+               if (slot->offset == -1)
+                       slot->offset = offset;
+               if (slot->freespace >= slot->needed) {
+                       slot->status = COMPACT;
+                       slot->size = offset + reclen - slot->offset;
+               }
+       }
+}
+
+/*
+ * Return an indication of where the new directory entry should be put.
+ * If we didn't find a slot, then set results->ulr_count to 0 indicating
+ * that the new slot belongs at the end of the directory. If we found a slot,
+ * then the new entry can be put in the range from results->ulr_offset to
+ * results->ulr_offset + results->ulr_count.
+ */
+static int
+slot_estimate(const struct slotinfo *slot, int dirblksiz, int nameiop,
+    doff_t prevoff, doff_t enduseful, const struct inode *ip,
+    struct ufs_lookup_results *results)
+{
+       if (slot->status == NONE) {
+               results->ulr_offset = roundup(ip->i_size, dirblksiz);
+               results->ulr_count = 0;
+               enduseful = results->ulr_offset;
+       } else if (nameiop == DELETE) {
+               results->ulr_offset = slot->offset;
+               if ((results->ulr_offset & (dirblksiz - 1)) == 0)
+                       results->ulr_count = 0;
+               else
+                       results->ulr_count = results->ulr_offset - prevoff;
+       } else {
+               results->ulr_offset = slot->offset;
+               results->ulr_count = slot->size;
+               if (enduseful < slot->offset + slot->size)
+                       enduseful = slot->offset + slot->size;
+       }
+       results->ulr_endoff = roundup(enduseful, dirblksiz);
+#if 0 /* commented out by dbj. none of the on disk fields changed */
+       ip->i_flag |= IN_CHANGE | IN_UPDATE;
+#endif
+       return EJUSTRETURN;
+}
+
 /*
  * Convert a component of a pathname into a pointer to a locked inode.
  * This is a very central and rather complicated routine.
@@ -139,18 +244,7 @@
        struct buf *bp;                 /* a buffer of directory entries */
        struct direct *ep;              /* the current directory entry */
        int entryoffsetinblock;         /* offset of ep in bp's buffer */
-       enum {
-               NONE,           /* need to search a slot for our new entry */
-               COMPACT,        /* a compaction can make a slot in the current
-                                  DIRBLKSIZ block */
-               FOUND,          /* found a slot (or no need to search) */
-       } slotstatus;
-       doff_t slotoffset;              /* offset of area with free space.
-                                          a special value -1 for invalid */
-       int slotsize;                   /* size of area at slotoffset */
-       int slotfreespace;              /* accumulated amount of space free in
-                                          the current DIRBLKSIZ block */
-       int slotneeded;                 /* size of the entry we're seeking */
+       struct slotinfo slot;
        int numdirpasses;               /* strategy for directory search */
        doff_t endsearch;               /* offset to end directory search */
        doff_t prevoff;                 /* previous value of ulr_offset */
@@ -171,11 +265,11 @@
        struct ufs_lookup_results *results;
        int iswhiteout;                 /* temp result from cache_lookup() */
        const int fsfmt = FSFMT(vdp);
+       uint16_t reclen;
 
        flags = cnp->cn_flags;
 
        bp = NULL;
-       slotoffset = -1;
        *vpp = NULL;
        endsearch = 0; /* silence compiler warning */
 
@@ -233,11 +327,11 @@
         * we watch for a place to put the new file in
         * case it doesn't already exist.
         */
-       slotstatus = FOUND;
-       slotfreespace = slotsize = slotneeded = 0;
+       slot_init(&slot);
+
        if ((nameiop == CREATE || nameiop == RENAME) && (flags & ISLASTCN)) {
-               slotstatus = NONE;
-               slotneeded = UFS_DIRECTSIZ(cnp->cn_namelen);
+               slot.status = NONE;
+               slot.needed = UFS_DIRECTSIZ(cnp->cn_namelen);
        }
 
        /*
@@ -262,22 +356,13 @@
         */
        if (ufsdirhash_build(dp) == 0) {
                /* Look for a free slot if needed. */
-               enduseful = dp->i_size;
-               if (slotstatus != FOUND) {
-                       slotoffset = ufsdirhash_findfree(dp, slotneeded,
-                           &slotsize);
-                       if (slotoffset >= 0) {
-                               slotstatus = COMPACT;
-                               enduseful = ufsdirhash_enduseful(dp);
-                               if (enduseful < 0)
-                                       enduseful = dp->i_size;
-                       }
-               }
+               enduseful = slot_findfree(&slot, dp->i_size);
                /* Look up the component. */
                numdirpasses = 1;
                entryoffsetinblock = 0; /* silence compiler warning */
                switch (ufsdirhash_lookup(dp, cnp->cn_nameptr, cnp->cn_namelen,
-                   &results->ulr_offset, &bp, nameiop == DELETE ? &prevoff : NULL)) {
+                   &results->ulr_offset, &bp,
+                   nameiop == DELETE ? &prevoff : NULL)) {
                case 0:
                        ep = (void *)((char *)bp->b_data +
                            (results->ulr_offset & bmask));
@@ -330,10 +415,10 @@
                 * If still looking for a slot, and at a DIRBLKSIZ
                 * boundary, have to start looking for free space again.
                 */
-               if (slotstatus == NONE &&
+               if (slot.status == NONE &&
                    (entryoffsetinblock & (dirblksiz - 1)) == 0) {
-                       slotoffset = -1;
-                       slotfreespace = 0;
+                       slot.offset = -1;
+                       slot.freespace = 0;
                }
                /*
                 * Get pointer to next entry.
@@ -345,15 +430,13 @@
                KASSERT(bp != NULL);
                ep = (void *)((char *)bp->b_data + entryoffsetinblock);
                const char *msg;
-               if ((ep->d_reclen == 0 && (msg = "null entry")) || (dirchk &&
+               reclen = ufs_rw16(ep->d_reclen, needswap);
+               if ((reclen == 0 && (msg = "null entry")) || (dirchk &&
                    (msg = ufs_dirbadentry(vdp, ep, entryoffsetinblock)))) {
-                       int i;
-
                        ufs_dirbad(dp, results->ulr_offset, msg);
-                       i = dirblksiz - (entryoffsetinblock & (dirblksiz - 1));
-                       results->ulr_offset += i;
-                       entryoffsetinblock += i;
-                       continue;
+                       reclen = dirblksiz -
+                           (entryoffsetinblock & (dirblksiz - 1));
+                       goto next;
                }
 
                /*
@@ -362,84 +445,60 @@
                 * in the current block so that we can determine if
                 * compaction is viable.
                 */
-               if (slotstatus != FOUND) {
-                       int size = ufs_rw16(ep->d_reclen, needswap);
-
+               if (slot.status != FOUND) {
+                       int size = reclen;
                        if (ep->d_ino != 0)
                                size -= UFS_DIRSIZ(fsfmt, ep, needswap);
-                       if (size > 0) {
-                               if (size >= slotneeded) {
-                                       slotstatus = FOUND;
-                                       slotoffset = results->ulr_offset;
-                                       slotsize = ufs_rw16(ep->d_reclen,
-                                           needswap);
-                               } else if (slotstatus == NONE) {
-                                       slotfreespace += size;
-                                       if (slotoffset == -1)
-                                               slotoffset = results->ulr_offset;
-                                       if (slotfreespace >= slotneeded) {
-                                               slotstatus = COMPACT;
-                                               slotsize = results->ulr_offset +
-                                                   ufs_rw16(ep->d_reclen,
-                                                            needswap) -
-                                                   slotoffset;
-                                       }
-                               }
-                       }
+                       if (size > 0)
+                               slot_update(&slot, size, reclen,
+                                   results->ulr_offset);
                }
 
+               if (ep->d_ino == 0)
+                       goto next;
+
                /*
                 * Check for a name match.
                 */
-               if (ep->d_ino) {
-                       const int namlen = NAMLEN(fsfmt, needswap, ep);
-                       if (namlen == cnp->cn_namelen &&
-                           !memcmp(cnp->cn_nameptr, ep->d_name,
-                           (unsigned)namlen)) {
+               const uint16_t namlen = NAMLEN(fsfmt, needswap, ep);
+               if (namlen != cnp->cn_namelen ||
+                   memcmp(cnp->cn_nameptr, ep->d_name,
+                   (unsigned)namlen))
+                       goto next;
+
 #ifdef UFS_DIRHASH
 foundentry:
 #endif
-                               /*
-                                * Save directory entry's inode number and
-                                * reclen, and release directory buffer.
-                                */
-                               if (!fsfmt && ep->d_type == DT_WHT) {



Home | Main Index | Thread Index | Old Index