From: Dave Chinner <david@fromorbit.com>
To: linux-xfs@vger.kernel.org
Subject: [PATCH 3/5] xfs: factor free block index lookup from xfs_dir2_node_addname_int()
Date: Thu, 25 Oct 2018 09:57:14 +1100 [thread overview]
Message-ID: <20181024225716.19459-4-david@fromorbit.com> (raw)
In-Reply-To: <20181024225716.19459-1-david@fromorbit.com>
From: Dave Chinner <dchinner@redhat.com>
Simplify the logic in xfs_dir2_node_addname_int() by factoring out
the free block index lookup code that finds a block with enough free
space for the entry to be added. The code that is moved gets a major
cleanup at the same time, but there is no algorithm change here.
Signed-off-by: Dave Chinner <dchinner@redhat.com>
---
fs/xfs/libxfs/xfs_dir2_node.c | 195 ++++++++++++++++++----------------
1 file changed, 105 insertions(+), 90 deletions(-)
diff --git a/fs/xfs/libxfs/xfs_dir2_node.c b/fs/xfs/libxfs/xfs_dir2_node.c
index 7c674c55e004..1ecf41e380fb 100644
--- a/fs/xfs/libxfs/xfs_dir2_node.c
+++ b/fs/xfs/libxfs/xfs_dir2_node.c
@@ -1638,7 +1638,7 @@ xfs_dir2_node_add_datablk(
int error;
/* Not allowed to allocate, return failure. */
- if ((args->op_flags & XFS_DA_OP_JUSTCHECK) || args->total == 0)
+ if (args->total == 0)
return -ENOSPC;
/* Allocate and initialize the new data block. */
@@ -1735,43 +1735,29 @@ xfs_dir2_node_add_datablk(
return 0;
}
-/*
- * Add the data entry for a node-format directory name addition.
- * The leaf entry is added in xfs_dir2_leafn_add.
- * We may enter with a freespace block that the lookup found.
- */
-static int /* error */
-xfs_dir2_node_addname_int(
- xfs_da_args_t *args, /* operation arguments */
- xfs_da_state_blk_t *fblk) /* optional freespace block */
+static int
+xfs_dir2_node_find_freeblk(
+ struct xfs_da_args *args,
+ struct xfs_da_state_blk *fblk,
+ xfs_dir2_db_t *dbnop,
+ struct xfs_buf **fbpp,
+ int *findexp,
+ int length)
{
- xfs_dir2_data_hdr_t *hdr; /* data block header */
- xfs_dir2_db_t dbno; /* data block number */
- struct xfs_buf *dbp; /* data block buffer */
- xfs_dir2_data_entry_t *dep; /* data entry pointer */
- xfs_inode_t *dp; /* incore directory inode */
- xfs_dir2_data_unused_t *dup; /* data unused entry pointer */
- int error; /* error return value */
- xfs_dir2_db_t fbno; /* freespace block number */
- struct xfs_buf *fbp; /* freespace buffer */
- int findex; /* freespace entry index */
- xfs_dir2_free_t *free=NULL; /* freespace block structure */
- xfs_dir2_db_t ifbno; /* initial freespace block no */
- xfs_dir2_db_t lastfbno=0; /* highest freespace block no */
- int length; /* length of the new entry */
- int logfree = 0; /* need to log free entry */
- int needlog = 0; /* need to log data header */
- int needscan = 0; /* need to rescan data frees */
- __be16 *tagp; /* data entry tag pointer */
- xfs_trans_t *tp; /* transaction pointer */
- __be16 *bests;
+ struct xfs_inode *dp = args->dp;
+ struct xfs_trans *tp = args->trans;
+ struct xfs_buf *fbp = NULL;
+ int findex;
+ xfs_dir2_db_t lastfbno;
+ xfs_dir2_db_t ifbno = -1;
+ xfs_dir2_db_t dbno = -1;
+ xfs_dir2_db_t fbno = -1;
+ xfs_dir2_free_t *free = NULL;
struct xfs_dir3_icfree_hdr freehdr;
- struct xfs_dir2_data_free *bf;
- xfs_dir2_data_aoff_t aoff;
+ __be16 *bests;
+ xfs_fileoff_t fo;
+ int error;
- dp = args->dp;
- tp = args->trans;
- length = dp->d_ops->data_entsize(args->namelen);
/*
* If we came in with a freespace block that means that lookup
* found an entry with our hash value. This is the freespace
@@ -1779,56 +1765,44 @@ xfs_dir2_node_addname_int(
*/
if (fblk) {
fbp = fblk->bp;
- /*
- * Remember initial freespace block number.
- */
- ifbno = fblk->blkno;
free = fbp->b_addr;
findex = fblk->index;
- bests = dp->d_ops->free_bests_p(free);
- dp->d_ops->free_hdr_from_disk(&freehdr, free);
-
- /*
- * This means the free entry showed that the data block had
- * space for our entry, so we remembered it.
- * Use that data block.
- */
if (findex >= 0) {
+ /* caller already found the freespace for us. */
+ bests = dp->d_ops->free_bests_p(free);
+ dp->d_ops->free_hdr_from_disk(&freehdr, free);
+
ASSERT(findex < freehdr.nvalid);
ASSERT(be16_to_cpu(bests[findex]) != NULLDATAOFF);
ASSERT(be16_to_cpu(bests[findex]) >= length);
dbno = freehdr.firstdb + findex;
- goto found_block;
- } else {
- /*
- * The data block looked at didn't have enough room.
- * We'll start at the beginning of the freespace entries.
- */
- dbno = -1;
- findex = 0;
+ goto out;
}
- } else {
+
/*
- * Didn't come in with a freespace block, so no data block.
+ * The data block looked at didn't have enough room.
+ * We'll start at the beginning of the freespace entries.
*/
- ifbno = dbno = -1;
- fbp = NULL;
- findex = 0;
+ ifbno = fblk->blkno;
+ fbno = ifbno;
}
+ ASSERT(dbno == -1);
+ findex = 0;
/*
- * If we don't have a data block yet, we're going to scan the
- * freespace blocks looking for one. Figure out what the
- * highest freespace block number is.
+ * If we don't have a data block yet, we're going to scan the freespace
+ * blocks looking for one. Figure out what the highest freespace block
+ * number is.
*/
- if (dbno == -1) {
- xfs_fileoff_t fo; /* freespace block number */
+ error = xfs_bmap_last_offset(dp, &fo, XFS_DATA_FORK);
+ if (error)
+ return error;
+ lastfbno = xfs_dir2_da_to_db(args->geo, (xfs_dablk_t)fo);
+
+ /* If we haven't get a search start block, set it now */
+ if (fbno == -1)
+ fbno = xfs_dir2_byte_to_db(args->geo, XFS_DIR2_FREE_OFFSET);
- if ((error = xfs_bmap_last_offset(dp, &fo, XFS_DATA_FORK)))
- return error;
- lastfbno = xfs_dir2_da_to_db(args->geo, (xfs_dablk_t)fo);
- fbno = ifbno;
- }
/*
* While we haven't identified a data block, search the freeblock
* data for a good data block. If we find a null freeblock entry,
@@ -1839,17 +1813,10 @@ xfs_dir2_node_addname_int(
* If we don't have a freeblock in hand, get the next one.
*/
if (fbp == NULL) {
- /*
- * Happens the first time through unless lookup gave
- * us a freespace block to start with.
- */
- if (++fbno == 0)
- fbno = xfs_dir2_byte_to_db(args->geo,
- XFS_DIR2_FREE_OFFSET);
/*
* If it's ifbno we already looked at it.
*/
- if (fbno == ifbno)
+ if (++fbno == ifbno)
fbno++;
/*
* If it's off the end we're done.
@@ -1900,6 +1867,62 @@ xfs_dir2_node_addname_int(
}
}
}
+out:
+ *dbnop = dbno;
+ *fbpp = fbp;
+ *findexp = findex;
+ return 0;
+}
+
+
+/*
+ * Add the data entry for a node-format directory name addition.
+ * The leaf entry is added in xfs_dir2_leafn_add.
+ * We may enter with a freespace block that the lookup found.
+ */
+static int /* error */
+xfs_dir2_node_addname_int(
+ xfs_da_args_t *args, /* operation arguments */
+ xfs_da_state_blk_t *fblk) /* optional freespace block */
+{
+ xfs_dir2_data_hdr_t *hdr; /* data block header */
+ xfs_dir2_db_t dbno; /* data block number */
+ struct xfs_buf *dbp; /* data block buffer */
+ xfs_dir2_data_entry_t *dep; /* data entry pointer */
+ xfs_inode_t *dp; /* incore directory inode */
+ xfs_dir2_data_unused_t *dup; /* data unused entry pointer */
+ int error; /* error return value */
+ struct xfs_buf *fbp; /* freespace buffer */
+ int findex; /* freespace entry index */
+ xfs_dir2_free_t *free=NULL; /* freespace block structure */
+ int length; /* length of the new entry */
+ int logfree = 0; /* need to log free entry */
+ int needlog = 0; /* need to log data header */
+ int needscan = 0; /* need to rescan data frees */
+ __be16 *tagp; /* data entry tag pointer */
+ xfs_trans_t *tp; /* transaction pointer */
+ __be16 *bests;
+ struct xfs_dir2_data_free *bf;
+ xfs_dir2_data_aoff_t aoff;
+
+ dp = args->dp;
+ tp = args->trans;
+ length = dp->d_ops->data_entsize(args->namelen);
+
+ error = xfs_dir2_node_find_freeblk(args, fblk, &dbno, &fbp, &findex,
+ length);
+ if (error)
+ return error;
+
+ /*
+ * Now we know if we must allocate blocks, so if we are checking whether
+ * we can insert without allocation then we can return now.
+ */
+ if (args->op_flags & XFS_DA_OP_JUSTCHECK) {
+ if (dbno != -1)
+ return 0;
+ return -ENOSPC;
+ }
/*
* If we don't have a data block, we need to allocate one and make
@@ -1911,29 +1934,21 @@ xfs_dir2_node_addname_int(
if (error)
return error;
- /* setup current free block buffer */
- free = fbp->b_addr;
- bests = dp->d_ops->free_bests_p(free);
-
/* we're going to have to log the free block index later */
logfree = 1;
} else {
-found_block:
- /* If just checking, we succeeded. */
- if (args->op_flags & XFS_DA_OP_JUSTCHECK)
- return 0;
-
/* Read the data block in. */
error = xfs_dir3_data_read(tp, dp,
xfs_dir2_db_to_da(args->geo, dbno),
-1, &dbp);
if (error)
return error;
-
- /* suppress gcc maybe-used-initialised warning */
- bests = dp->d_ops->free_bests_p(free);
}
+ /* setup current free block buffer */
+ free = fbp->b_addr;
+ bests = dp->d_ops->free_bests_p(free);
+
/* setup for data block up now */
hdr = dbp->b_addr;
bf = dp->d_ops->data_bestfree_p(hdr);
--
2.19.1
next prev parent reply other threads:[~2018-10-25 7:27 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-10-24 22:57 [PATCH 0/5] xfs: speed up large directory modifications Dave Chinner
2018-10-24 22:57 ` [PATCH 1/5] xfs: move xfs_dir2_addname() Dave Chinner
2018-10-26 9:24 ` Christoph Hellwig
2018-10-24 22:57 ` [PATCH 2/5] xfs: factor data block addition from xfs_dir2_node_addname_int() Dave Chinner
2018-10-26 9:45 ` Christoph Hellwig
2018-10-26 10:52 ` Dave Chinner
2018-10-26 12:01 ` Christoph Hellwig
2018-10-24 22:57 ` Dave Chinner [this message]
2018-10-26 9:48 ` [PATCH 3/5] xfs: factor free block index lookup " Christoph Hellwig
2018-10-26 10:49 ` Dave Chinner
2018-10-24 22:57 ` [PATCH 4/5] xfs: speed up directory bestfree block scanning Dave Chinner
2018-10-26 10:24 ` Christoph Hellwig
2018-10-26 10:58 ` Dave Chinner
2018-10-26 11:56 ` Christoph Hellwig
2018-10-26 12:12 ` Christoph Hellwig
2018-10-24 22:57 ` [PATCH 5/5] xfs: reverse search directory freespace indexes Dave Chinner
2018-10-26 12:14 ` Christoph Hellwig
-- strict thread matches above, loose matches on Subject: below --
2019-08-29 6:30 [PATCH V2 0/5] xfs: speed up large directory modifications Dave Chinner
2019-08-29 6:30 ` [PATCH 3/5] xfs: factor free block index lookup from xfs_dir2_node_addname_int() Dave Chinner
2019-08-29 8:10 ` Christoph Hellwig
2019-08-29 8:35 ` Dave Chinner
2019-08-29 10:47 [PATCH v3 0/5] xfs: speed up large directory modifications Dave Chinner
2019-08-29 10:47 ` [PATCH 3/5] xfs: factor free block index lookup from xfs_dir2_node_addname_int() Dave Chinner
2019-08-29 21:07 ` Darrick J. Wong
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20181024225716.19459-4-david@fromorbit.com \
--to=david@fromorbit.com \
--cc=linux-xfs@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.