It is a common task to resize/expand btrfs file system since btrfs is widely used in CentOS/RHEL 7 and also as Docker’s backend storage driver. This post illustrates 2 common procedures to expand a btrfs root volume:
- Expand to use available space on original disk
- Add a new disk into the same btrfs volume
Note:
These procedures are risky due to possible mistakes made in changing existing partitions or unexpected power outages during btrfs balance operation, please make sure your data/system has a latest usable BACKUP.
1. Resizing partition to use available space on original disk
1. Verify your disk space and current partition’s size with fdisk or parted if your disk is larger than 2 terabyes:
# fdisk -l /dev/xvda Disk /dev/xvda: 53.7 GB, 53687091200 bytes, 104857600 sectors Units = sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk label type: dos Disk identifier: 0x00087895 Device Boot Start End Blocks Id System /dev/xvda1 * 2048 1030143 514048 83 Linux /dev/xvda2 1030144 9418751 4194304 82 Linux swap / Solaris /dev/xvda3 9418752 31457279 11019264 83 Linux [root@host0 ~]# lsblk -f /dev/xvda NAME FSTYPE LABEL UUID MOUNTPOINT xvda ├─xvda1 xfs /boot 049e257e-25b1-4f46-80aa-ffaa27a21022 /boot ├─xvda2 swap SWAP-VM 0406d7df-68b6-47cb-8ea9-195ac7ef7497 [SWAP] └─xvda3 btrfs btr_pool 1e72a30b-d59d-458f-b04f-59bf8bdec35d /
2. fdisk does not support resize partition, so you need to delete the old partition which you want to change and create a new one.
# fdisk /dev/xvda Welcome to fdisk (util-linux 2.23.2). Changes will remain in memory only, until you decide to write them. Be careful before using the write command. Command (m for help): p Disk /dev/xvda: 53.7 GB, 53687091200 bytes, 104857600 sectors Units = sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk label type: dos Disk identifier: 0x00087895 Device Boot Start End Blocks Id System /dev/xvda1 * 2048 1030143 514048 83 Linux /dev/xvda2 1030144 9418751 4194304 82 Linux swap / Solaris /dev/xvda3 9418752 31457279 11019264 83 Linux Command (m for help): d Partition number (1-3, default 3): 3 Partition 3 is deleted
3. Lets now create a new partition.
Command (m for help): n Partition type: p primary (2 primary, 0 extended, 2 free) e extended Select (default p): p Partition number (3,4, default 3): 3 First sector (9418752-104857599, default 9418752): Using default value 9418752 Last sector, +sectors or +size{K,M,G} (9418752-104857599, default 104857599): Using default value 104857599 Partition 3 of type Linux and of size 45.5 GiB is set Command (m for help): w The partition table has been altered! Calling ioctl() to re-read partition table. WARNING: Re-reading the partition table failed with error 16: Device or resource busy. The kernel still uses the old table. The new table will be used at the next reboot or after you run partprobe(8) or kpartx(8) Syncing disks.
4. Verify the newly created partition using “fdisk -l
”.
# fdisk -l /dev/xvda Disk /dev/xvda: 53.7 GB, 53687091200 bytes, 104857600 sectors Units = sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk label type: dos Disk identifier: 0x00087895 Device Boot Start End Blocks Id System /dev/xvda1 * 2048 1030143 514048 83 Linux /dev/xvda2 1030144 9418751 4194304 82 Linux swap / Solaris /dev/xvda3 9418752 104857599 47719424 83 Linux
5. You need to let Linux kernel know the change you made to /dev/xvda
using the “partprobe
” command:
# partprobe Error: Partition(s) 3 on /dev/xvda have been written, but we have been unable to inform the kernel of the change, probably because it/they are in use. As a result, the old partition(s) will remain in use. You should reboot now before making further changes.
6. As it is root file system which is being used, you have to reboot OS to let kernel see the change. If it is not a root filesystem, you may skip this step.
# shutdown -r now
Expanding btfrs Filesystem
1. Now you can expand the btrfs root file system.
# btrfs filesystem resize +10g / Resize '/' of '+10g'
2. Verify the new filesystem size in “df -h” command output.
# df -h / Filesystem Size Used Avail Use% Mounted on /dev/xvda3 21G 2.5G 17G 14% /
You may also use all the space on the disk if you want. Use the option “max
” with “btrfs filesystem resize
” command.
# btrfs filesystem resize max / Resize '/' of 'max'
# df -h / Filesystem Size Used Avail Use% Mounted on /dev/xvda3 46G 2.5G 42G 6% /
2. Add a new disk to btrfs volume
1. You can add a new disk to the system by either presenting a new LUN or attach a new virtual disk if you are running a virtual machine. You may need to run below script to scan the new LUN/disk.
# rescan-scsi-bus.sh -a
or reboot system to make the new disk visible to OS,
2. Verify the new disk can be seen by operating system using the commands “sblk -f
” or “fdisk -l
”. For example /dev/xvdb is the new disk for the example in this post.
# lsblk -f NAME FSTYPE LABEL UUID MOUNTPOINT xvda ├─xvda1 xfs /boot 049e257e-25b1-4f46-80aa-ffaa27a21022 /boot ├─xvda2 swap SWAP-VM 0406d7df-68b6-47cb-8ea9-195ac7ef7497 [SWAP] └─xvda3 btrfs btr_pool 1e72a30b-d59d-458f-b04f-59bf8bdec35d / xvdb
# fdisk -l /dev/xvdb Disk /dev/xvdb: 10.7 GB, 10737418240 bytes, 20971520 sectors Units = sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes
3. Add new disk /dev/xvdb to root volume
# btrfs device add /dev/xvdb /
4. Distribute meta data from first disk /dev/xvda to the 2nd disk /dev/xvdb.
# btrfs filesystem balance / WARNING: Full balance without filters requested. This operation is very intense and takes potentially very long. It is recommended to use the balance filters to narrow down the balanced data. Use 'btrfs balance start --full-balance' option to skip this warning. The operation will start in 10 seconds. Use Ctrl-C to stop it. 10 9 8 7 6 5 4 3 2 1 Starting balance without any filters. Done, had to relocate 9 out of 9 chunks
5. Verify the new size of the filesystem using “df -h”.
# df -h / Filesystem Size Used Avail Use% Mounted on /dev/xvda3 56G 2.5G 52G 5% /
You can see the root file system is increased another 10G which is /dev/xvdb’s size.