Tuesday, June 16, 2015

Linux BTRFS newbie thoughts: rolling back changes made to the root subvolume

If you're more intelligent than me, when you started using btrfs, you probably planned out how you are going to manage your data within a hierarchy of snapshots before using a btrfs filesystem. Let me state this more plainly, using more directive language: when using btrfs, consider mounting the root subvolume (subvolid=0) somewhere (e.g.: /media/btrfs/volume_name), for the sole purpose of managing snapshots.

Unfortunately, I wasn't that smart. I mounted my "root" btrfs volume on /backup, and willy-nilly copied files into the top level of /backup. Only later did I realize I wanted to use snapshots to allow granularity in changes made to /backup, so I created a directory /backup/snapshots/before_modification with the commands:
% mkdir /backup/snapshots
% su
# btrfs subvolume snapshot /backup /backup/snapshots/before_modification
I then made changes to the files inside of /backup, and messed something up, and then wanted to revert my changes. Okay, no problem; the btrfs system admin guide says that all I need to do is to mount the snapshot in question:
# btrfs subvolume list /backup
ID 666 Gen 5902 top level 5 path snapshots/before_modification
# umount /backup
# mount -o defaults,subvol=666 /dev/sdc1 /backup
Well, great! That worked fine; my ugly changes don't appear in /backup any more. But my btrfs filesystem is undoubtedly saving changes that I don't want to keep; these changes are associated with the 'root' subvolume (id=0). Surely, I can now delete these changes, right? (For the truly curious, you can measure the space used by a snapshot after you enable quota management). Can't I simply:
# btrfs subvolume delete 0 /backup
NOPE! Documentation says that the only argument to 'delete' is a path, and doesn't involve a subvolume ID. Uhhh... now I'm stuck. At this point, my puny brain imploded, and I had to visit #btrfs on freenode, where user darkling helped me out.

The solution? To release all of the space held by the root subvolume:
# mount -o defaults,subvol=0 /dev/sdc1 /media/btrfs/backup
# cd /media/btrfs/backup
# rm -rf dir1 dir2 dir3 dir4 ...
From there, I selectively deleted all subdirectories inside of /media/btrfs/backup -- and carefully excluded the /media/btrfs/backup/snapshots directory.

Note: even if you think you're clever, and decide to change permissions of the /media/btrfs/backup/snapshots directory itself, remember that the rm -rf command will still delete any accessible subdirectories with write permissions. In other words, DO NOT rely on permissions of the snapshot directory alone to keep your files safe.

And now, I have a directory structure very similar to that described in the btrfs system administration guide...







No comments: