The Btrfs filesystem has built-in multi-device support, so you can create different levels of RAID using it.

Once you’ve created a Btrfs RAID, you can add more storage devices to the RAID to expand the RAID. But, once you have added more storage devices to the RAID, Btrfs won’t spread the existing data/metadata/system-data to the new storage devices automatically. So, you may not get the desired throughput (read/write speed) out of the RAID, and it may not be able to populate the new storage devices with the required redundant data. So, the RAID array may fail to survive the desired number of drive failures.

To solve these problems, the Btrfs filesystem provides a built-in balancing tool. The Btrfs balance utility will spread the data/metadata/system-data of the existing storage devices of the RAID to the newly added storage devices.

In this article, I am going to show you how to use the Btrfs balance utility to spread the data/metadata/system-data of the existing storage devices of the RAID to the newly added storage devices. So, let’s get started!

Abbreviations

RAID – Redundant Array of Inexpensive/Independent Disks

MB – Megabyte

GB – Gigabyte

Prerequisites

To follow this article, you need to have a working Btrfs RAID or multi-device setup.

I have created a Btrfs RAID in RAID-0 configuration using 4 storage devices sdb, sdc, sdd, and sde.

As you can see, the Btrfs filesystem allocated 1 GB of disk space for data1 256 MB of disk space for metadata2, and 4 MB of disk space for system-data3 from each of the storage devices in the RAID.

About 18.75 GB out of 20 GB is still unallocated4 from each of the storage devices of the RAID.

$ sudo btrfs filesystem usage /data

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/01/echo/How-to-Use-Btrfs-Balance_1.jpg" data-lazy- height="865" src="data:image/svg xml,” width=”849″>

Writing a Script to Generate Random Files

To show you how the Btrfs balance utility works, we need to generate some random files to fill up the Btrfs filesystem. Let’s create a shell script that does just that.

Create a new shell script genfiles.sh in the /usr/local/bin/ directory as follows:

$ sudo nano /usr/local/bin/genfiles.sh

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/01/echo/How-to-Use-Btrfs-Balance_2.jpg" data-lazy- height="86" src="data:image/svg xml,” width=”685″>

Type in the following lines of codes in the genfiles.sh shell script.

#!/bin/bash

while true

do


    FILENAME=$(uuidgen)


    echo “[Creating] $FILENAME


    dd if=/dev/random of=$FILENAME bs=1M count=256 status=progress


    echo “[Created] $FILENAME

done

Once you’re done, press X followed by Y and to save the genfiles.sh shell script.

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/01/echo/How-to-Use-Btrfs-Balance_3.jpg" data-lazy- height="434" src="data:image/svg xml,” width=”831″>

The genfiles.sh shell script runs an infinite while loop.

while true

do


    # other codes

done

The following line generates a UUID using the uuidgen command and stores the UUID in the FILENAME variable.

<img alt="" data-lazy-src="https://kirelos.com/wp-content/uploads/2021/01/echo/How-to-Use-Btrfs-Balance_4.jpg" height="34" src="data:image/svg xml,” width=”244″>

The following line prints a message on the console before the file FILENAME is generated.

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/01/echo/How-to-Use-Btrfs-Balance_5.jpg" data-lazy- height="36" src="data:image/svg xml,” width=”356″>

The following line generates a new random file FILENAME using the dd command. The file will be 256 MB in size.

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/01/echo/How-to-Use-Btrfs-Balance_6.jpg" data-lazy- height="35" src="data:image/svg xml,” width=”779″>

The following line prints a message on the console after the file FILENAME is generated.

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/01/echo/How-to-Use-Btrfs-Balance_7.jpg" data-lazy- height="34" src="data:image/svg xml,” width=”338″>

Add execute permission to the genfiles.sh shell script as follows:

$ sudo chmod x /usr/local/bin/genfiles.sh

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/01/echo/How-to-Use-Btrfs-Balance_8.jpg" data-lazy- height="101" src="data:image/svg xml,” width=”703″>

The genfiles.sh shell script should now be accessible as any other commands.

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/01/echo/How-to-Use-Btrfs-Balance_9.jpg" data-lazy- height="143" src="data:image/svg xml,” width=”539″>

Generating Random Files in the Btrfs Filesystem

We want to generate random files in the Btrfs RAID. Let’s say, the Btrfs RAID is mounted on the /data directory.

Navigate to the /data directory where the Btrfs RAID is mounted as follows:

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/01/echo/How-to-Use-Btrfs-Balance_10.jpg" data-lazy- height="115" src="data:image/svg xml,” width=”533″>

As you can see, there are no files available in my Btrfs RAID at the moment.

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/01/echo/How-to-Use-Btrfs-Balance_11.jpg" data-lazy- height="136" src="data:image/svg xml,” width=”549″>

To generate some random files in the current working directory (/data directory in this case), run the genfiles.sh shell script as follows:

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/01/echo/How-to-Use-Btrfs-Balance_12.jpg" data-lazy- height="84" src="data:image/svg xml,” width=”554″>

The genfiles.sh shell script should start generating random files in the /data directory.

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/01/echo/How-to-Use-Btrfs-Balance_13.jpg" data-lazy- height="274" src="data:image/svg xml,” width=”695″>

