9 Changing RAID Level
The RAID level of a btrfs file system can also be changed online. Let's assume we're using RAID0 for data and metadata and want to change to RAID1, this can be done as follows:
btrfs balance start -dconvert=raid1 -mconvert=raid1 /mnt
10 Creating Subvolumes
With btrfs, we can create subvolumes in volumes or other subvolumes, and we can take snapshots of these subvolumes or mount subvolumes instead of the top-level volume.
To create the subvolume /mnt/sv1 in the /mnt volume, we run:
btrfs subvolume create /mnt/sv1
This subvolume looks like a normal directory...
ls -l /mnt
root@server1:~# ls -l /mnt/
total 0
drwxr-xr-x 1 root root 0 Nov 21 16:06 sv1
root@server1:~#
... but it's a subvolume of /mnt (with the suvolid 265 in this case):
btrfs subvolume list /mnt
root@server1:~# btrfs subvolume list /mnt
ID 265 top level 5 path sv1
root@server1:~#
To create a subvolume of a subvolume (e.g. /mnt/sv1/sv12), run:
btrfs subvolume create /mnt/sv1/sv12
The command...
btrfs subvolume list /mnt
... lists now also the new subvolume:
root@server1:~# btrfs subvolume list /mnt
ID 265 top level 5 path sv1
ID 266 top level 5 path sv1/sv12
root@server1:~#
11 Mounting Subvolumes
When you mount the top-level volume, this also mounts any subvolume automatically. But with btrfs, it is also possible to mount a subvolume instead of the top-level volume.
For example, to mount the subvolume with the ID 266 (which we created in the last chapter) to the /mnt directory, first unmount the top-level volume...
umount /dev/sdb
... and then mount the subvolume like this:
mount -o subvolid=266 /dev/sdb /mnt
(Instead of the subvolid, you can also use its name from the btrfs subvolume list /mnt output:
mount -o subvol=sv1/sv12 /dev/sdb /mnt
)
To mount the default volume again, unmount /mnt...
umount /dev/sdb
... and run the mount command like this:
mount /dev/sdb /mnt
This is in fact equivalent to the command...
mount -o subvolid=0 /dev/sdb /mnt
... because the top-level volume has the subvolid 0.
If you want to make the subvolume with the subvolid 266 the default volume (so that you can mount it without any parameters), just run...
btrfs subvolume set-default 266 /mnt
... and then unmount/mount again:
umount /dev/sdb
mount /dev/sdb /mnt
Now the subvolume with the ID 266 is mounted to /mnt instead of the top-level volume.
If you've changed the default subvolume and want to mount the top-level volume again, you must either use the subvolid 0 with the mount command...
umount /dev/sdb
mount -o subvolid=0 /dev/sdb /mnt
... or make the top-level volume the default one again:
btrfs subvolume set-default 0 /mnt
Then unmount/mount again:
umount /dev/sdb
mount /dev/sdb /mnt
12 Deleting Subvolumes
Subvolumes can be deleted using their path while they are mounted. For example, the subvolume /mnt/sv1/sv12 can be deleted as follows:
btrfs subvolume delete /mnt/sv1/sv12
The command...
btrfs subvolume list /mnt
... shouldn't list the deleted subvolume anymore:
root@server1:~# btrfs subvolume list /mnt
ID 265 top level 5 path sv1
root@server1:~#
13 Creating Snapshots
One of the most useful btrfs features is that you can create snapshots of subvolumes online. This can be useful for doing rollbacks or creating consistent backups.
Let's create some test files in our /mnt/sv1 subvolume:
touch /mnt/sv1/test1 /mnt/sv1/test2
Now we take a snapshot called /mnt/sv1_snapshot of the /mnt/sv1 subvolume:
btrfs subvolume snapshot /mnt/sv1 /mnt/sv1_snapshot
If everything went well, we should find our test files in the snapshot as well:
ls -l /mnt/sv1_snapshot
root@server1:~# ls -l /mnt/sv1_snapshot
total 0
-rw-r--r-- 1 root root 0 Nov 21 16:23 test1
-rw-r--r-- 1 root root 0 Nov 21 16:23 test2
root@server1:~#
14 Taking Snapshots Of Files
With btrfs, it's even possible to take a snapshot of a single file.
For example, to take a snaptshot of the file /mnt/sv1/test1, you can run:
cp --reflink /mnt/sv1/test1 /mnt/sv1/test3
As long as the contents of /mnt/sv1/test1 doesn't change, the snapshot /mnt/sv1/test3 will not take up any space! Only if the original file /mnt/sv1/test1 is modified, will the original contents be copied to the snapshot /mnt/sv1/test3.
15 Defragmentation
To defragment a btrfs file system, you can run:
btrfs filesystem defrag /mnt
Please note that this command is useful only on normal hard drives, not on solid state disks (SSDs)!
16 Converting An ext3/ext4 File System To btrfs
It is possible to convert an ext3 or ext4 file system to btrfs (and also to do a rollback). To do this for your system partition, you need to boot into a rescue system - for Ubuntu 12.10, I've written a tutorial about this: How To Convert An ext3/ext4 Root File System To btrfs On Ubuntu 12.10
For non-system partitions, this can be done without a reboot. In this example, I want to convert my ext4 partition /dev/sdb1 (mounted to /mnt) to btrfs:
First unmount the partition and run a file system check:
umount /mnt
fsck -f /dev/sdb1
Then do the conversion as follows:
btrfs-convert /dev/sdb1
root@server1:~# btrfs-convert /dev/sdb1
creating btrfs metadata.
creating ext2fs image file.
cleaning up system chunk.
conversion complete.
root@server1:~#
That's it - you can now mount the btrfs partition:
mount /dev/sdb1 /mnt
The conversion has created an ext2_saved subvolume with an image of the original partition:
btrfs subvolume list /mnt
root@server1:~# btrfs subvolume list /mnt
ID 256 top level 5 path ext2_saved
root@server1:~#
If you want to do a rollback, you must keep that subvolume. Otherwise, you can delete it to free up some space:
btrfs subvolume delete /mnt/ext2_saved
16.1 Doing A Rollback To ext3/ext4
Let's assume you're not happy with the result - this is how you can roll back to the original file system (ext3 or ext4):
The conversion should have created an ext2_saved subvolume with an image of the original partition:
btrfs subvolume list /mnt
root@server1:~# btrfs subvolume list /mnt
ID 256 top level 5 path ext2_saved
root@server1:~#
This image will be used to do the rollback.
Unmount the partition...
umount /mnt
... then do the rollback...
btrfs-convert -r /dev/sdb1
... and finally mount the original partition again:
mount /dev/sdb1 /mnt