How to Manage Btrfs Filesystem in Linux

Btrfs, also pronounced as 'Butter FS' or 'B-tree FS', is a copy-on-write(CoW) filesystem for Linux.  It is GPL licensed and focuses on providing features like scalability, data integrity, defragmentation and fault tolerance among others. In this article, let us learn how to install and use some of the important features of btrfs.

Installation and Creation

First, install the btrfs packages if not already installed.  On RedHat based distros, use:

yum install btrfs-progs

On Debian based distros, use:

apt-get install btrfs-tools

Enable the btrfs kernel module using:

modprobe btrfs

Let us now make a partition on a disk and create the btrfs filesystem on it.  In the examples below, we will be using a virtual disk /dev/xvdc which does not yet have any partitions on it.

Using 'fdisk', create a new partition on the device. When prompted, choose 'n' for new partition followed by 'P' for primary and '1' for the partition number. Next, select the default values by selecting the 'Enter' key.  Then select 'w' to save the changes and exit.

[root@localhost ~]# fdisk /dev/xvdc

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.

Device does not contain a recognized partition table

Building a new DOS disklabel with disk identifier 0x4ea901ae.

The device presents a logical sector size that is smaller than

the physical sector size. Aligning to a physical sector (or optimal

I/O) size boundary is recommended, or performance may be impacted.

Command (m for help): p

Disk /dev/xvdc: 2097 MB, 2097152000 bytes, 4096000 sectors

Units = sectors of 1 * 512 = 512 bytes

Sector size (logical/physical): 512 bytes / 4096 bytes

I/O size (minimum/optimal): 4096 bytes / 4096 bytes

Disk label type: dos

Disk identifier: 0x4ea901ae

Device Boot Start End Blocks Id System

Command (m for help): n

Partition type:

p primary (0 primary, 0 extended, 4 free)

e extended

Select (default p): p

Partition number (1-4, default 1):

First sector (2048-4095999, default 2048):

Using default value 2048

Last sector, +sectors or +size{K,M,G} (2048-4095999, default 4095999): +1G

Partition 1 of type Linux and of size 1 GiB is set

Command (m for help): p

Disk /dev/xvdc: 2097 MB, 2097152000 bytes, 4096000 sectors

Units = sectors of 1 * 512 = 512 bytes

Sector size (logical/physical): 512 bytes / 4096 bytes

I/O size (minimum/optimal): 4096 bytes / 4096 bytes

Disk label type: dos

Disk identifier: 0x4ea901ae

Device Boot Start End Blocks Id System

/dev/xvdc1 2048 2099199 1048576 83 Linux

Command (m for help): w

The partition table has been altered!

Calling ioctl() to re-read partition table.

Syncing disks.

We will now create the filesystem on the partition.

mkfs.btrfs <device>

[root@localhost ~]# mkfs.btrfs /dev/xvdc1

Detected a SSD, turning off metadata duplication. Mkfs with -m dup if you want to force metadata duplication.

Btrfs v3.16.2

See for more information.

Turning ON incompat feature 'extref': increased hardlink limit per file to 65536

fs created label (null) on /dev/xvdc1

nodesize 16384 leafsize 16384 sectorsize 4096 size 1.00GiB

Next step is to create a mount point and mount the filesystem.

[root@localhost ~]# mkdir /mnt/btrfs_mount

[root@localhost ~]# mount /dev/xvdc1 /mnt/btrfs_mount/

Verify if the mount was successful using 'df -h' command

[root@localhost ~]# df -h

Filesystem Size Used Avail Use% Mounted on

/dev/root 14G 741M 13G 6% /

devtmpfs 493M 0 493M 0% /dev

tmpfs 494M 0 494M 0% /dev/shm

tmpfs 494M 14M 481M 3% /run

tmpfs 494M 0 494M 0% /sys/fs/cgroup

/dev/xvdc1 1.0G 17M 899M 2% /mnt/btrfs_mount

Some useful mount options

Btrfs offers some special mount options which we can use to control its behaviour.  To name a few,

compress [=zlib|lzo|no]   -   To turn on data compression using zlib or LZO compression. While zlib method is faser, LZO offers better compression

autodefrag   - Enables auto defragmentation of the filesystem in the background.

nodatacow -  Turn off copy-on-write for newly created files.

nodatasum - Turn off data checksum creation for new files.

The following example mounts the filesystem using lzo compression

[root@localhost ~]#mount -o compress=lzo /dev/xvdc1 /mnt/btrfs_mount

Adding and removing devices in btrfs

It is possible to add another device to the mount point.

btrfs device add <device> <mount point>

Adding a device to btrfs

Adding a device to btrfs

Notice from the 'df -h' output above that the size of the filesystem which was 1GB earlier is now increased to 2GB.

Same way, we can also remove one or more added devices / volumes:

btrfs device delete

[root@localhost ~]# btrfs device delete /dev/xvdd1 /mnt/btrfs_mount/

[root@localhost ~]# df -h

Filesystem Size Used Avail Use% Mounted on

/dev/root 14G 786M 13G 6% /

devtmpfs 493M 0 493M 0% /dev

tmpfs 494M 0 494M 0% /dev/shm

tmpfs 494M 51M 444M 11% /run

tmpfs 494M 0 494M 0% /sys/fs/cgroup

/dev/xvdc1 1.0G 17M 899M 2% /mnt/btrfs_mount

After adding or removing devices, it is possible to redistribute the data and metadata present in the filesystem across the available devices.

btrfs filesystem balance <mount point>

[root@localhost ~]# btrfs filesystem balance /mnt/btrfs_mount

Done, had to relocate 4 out of 4 chunks

Resizing the filesystem

One can increase or decrease the size of the btrfs filesystem while it is mounted, provided the underlying device has enough space to support these actions.

btrfs filesystem resize <new size> <mount point>

filesystem resize

Resizing the filesystem

Compression and defragmentation

Btrfs allows compression and defragmentation to increase the filesystem capacity and IO performance respectively.

Defragmentation is done using the following command:

btrfs filesystem defragment <mount point>

[root@localhost ~]# btrfs filesystem defragment /mnt/btrfs_mount

To compress and defragment parallelly,

btrfs filesystem defragment -c <mount point>

[root@localhost ~]# btrfs filesystem defragment -c /mnt/btrfs_mount

NOTE: In order to use the '-c' option, compression should be enabled at the time of mounting as specified previously in the 'Some useful mount options' section. 

It is also possible to defragment files and directories individually by providing the specific files and directories.

btrfs filesystem defragment -c <file-name> ......

Subvolumes, Snapshots and Quotas

Subvolumes and snapshots are one of the key features of btrfs. A subvolume is a POSIX file namespace.  It is different from LVM volumes where the volumes are block devices.  We can think of them to the ones providing a restricted view of the filesystem as they can be mounted independently. Every subvolume contains a corresponding directory under its parent filesystem. We can further create other directories under this directory and even subvolumes, but its behaviour is very similar to a normal directory.

To create a subvolume, use the following command:

#btrfs subvolume create  <subvolume>

[root@localhost ~]# btrfs subvolume create /mnt/btrfs_mount/subvol1

Create subvolume '/mnt/btrfs_mount/subvol1'

List the available subvolumes

#btrfs subvolume list <mount point>

[root@localhost ~]# btrfs subvolume list /mnt/btrfs_mount/

ID 259 gen 38 top level 5 path subvol1

We can try copying some data into the newly created subvolume.

[root@localhost ~]# cp /etc/hosts /mnt/btrfs_mount/subvol1

[root@localhost ~]# ls -l /mnt/btrfs_mount/subvol1/

total 4

-rw-r--r-- 1 root root 158 Aug 6 09:44 hosts

Let us now unmount the main filesystem and mount only the subvolume.

[root@localhost ~]# umount /mnt/btrfs_mount/

[root@localhost ~]# mount -o subvol=subvol1 /dev/xvdc1 /mnt

[root@localhost ~]# ls -l /mnt

total 4

-rw-r--r-- 1 root root 158 Aug 6 09:44 hosts

Notice that we are now seeing only the subvolume content. Anything above this level is not accessible, thus giving a restricted view.

Coming to snapshots, they help in taking a snapshot of the contents of subvolumes.

#btrfs subvolume snapshot

[root@localhost ~]# btrfs subvolume snapshot /mnt/btrfs_mount /mnt/btrfs_mount/snapshot1

Create a snapshot of '/mnt/btrfs_mount' in '/mnt/btrfs_mount/snapshot1'

[root@localhost ~]# ls -l /mnt/btrfs_mount

total 16

drwxr-xr-x 1 root root 14 Aug 4 09:56 snapshot1

drwxr-xr-x 1 root root 10 Aug 6 09:44 subvol1

Interestingly, a snapshot is itself a subvolume. We can use '-r' option in te above command to create a read-only snapshot.

We can delete any subvolume or snapshot using the 'btrfs subvol delete' command

[root@localhost ~]# btrfs subvol delete /mnt/btrfs_mount/subvol1

Transaction commit: none (default)

Delete subvolume '/mnt/btrfs_mount/subvol1'

[root@localhost ~]# btrfs subvol delete /mnt/btrfs_mount/snapshot1/

Transaction commit: none (default)

Delete subvolume '/mnt/btrfs_mount/snapshot1'

[root@localhost ~]# ls -l /mnt/btrfs_mount/

total 0

It is possible to limit one or more subvolumes from consuming all the filesystem space using quotas.

To use this, we need to first enable quotas on the filesystem before creating any subvolumes.

#btrfs quota enable <mount point>

[root@localhost ~]#btrfs quota enable /mnt/btrfs_mount

Now the subvolume can be limited:

#btrfs qgroup limit <size-limit> <subvolume-path>

[root@localhost ~]# btrfs subvolume create /mnt/btrfs_mount/svol1

Create subvolume '/mnt/btrfs_mount/svol1'

[root@localhost ~]# btrfs qgroup limit 500M /mnt/btrfs_mount/svol1/

 Other useful options

btrfs filesystem df - Shows space usage information of a given mount point

Output of 'df' in btrfs

Btrfs space usage information


btrfs filesystem show - Shows the filesystem version details

[root@localhost ~]# btrfs filesystem show /mnt/btrfs_mount/

Btrfs v3.16.2

btrfs scrub - Starts error checking on selected or all devices

[root@localhost ~]# btrfs scrub start /mnt/btrfs_mount/

scrub started on /mnt/btrfs_mount/, fsid 199b8fd8-95d4-49d5-b1b5-edc005f9bd48 (pid=20225)

Check the status of crub using the 'status' command:

[root@localhost ~]# btrfs scrub status /mnt/btrfs_mount/

scrub status for 199b8fd8-95d4-49d5-b1b5-edc005f9bd48

scrub started at Thu Aug 6 10:12:22 2015 and finished after 0 seconds

total bytes scrubbed: 288.00KiB with 0 errors

btrfs restore [options]   - Restores files from a damaged filesystem without unmounting it.

For more details on btrfs, refer the btrfs wiki.


Though Btrfs is said to be still experimental and not fully stable, some distributions have switched to it already. It is the default file system in openSuSE 13.2 . It has many advance features and a few killer features like snapshot and rollback which makes it quite popular. Down the road, this might become the chosen filesystem for other Linux distributions as well.

About B N Poornima

She is a Linux professional working on Linux and open source since 2003. She loves blogging, travelling, photography and music.

Author Archive Page

Have anything to say?

Your email address will not be published. Required fields are marked *

All comments are subject to moderation.