From: Nikolay Borisov <nborisov@suse.com>
To: linux-btrfs@vger.kernel.org
Cc: Nikolay Borisov <nborisov@suse.com>
Subject: [PATCH v3 11/12] btrfs: Implement find_first_clear_extent_bit
Date: Mon, 25 Mar 2019 14:31:31 +0200 [thread overview]
Message-ID: <20190325123132.27835-12-nborisov@suse.com> (raw)
In-Reply-To: <20190325123132.27835-1-nborisov@suse.com>
This function is very similar to find_first_extent_bit except that it
locates the first contiguous span of space which does not have bits set.
It's intended use is in the freespace trimming code.
Signed-off-by: Nikolay Borisov <nborisov@suse.com>
---
fs/btrfs/extent_io.c | 73 ++++++++++++++++++++++++++++++++++++++++++++
fs/btrfs/extent_io.h | 2 ++
2 files changed, 75 insertions(+)
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index ff3f8443e180..7e49e5687bac 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -1535,6 +1535,79 @@ int find_first_extent_bit(struct extent_io_tree *tree, u64 start,
return ret;
}
+/**
+ * find_first_clear_extent_bit - finds the first range that has @bits not set
+ * and that starts after @start
+ *
+ * @tree - the tree to search
+ * @start - the offset at/after which the found extent should start
+ * @start_ret - records the beginning of the range
+ * @end_ret - records the end of the range (inclusive)
+ * @bits - the set of bits which must be unset
+ *
+ * Since unallocated range is also considered one which doesn't have the bits
+ * set it's possible that @end_ret contains -1, this happens in case the range
+ * spans (last_range_end, end of device]. In this case it's up to the caller to
+ * trim @end_ret to the appropriate size.
+ */
+void find_first_clear_extent_bit(struct extent_io_tree *tree, u64 start,
+ u64 *start_ret, u64 *end_ret, unsigned bits)
+{
+ struct extent_state *state;
+ struct rb_node *node, *prev = NULL, *next;
+
+ spin_lock(&tree->lock);
+
+ /* Find first extent with bits cleared */
+ while (1) {
+ node = __etree_search(tree, start, &next, &prev, NULL, NULL);
+ if (!node) {
+ node = next;
+ if (!node) {
+ /*
+ * We are past the last allocated chunk,
+ * set start at the end of the last extent. The
+ * device alloc tree should never be empty so
+ * prev is always set.
+ */
+ ASSERT(prev);
+ state = rb_entry(prev, struct extent_state, rb_node);
+ *start_ret = state->end + 1;
+ *end_ret = -1;
+ goto out;
+ }
+ }
+ state = rb_entry(node, struct extent_state, rb_node);
+ if (in_range(start, state->start, state->end - state->start + 1) &&
+ (state->state & bits)) {
+ start = state->end + 1;
+ } else {
+ *start_ret = start;
+ break;
+ }
+ }
+
+ /*
+ * Find the longest stretch from start until an entry which has the
+ * bits set
+ */
+ while (1) {
+ state = rb_entry(node, struct extent_state, rb_node);
+ if (state->end >= start && !(state->state & bits)) {
+ *end_ret = state->end;
+ } else {
+ *end_ret = state->start - 1;
+ break;
+ }
+
+ node = rb_next(node);
+ if (!node)
+ break;
+ }
+out:
+ spin_unlock(&tree->lock);
+}
+
/*
* find a contiguous range of bytes in the file marked as delalloc, not
* more than 'max_bytes'. start and end are used to return the range,
diff --git a/fs/btrfs/extent_io.h b/fs/btrfs/extent_io.h
index 9dd5190d9dd8..120bc7346405 100644
--- a/fs/btrfs/extent_io.h
+++ b/fs/btrfs/extent_io.h
@@ -406,6 +406,8 @@ static inline int set_extent_uptodate(struct extent_io_tree *tree, u64 start,
int find_first_extent_bit(struct extent_io_tree *tree, u64 start,
u64 *start_ret, u64 *end_ret, unsigned bits,
struct extent_state **cached_state);
+void find_first_clear_extent_bit(struct extent_io_tree *tree, u64 start,
+ u64 *start_ret, u64 *end_ret, unsigned bits);
int extent_invalidatepage(struct extent_io_tree *tree,
struct page *page, unsigned long offset);
int extent_write_full_page(struct page *page, struct writeback_control *wbc);
--
2.17.1
next prev parent reply other threads:[~2019-03-25 12:31 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-03-25 12:31 [PATCH v3 00/12] FITRIM improvements Nikolay Borisov
2019-03-25 12:31 ` [PATCH v3 01/12] btrfs: Honour FITRIM range constraints during free space trim Nikolay Borisov
2019-03-25 12:31 ` [PATCH v3 02/12] btrfs: combine device update operations during transaction commit Nikolay Borisov
2019-03-25 13:44 ` Nikolay Borisov
2019-03-25 12:31 ` [PATCH v3 03/12] btrfs: Handle pending/pinned chunks before blockgroup relocation during device shrink Nikolay Borisov
2019-03-25 15:09 ` David Sterba
2019-03-25 15:16 ` David Sterba
2019-03-25 12:31 ` [PATCH v3 04/12] btrfs: Rename and export clear_btree_io_tree Nikolay Borisov
2019-03-25 12:31 ` [PATCH v3 05/12] btrfs: Populate ->orig_block_len during read_one_chunk Nikolay Borisov
2019-03-25 12:31 ` [PATCH v3 06/12] btrfs: Introduce new bits for device allocation tree Nikolay Borisov
2019-03-25 16:12 ` David Sterba
2019-03-25 16:13 ` Nikolay Borisov
2019-03-25 12:31 ` [PATCH v3 07/12] btrfs: replace pending/pinned chunks lists with io tree Nikolay Borisov
2019-03-25 14:22 ` David Sterba
2019-03-25 16:26 ` David Sterba
2019-03-25 16:43 ` Nikolay Borisov
2019-03-25 16:57 ` David Sterba
2019-03-25 12:31 ` [PATCH v3 08/12] btrfs: Remove 'trans' argument from find_free_dev_extent(_start) Nikolay Borisov
2019-03-25 12:31 ` [PATCH v3 09/12] btrfs: Factor out in_range macro Nikolay Borisov
2019-03-25 12:31 ` [PATCH v3 10/12] btrfs: Optimize unallocated chunks discard Nikolay Borisov
2019-03-25 16:29 ` David Sterba
2019-03-25 12:31 ` Nikolay Borisov [this message]
2019-03-25 12:31 ` [PATCH v3 12/12] btrfs: Switch btrfs_trim_free_extents to find_first_clear_extent_bit Nikolay Borisov
2019-03-25 18:44 ` [PATCH v3 00/12] FITRIM improvements Darrick J. Wong
2019-03-26 8:09 ` Nikolay Borisov
2019-03-26 10:50 ` Filipe Manana
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=20190325123132.27835-12-nborisov@suse.com \
--to=nborisov@suse.com \
--cc=linux-btrfs@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox