* [PATCH] Btrfs: fix defrag to merge tail file extent
@ 2015-08-07 8:48 Liu Bo
2015-08-07 8:50 ` Liu Bo
0 siblings, 1 reply; 2+ messages in thread
From: Liu Bo @ 2015-08-07 8:48 UTC (permalink / raw)
To: linux-btrfs
The file layout is
[extent 1]...[extent n][4k extent][HOLE][extent x]
extent 1~n and 4k extent can be merged during defrag, and the whole
defrag bytes is larger than our defrag thresh(256k), 4k extent as a
tail is left unmerged since we check if its next extent can be merged
(the next one is a hole, so the check will fail), the layout thus can
be
[new extent][4k extent][HOLE][extent x]
(1~n)
To fix it, beside looking at the next one, this also looks at the
previous one by checking @defrag_end, which is set to 0 when we
decide to stop merging contiguous extents, otherwise, we can merge
the previous one with our extent.
Also, this makes btrfs behave consistent with how xfs and ext4 do.
Signed-off-by: Liu Bo <bo.li.liu@oracle.com>
---
fs/btrfs/ioctl.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index 0770c91..0691b2b 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -1030,6 +1030,7 @@ static int should_defrag_range(struct inode *inode, u64 start, u32 thresh,
struct extent_map *em;
int ret = 1;
bool next_mergeable = true;
+ bool prev_mergeable = true;
/*
* make sure that once we start defragging an extent, we keep on
@@ -1050,13 +1051,16 @@ static int should_defrag_range(struct inode *inode, u64 start, u32 thresh,
goto out;
}
+ if (!*defrag_end)
+ prev_mergeable = false;
+
next_mergeable = defrag_check_next_extent(inode, em);
/*
* we hit a real extent, if it is big or the next extent is not a
* real extent, don't bother defragging it
*/
if (!compress && (*last_len == 0 || *last_len >= thresh) &&
- (em->len >= thresh || !next_mergeable))
+ (em->len >= thresh || (!next_mergeable && !prev_mergeable)))
ret = 0;
out:
/*
--
2.1.0
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH] Btrfs: fix defrag to merge tail file extent
2015-08-07 8:48 [PATCH] Btrfs: fix defrag to merge tail file extent Liu Bo
@ 2015-08-07 8:50 ` Liu Bo
0 siblings, 0 replies; 2+ messages in thread
From: Liu Bo @ 2015-08-07 8:50 UTC (permalink / raw)
To: linux-btrfs
Writing a xfstests case for this, will come soon.
Thanks,
-liubo
On Fri, Aug 07, 2015 at 04:48:41PM +0800, Liu Bo wrote:
> The file layout is
>
> [extent 1]...[extent n][4k extent][HOLE][extent x]
>
> extent 1~n and 4k extent can be merged during defrag, and the whole
> defrag bytes is larger than our defrag thresh(256k), 4k extent as a
> tail is left unmerged since we check if its next extent can be merged
> (the next one is a hole, so the check will fail), the layout thus can
> be
>
> [new extent][4k extent][HOLE][extent x]
> (1~n)
>
> To fix it, beside looking at the next one, this also looks at the
> previous one by checking @defrag_end, which is set to 0 when we
> decide to stop merging contiguous extents, otherwise, we can merge
> the previous one with our extent.
>
> Also, this makes btrfs behave consistent with how xfs and ext4 do.
>
> Signed-off-by: Liu Bo <bo.li.liu@oracle.com>
> ---
> fs/btrfs/ioctl.c | 6 +++++-
> 1 file changed, 5 insertions(+), 1 deletion(-)
>
> diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
> index 0770c91..0691b2b 100644
> --- a/fs/btrfs/ioctl.c
> +++ b/fs/btrfs/ioctl.c
> @@ -1030,6 +1030,7 @@ static int should_defrag_range(struct inode *inode, u64 start, u32 thresh,
> struct extent_map *em;
> int ret = 1;
> bool next_mergeable = true;
> + bool prev_mergeable = true;
>
> /*
> * make sure that once we start defragging an extent, we keep on
> @@ -1050,13 +1051,16 @@ static int should_defrag_range(struct inode *inode, u64 start, u32 thresh,
> goto out;
> }
>
> + if (!*defrag_end)
> + prev_mergeable = false;
> +
> next_mergeable = defrag_check_next_extent(inode, em);
> /*
> * we hit a real extent, if it is big or the next extent is not a
> * real extent, don't bother defragging it
> */
> if (!compress && (*last_len == 0 || *last_len >= thresh) &&
> - (em->len >= thresh || !next_mergeable))
> + (em->len >= thresh || (!next_mergeable && !prev_mergeable)))
> ret = 0;
> out:
> /*
> --
> 2.1.0
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2015-08-07 8:50 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-08-07 8:48 [PATCH] Btrfs: fix defrag to merge tail file extent Liu Bo
2015-08-07 8:50 ` Liu Bo
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox