2

Just a few questions about Btrfs:

  1. Do I have to mount a Btrfs filesystem before creating subvolumes on it?
  2. Can I easily convert an existing directory into a subvolume? (i.e. if I want to make "/home" a separate subvolume can I just go mk_btrfs_subfolder /home (or whatever the command is), instead of having to make a new empty subvolume and copying everything over?

The commands to do the above would be good but not necessary, just yes/no will be fine and I can Google how.

1
  1. Yes.
  2. No.

At least not at the moment.


  • 2
    This answer is incomplete. Please expand. – n0pe Mar 7 '13 at 18:22
  • 1
    @MaxMackie I'd love to expand, but please state the question first. Do you want reference? Do you want working example of how to mount btrfs volume? Or even better: if you have more questions, post them as separate post. – Adam Ryczkowski Mar 8 '13 at 11:06
4

Yes you have to mount it, and if you want to convert a directory into a subvolume what you can do is create a snapshot using

btrfs su sn <name of subvolume containing folder> @new_subvol

Then you could go into the subvolume and delete everything other than @new_subvol/home for instance and move everything in home to the root of the new subvolume with something like

mv @new_subvol/home/* @new_subvol

Then you could delete the original directory and move the newly created snapshot into its place.

  • The asker wants to do it "instead of having to make a new empty subvolume and copying everything over," which it seems your answer is suggesting, no? – Geremia May 27 '16 at 17:35
  • 1
    Actually, your method is the proper one so as to avoid making new extents. – Geremia May 27 '16 at 18:03
  • 1
    Also, couldn't you just rename home to something like home_old and then move everything from that to @new_subvol? – Geremia May 27 '16 at 18:26
  • @Germia The problem with doing that is that it will be seen as a "cross device move", so the move will turn into a copy and delete whereas with andrews method the only move is completely inside the snapshot, so it remains a true move. – plugwash Nov 22 '17 at 22:36
1

Can I easily convert an existing directory into a subvolume? (i.e. if I want to make "/home" a separate subvolume can I just go mk_btrfs_subfolder /home (or whatever the command is), instead of having to make a new empty subvolume and copying everything over?

For large subvolumes the least bad way of doing this is by creating the subvolume as a snapshot and then cleaning things up. This avoids actually copying any file data though it does mean a bunch of meta data updates that would be unnecessary if this was supported natively.

Andrew mentions this in his answer but doesn't give a complete worked example so here is one. I take a slightly different approach from him moving the old directories out of the way first so I can create the subvolumes in their final locations.

cd /build/
mkdir xxxx
mv *-rpi-staging xxxx
btrfs subvolume snapshot /build /build/wheezy-armhf-rpi-staging
btrfs subvolume snapshot /build /build/jessie-armhf-rpi-staging
btrfs subvolume snapshot /build /build/stretch-armhf-rpi-staging
btrfs subvolume snapshot /build /build/buster-armhf-rpi-staging
cd /build/wheezy-armhf-rpi-staging/
find -maxdepth 1 ! -name xxxx ! -name . -exec rm -rf {} +
(shopt -s dotglob; mv -- xxxx/wheezy-armhf-rpi-staging/* . )
rm -rf xxxx
cd /build/jessie-armhf-rpi-staging/
find -maxdepth 1 ! -name xxxx ! -name . -exec rm -rf {} +
(shopt -s dotglob; mv -- xxxx/jessie-armhf-rpi-staging/* . )
rm -rf xxxx
cd /build/stretch-armhf-rpi-staging/
find -maxdepth 1 ! -name xxxx ! -name . -exec rm -rf {} +
(shopt -s dotglob; mv -- xxxx/stretch-armhf-rpi-staging/* . )
rm -rf xxxx
cd /build/buster-armhf-rpi-staging/
find -maxdepth 1 ! -name xxxx ! -name . -exec rm -rf {} +
(shopt -s dotglob; mv -- xxxx/buster-armhf-rpi-staging/* . )
rm -rf xxxx

Notes on this worked example.

  1. /build is a btrfs filesystem.
  2. wheezy-armhf-rpi-staging jessie-armhf-rpi-staging stretch-armhf-rpi-staging and buster-armhf-rpi-staging are the directories to convert.
  3. this worked example is a cleaned-up version of what I actually did, if there are any errors in it please point them out.
  4. no file/directory called xxxx should exist either directly under the directories you want to convert or directly under the top-level directory in which the conversion is taking place.
  5. I would recommend that if you are going to do this on a system with important data you create an extra snapshot first so you can recover if you screw things up.
  6. The shell used is assumed to be bash.
1

Can I easily convert an existing directory into a subvolume? (i.e. if I want to make "/home" a separate subvolume can I just go mk_btrfs_subfolder /home (or whatever the command is), instead of having to make a new empty subvolume and copying everything over?

I had a specific version of this problem: I have a couple of top-level btrfs subvolumes on my file system that are snapshotted by a utility called snapper on a particular schedule. Unfortunately this can create quite a lot of bloat when it comes to oft-changing directories, of which I had many that I wanted to exclude.

At initial setup, excluding particular paths from snapshots is easy: just make a new btrfs subvolume at the path in question. Unfortunately, it's a bit more complicated once you have a running system.

I thought this wouldn't be too hard to script, and so I started a little bash script. And of course that little script quickly grew to almost 100 lines, as I started to handle different kinds of input, file locks, permissions, etc.

If you have a similar problem (snapper-managed btrfs filesystem that you'd like to prune), I invite you to use (at your own risk): https://github.com/billwanjohi/snapper-exclude/blob/master/snapper-exclude.sh

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.