8

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.

4 Answers 4

16

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 subvolume snapshot <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.

8
  • 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
    Commented May 27, 2016 at 17:35
  • 2
    Actually, your method is the proper one so as to avoid making new extents.
    – Geremia
    Commented May 27, 2016 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
    Commented May 27, 2016 at 18:26
  • 4
    @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
    Commented Nov 22, 2017 at 22:36
  • 1
    @plugwash I just created a new subvolume and moved over 130 GB of files into it. It was pretty much instant, so I guess things have changed.
    – eesiraed
    Commented May 17, 2022 at 6:53
3
  1. Yes.
  2. No.

At least not at the moment.


3
  • 5
    This answer is incomplete. Please expand.
    – nopcorn
    Commented Mar 7, 2013 at 18:22
  • 3
    @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. Commented Mar 8, 2013 at 11:06
  • @AdamRyczkowski, An example of converting a directory into its own subvolume and then sending that subvolume to another device. I have a directory with VERY large files with only a small difference between them. I need to move them to another device, but also need to keep the CoW sharing intact. Each file is a 1TB, but only have about 1GB difference between them. The source and destination is 2TB so I can't just copy and dedup later.
    – Brandon
    Commented Dec 31, 2023 at 0:50
3

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
  • did executing the "rm -rf xxxx" at the very end also cause a ton of disk IO back then? Or is this a new bug?
    – K. Frank
    Commented Feb 27 at 5:53
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

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .