All of lore.kernel.org
 help / color / mirror / Atom feed
From: Qu Wenruo <wqu@suse.com>
To: linux-btrfs@vger.kernel.org
Subject: [POC for v5.15 2/2] btrfs: defrag: limit cluster size to the first hole/prealloc range
Date: Tue, 25 Jan 2022 14:50:57 +0800	[thread overview]
Message-ID: <20220125065057.35863-3-wqu@suse.com> (raw)
In-Reply-To: <20220125065057.35863-1-wqu@suse.com>

We always use 256K as cluster size if possible, but it's very common
that there are only several small regular extents which are target for
defrag.

But those extents are not filling the whole 256K cluster, and the holes
after those extents will make defrag to reject the whole cluster.

This patch will mitigate the problem by doing another search for the
hole/preallocated range, and limit the size of the cluster just to the
regular extents part.

By this, defrag can do more of its work without being interrupted by a
hole.

Signed-off-by: Qu Wenruo <wqu@suse.com>
---
 fs/btrfs/ioctl.c | 31 +++++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)

diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index 8350864a4bd8..b66bb10e2e4a 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -1481,6 +1481,29 @@ static int cluster_pages_for_defrag(struct inode *inode,
 
 }
 
+static u64 get_cluster_size(struct inode *inode, u64 start, u64 len)
+{
+	u64 cur = start;
+	u64 cluster_len = 0;
+	while (cur < start + len) {
+		struct extent_map *em;
+
+		em = defrag_lookup_extent(inode, cur, false);
+		if (!em)
+			break;
+		/*
+		 * Here we don't do comprehensive checks, we just
+		 * find the first hole/preallocated.
+		 */
+		if (em->block_start >= EXTENT_MAP_LAST_BYTE ||
+		    test_bit(EXTENT_FLAG_PREALLOC, &em->flags))
+			break;
+		cluster_len += min(em->start + em->len - cur, start + len - cur);
+		cur = min(em->start + em->len, start + len);
+	}
+	return cluster_len;
+}
+
 /*
  * Entry point to file defragmentation.
  *
@@ -1618,6 +1641,13 @@ int btrfs_defrag_file(struct inode *inode, struct file_ra_state *ra,
 		} else {
 			cluster = max_cluster;
 		}
+		cluster = min_t(unsigned long,
+				get_cluster_size(inode, i << PAGE_SHIFT,
+						 cluster << PAGE_SHIFT)
+					>> PAGE_SHIFT,
+			        cluster);
+		if (cluster == 0)
+			goto next;
 
 		if (i + cluster > ra_index) {
 			ra_index = max(i, ra_index);
@@ -1644,6 +1674,7 @@ int btrfs_defrag_file(struct inode *inode, struct file_ra_state *ra,
 		balance_dirty_pages_ratelimited(inode->i_mapping);
 		btrfs_inode_unlock(inode, 0);
 
+next:
 		if (newer_than) {
 			if (newer_off == (u64)-1)
 				break;
-- 
2.34.1


  parent reply	other threads:[~2022-01-25  6:55 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-01-25  6:50 [POC for v5.15 0/2] btrfs: defrag: what if v5.15 is doing proper defrag Qu Wenruo
2022-01-25  6:50 ` [POC for v5.15 1/2] btrfs: defrag: don't defrag preallocated extents Qu Wenruo
2022-01-25  6:50 ` Qu Wenruo [this message]
2022-01-25 10:37 ` [POC for v5.15 0/2] btrfs: defrag: what if v5.15 is doing proper defrag Filipe Manana
2022-01-25 10:55   ` Qu Wenruo
2022-01-25 11:05     ` Qu Wenruo
2022-01-25 19:58       ` François-Xavier Thomas
2022-02-01 21:18         ` François-Xavier Thomas
2022-02-02  0:35           ` Qu Wenruo
2022-02-02  1:18             ` Qu Wenruo
2022-02-02 19:01               ` François-Xavier Thomas
2022-02-04  9:32                 ` François-Xavier Thomas
2022-02-04  9:49                   ` Qu Wenruo
2022-02-04 11:05                     ` François-Xavier Thomas
2022-02-04 11:21                       ` Qu Wenruo
2022-02-04 11:27                         ` François-Xavier Thomas
2022-02-04 11:28                           ` François-Xavier Thomas
2022-02-05 10:19                       ` Qu Wenruo

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=20220125065057.35863-3-wqu@suse.com \
    --to=wqu@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 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.