The genfiles.sh script is generating random files. Let the script run for a couple of minutes, so it fills up about 2-3 GB of disk space of the Btrfs RAID.

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/01/echo/How-to-Use-Btrfs-Balance_14.jpg" data-lazy- height="367" src="data:image/svg xml,” width=”839″>

When you want to stop the genfiles.sh shell script, press C.

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/01/echo/How-to-Use-Btrfs-Balance_15.jpg" data-lazy- height="357" src="data:image/svg xml,” width=”827″>

As you can see, some random files are generated in the Btrfs RAID.

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/01/echo/How-to-Use-Btrfs-Balance_16.jpg" data-lazy- height="694" src="data:image/svg xml,” width=”840″>

As you can see, the Btrfs RAID allocated 2 GB from each of the storage devices added to the RAID. Previously the Btrfs RAID allocated 1 GB from each of the storage devices added to the RAID.

The unallocated disk space has been reduced from 18.75 GB to 17.75 GB in all the storage devices of the RAID.

$ sudo btrfs filesystem usage /data

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/01/echo/How-to-Use-Btrfs-Balance_17.jpg" data-lazy- height="866" src="data:image/svg xml,” width=”841″>

Adding Another Storage Device to the Btrfs RAID

To show you how to balance a Btrfs RAID after adding a new storage device, you have to add a new storage device to it.

I have added a new HDD sdf to my computer, which I want to add to the Btrfs RAID mounted on the /data directory. Let’s see how to do it.

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/01/echo/How-to-Use-Btrfs-Balance_18.jpg" data-lazy- height="352" src="data:image/svg xml,” width=”671″>

Navigate to a different directory (i.e., HOME directory) from the /data directory as follows:

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/01/echo/How-to-Use-Btrfs-Balance_19.jpg" data-lazy- height="106" src="data:image/svg xml,” width=”538″>

To add the storage device sdf to the Btrfs RAID mounted on the /data directory, run the following command:

$ sudo btrfs device add /dev/sdf /data

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/01/echo/How-to-Use-Btrfs-Balance_20.jpg" data-lazy- height="86" src="data:image/svg xml,” width=”693″>

As you can see, the storage device sdf is added to the Btrfs RAID. The RAID size has increased from 80 GB to 100 GB.

$ sudo btrfs filesystem usage /data

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/01/echo/How-to-Use-Btrfs-Balance_21.jpg" data-lazy- height="881" src="data:image/svg xml,” width=”841″>

Balancing the Btrfs RAID

As you can see, the newly added storage device (sdf) of the RAID (mounted on the /data directory) has 20 GB unallocated, and the other storage devices (sdb, sdc, sdd, sde, etc.) have 17.75 GB unallocated.

$ sudo btrfs filesystem usage /data

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/01/echo/How-to-Use-Btrfs-Balance_211.jpg" data-lazy- height="881" src="data:image/svg xml,” width=”841″>

The data1, metadata2, and system-data3 are only available on the existing storage devices of the RAID, not the newly added storage device.

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/01/echo/How-to-Use-Btrfs-Balance_22.jpg" data-lazy- height="887" src="data:image/svg xml,” width=”836″>

To spread out the data, metadata, and system-data on all the storage devices of the RAID (including the newly added storage device) mounted on the /data directory, run the following command:

$ sudo btrfs balance start –full-balance /data

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/01/echo/How-to-Use-Btrfs-Balance_23.jpg" data-lazy- height="92" src="data:image/svg xml,” width=”770″>

It may take a while to spread out the data, metadata, and system-data on all the storage devices of the RAID ifit contains a lot of data.

Once the storage devices of the RAID are properly balanced, you should see the following message.

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/01/echo/How-to-Use-Btrfs-Balance_24.jpg" data-lazy- height="154" src="data:image/svg xml,” width=”847″>

As you can see, after the balance operation is completed, the newly added storage device has an equal amount of unallocated disk space as the other storage devices of the RAID.

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/01/echo/How-to-Use-Btrfs-Balance_25.jpg" data-lazy- height="964" src="data:image/svg xml,” width=”899″>

After the balance operation, an equal amount of disk space as the other storage devices of the RAID is allocated for the data, metadata, and system-data from the newly added storage device (sdf) of the RAID.

<img alt="" data-lazy- data-lazy-src="https://kirelos.com/wp-content/uploads/2021/01/echo/How-to-Use-Btrfs-Balance_26.jpg" data-lazy- height="964" src="data:image/svg xml,” width=”899″>

Conclusion

In this article, I have discussed the purpose of the Btrfs balance utility, as well as how to balance a Btrfs RAID or multi-device filesystem after adding new storage devices to the RAID or multi-device filesystem.

About the author

<img alt="Shahriar Shovon" data-lazy-src="https://kirelos.com/wp-content/uploads/2021/01/echo/photo2-150×150.png60120af5c0864.jpg" height="112" src="data:image/svg xml,” width=”112″>

Shahriar Shovon

Freelancer & Linux System Administrator. Also loves Web API development with Node.js and JavaScript. I was born in Bangladesh. I am currently studying Electronics and Communication Engineering at Khulna University of Engineering & Technology (KUET), one of the demanding public engineering universities of Bangladesh.