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