Commit 5db7ccf
btrfs: optimize fill_holes() to merge a new hole with both adjacent items
fill_holes() currently merges a punched hole with either the previous
or the next file extent item, but never both in the same call. When
holes are punched in a non-sequential order this leaves consecutive
hole items in the inode's subvolume tree that should have been collapsed
into a single one.
This is a minor metadata optimization that reduces the number of file
extent items when holes are punched in non-sequential order. While
having extra file extent items is harmless and has no functional
impact, reducing metadata overhead can benefit workloads with heavily
fragmented hole patterns.
For example:
fallocate -p -o 4K -l 4K ${FILE}
fallocate -p -o 12K -l 4K ${FILE}
fallocate -p -o 8K -l 4K ${FILE}
After the third punch the [4K, 8K) and [12K, 16K) holes become
adjacent to the new [8K, 12K) hole, but fill_holes() merges only one
side and leaves two separate hole items ([4K, 12K) and [12K, 16K))
instead of the expected single [4K, 16K) hole item.
Fix this by checking both path->slots[0] - 1 and path->slots[0] in one
pass:
- If only the previous slot is mergeable, extend it forward as
before.
- If only the next slot is mergeable, extend it backward and update
its key offset as before.
- If both are mergeable, extend the previous item to cover the new
hole plus the next item, and remove the redundant next item with
btrfs_del_items().
Because the merge path may now delete an item, switch the initial
btrfs_search_slot() call from a plain lookup (ins_len = 0) to a
search-for-deletion (ins_len = -1), so the leaf is prepared for a
possible item removal.
Note: This optimization only applies to filesystems without the
NO_HOLES feature enabled. Since NO_HOLES is now the default, this
primarily benefits older filesystems or those explicitly created with
NO_HOLES disabled.
Signed-off-by: Dave Chen <davechen@synology.com>
Reviewed-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: Filipe Manana <fdmanana@suse.com>1 parent 436ac81 commit 5db7ccf
1 file changed
Lines changed: 32 additions & 17 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2067 | 2067 | | |
2068 | 2068 | | |
2069 | 2069 | | |
| 2070 | + | |
| 2071 | + | |
| 2072 | + | |
| 2073 | + | |
2070 | 2074 | | |
2071 | 2075 | | |
2072 | 2076 | | |
| |||
2076 | 2080 | | |
2077 | 2081 | | |
2078 | 2082 | | |
2079 | | - | |
| 2083 | + | |
2080 | 2084 | | |
2081 | 2085 | | |
2082 | 2086 | | |
| |||
2089 | 2093 | | |
2090 | 2094 | | |
2091 | 2095 | | |
2092 | | - | |
2093 | | - | |
2094 | | - | |
2095 | | - | |
| 2096 | + | |
2096 | 2097 | | |
2097 | 2098 | | |
2098 | 2099 | | |
2099 | | - | |
2100 | | - | |
2101 | | - | |
2102 | | - | |
2103 | | - | |
| 2100 | + | |
2104 | 2101 | | |
2105 | | - | |
2106 | 2102 | | |
2107 | | - | |
2108 | | - | |
2109 | | - | |
2110 | | - | |
2111 | 2103 | | |
2112 | 2104 | | |
2113 | | - | |
2114 | | - | |
| 2105 | + | |
| 2106 | + | |
| 2107 | + | |
| 2108 | + | |
| 2109 | + | |
| 2110 | + | |
| 2111 | + | |
| 2112 | + | |
| 2113 | + | |
| 2114 | + | |
| 2115 | + | |
| 2116 | + | |
| 2117 | + | |
2115 | 2118 | | |
2116 | 2119 | | |
| 2120 | + | |
| 2121 | + | |
| 2122 | + | |
| 2123 | + | |
2117 | 2124 | | |
2118 | 2125 | | |
| 2126 | + | |
| 2127 | + | |
| 2128 | + | |
| 2129 | + | |
| 2130 | + | |
| 2131 | + | |
| 2132 | + | |
| 2133 | + | |
2119 | 2134 | | |
2120 | 2135 | | |
2121 | 2136 | | |
| |||
0 commit comments