From af265a0e5835cef7db3241b06d94a02348824e49 Mon Sep 17 00:00:00 2001 From: Ivan Shapovalov Date: Sun, 5 Sep 2021 11:00:45 +0300 Subject: [PATCH 1/2] btrfs-balance-least-used: sort block groups by bytes used, not percentage used This way, we can quickly clean up completely empty block groups. Additionally, if `btrfs-balance-least-used -u 0` is invoked, only consider fully empty block groups because this seems a useful edge case (there can be a lot of almost-empty block groups which are technically used_pct==0 but still take a lot of time to balance, so the user may as well invoke with `-u 1`). --- bin/btrfs-balance-least-used | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/bin/btrfs-balance-least-used b/bin/btrfs-balance-least-used index 7005347..c6264ec 100755 --- a/bin/btrfs-balance-least-used +++ b/bin/btrfs-balance-least-used @@ -43,8 +43,11 @@ def load_block_groups(fs, max_used_pct): continue try: block_group = fs.block_group(chunk.vaddr, chunk.length) - if block_group.used_pct <= max_used_pct: - block_groups.append((block_group.used_pct, block_group)) + # if max_used_pct == 0, only balance completely empty block groups + if (max_used_pct == 0 + and block_group.used == 0 + or block_group.used_pct <= max_used_pct): + block_groups.append((block_group.used, block_group.used_pct, block_group)) if block_group.used_pct < min_used_pct: min_used_pct = block_group.used_pct except IndexError: @@ -55,13 +58,14 @@ def load_block_groups(fs, max_used_pct): def balance_one_block_group(fs, block_groups, max_used_pct): - next_used_pct, next_block_group = block_groups[0] + next_used, next_used_pct, next_block_group = block_groups[0] try: block_group = fs.block_group(next_block_group.vaddr, next_block_group.length) except IndexError: heapq.heappop(block_groups) return vaddr = block_group.vaddr + used = block_group.used used_pct = block_group.used_pct if used_pct > next_used_pct: if used_pct > max_used_pct: @@ -71,14 +75,14 @@ def balance_one_block_group(fs, block_groups, max_used_pct): else: print("Postponing block group vaddr {} used_pct changed {} -> {}".format( vaddr, next_used_pct, used_pct)) - heapq.heapreplace(block_groups, (used_pct, block_group)) + heapq.heapreplace(block_groups, (used, used_pct, block_group)) return start_time = time.time() heapq.heappop(block_groups) args = btrfs.ioctl.BalanceArgs(vstart=vaddr, vend=vaddr+1) - print("Balance block group vaddr {} used_pct {} ...".format( - vaddr, used_pct), end='', flush=True) + print("Balance block group vaddr {} used_pct {} {}...".format( + vaddr, used_pct, used == 0 and "(empty) " or ""), end='', flush=True) try: progress = btrfs.ioctl.balance_v2(fs.fd, data_args=args) end_time = time.time() @@ -96,7 +100,7 @@ def parse_args(): '--usage', type=int, default=100, - help="Only consider block groups with less than this percentage used", + help="Only consider block groups with less than this percentage used (if 0, only consider empty block groups)", ) parser.add_argument( 'mountpoint', From 3e56a10bdaf04251064291f76b5f1f59f6d75c9e Mon Sep 17 00:00:00 2001 From: Ivan Shapovalov Date: Mon, 15 Nov 2021 14:51:50 +0300 Subject: [PATCH 2/2] btrfs-balance-least-used: show bytes used, not just empty/no --- bin/btrfs-balance-least-used | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/btrfs-balance-least-used b/bin/btrfs-balance-least-used index c6264ec..27ba92e 100755 --- a/bin/btrfs-balance-least-used +++ b/bin/btrfs-balance-least-used @@ -81,8 +81,8 @@ def balance_one_block_group(fs, block_groups, max_used_pct): start_time = time.time() heapq.heappop(block_groups) args = btrfs.ioctl.BalanceArgs(vstart=vaddr, vend=vaddr+1) - print("Balance block group vaddr {} used_pct {} {}...".format( - vaddr, used_pct, used == 0 and "(empty) " or ""), end='', flush=True) + print("Balance block group vaddr {} used_pct {} (used {}) ...".format( + vaddr, used_pct, used), end='', flush=True) try: progress = btrfs.ioctl.balance_v2(fs.fd, data_args=args) end_time = time.time()