5

After shrinking a BTRFS file system using "btrfs filesystem resize /mnt -20g", this space doesn't show up as free for allocation in GParted. It doesn't seem like GParted can resize the btrfs partition on its own either. Rebooting doesn't help.

The various ways to check freespace on a btrfs volume https://btrfs.wiki.kernel.org/index.php/FAQ#Why_are_there_so_many_ways_to_check_the_amount_of_free_space.3F do show that the total space has shrunk by 20 GB.

How can I reclaim this space to use for another new partition on the hard disk?

2 Answers 2

3

Thanks to help from cwillu and mig at freenode, I figured out the solution. The btrfs filesystem resize command just like resize2fs resizes the filesystem, but keeps the partition limits unchanged. These can be changed using the fdisk to delete the btrfs partition and then recreating it with an endpoint which is slighty less than 20Gb smaller than the current endpoint, since the freespace is at the end. Run btrfsck to ensure everything is fine, otherwise revert back to the previous partition table. There are many tutorials on the web on this process.

2
  • 2
    "Many"? Sadly, I can't find any relevant ones. Commented Jun 9, 2020 at 11:45
  • 1
    Me neither. A helpful link would be nice. Commented Feb 26, 2022 at 18:24
0

Method 1
The easiest and safest way to do this is with GParted.

Method 2
The below is an explanation of how to do this using command line tools.

Shrinking a btrfs file system

Assuming you have a btrfs file system residing in just one partition on one device.

Mount the file system locally, find out what is the minimum size it can safely be shrunk to:
sudo btrfs inspect-internal min-dev-size /mnt/point/

This gives the minimum safe size in bytes.
Use google to convert this to Kibibytes. Let's say you get 150908 Kibibytes.

Check the file system for any errors:
sudo btrfs check /mnt/point

!! Warning, if used incorrectly, this could delete your data !!

Resize the BTRFS filesystem to the smallest size it can safely be shrunk to:
sudo btrfs filesystem resize 1:150908K /mnt/point/

Check the file system for any errors:
sudo btrfs check /mnt/point

Shrinking a partition around a btrfs file system

Let's say you have an image file disk.img of a disk with one partition that contains a btrfs file system and you want to shrink that partition around the file system leaving as little space as possible.

This is a simple case where the btrfs file system entirely resides in ONE partition on ONE disk.

  • Create a loop device for the image file

    sudo losetup --show --find --partscan disk.img

    Mostly likely the device will be available at /dev/loop0 and the partition at /dev/loop0p1

  • While the partition is not mounted, check the file system for any errors

    sudo btrfs check '/dev/loop0p1'

  • Use btrfs tools to get the dimensions (in sectors) of the btrfs file system

    sudo btrfs filesystem show --raw /dev/loop0p1

  • Use Parted command to get the dimensions (in sectors) of the disk image its partition(s):

    sudo parted -s -a opt /dev/loop0 "unit s print"

!! Warning, if used incorrectly, this could delete your data !!

  • Use this command to shrink the partition around the btrfs file system

    echo -e "resizepart 1 [partition_end_sector]s\nyes\nunit s\nprint\nquit" | sudo parted /dev/loop0 ---pretend-input-tty

  • Check the file system for any errors

    sudo btrfs check '/dev/loop0p1'

Some parameters explained:
resizepart 1 - This means to resize partition number 1.
[partition_end_sector]s - The desired new End Sector of the newly resized partition.
---pretend-input-tty - This simulates an interactive session with parted. You echo the parameters to it and the command executes all in one go without requiring any user input. This is an undocumented feature of parted but I got confirmation from the parted developers that there are no plans to remove this feature because they use it to test all new versions of parted.

Calculation of the “New End Sector of Partition”:
• As explained in this thread we need the partition start sector and the desired new partition size (in sectors).
• The new partition size is calculated based on the sector size of the partition (e.g: 1 sector = 512 bytes, from output of parted command above) and the size (in sectors) of the btrfs file system (from the btrfs command above).
• New partition size (in sectors) = [Size of btrfs filesystem in bytes] / 512 bytes sector size
partition_end_sector = Partition Start Sector (e.g 2048 - from parted output above) + new_partition_size (in sectors) - 1

Notes of Warning

  • If used incorrectly the above parted command could potentially delete your data. If in doubt you should simply use parted in interactive mode!
  • The partition is shrunk to just 1 sector larger than the btrfs file system. I assume the btrfs file system has first been shrunk to a safe size e.g: using btrfs inspect-internal min-dev-size [mount point] as explained in the btrfs docs.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .