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.

Clinton
  • 729

4 Answers4

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.

Tyson
  • 143
Andrew
  • 251
  • 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
  • 2
    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
  • 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 Nov 22 '17 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 May 17 '22 at 06:53
  • @eesiraed cannot confirm that. For me on Alpine Linux it attempted to make a full copy and when I added "--no-copy" it failed because of being cross device too. (tried using GNU coreutils mv) – K. Frank Feb 27 '24 at 05:20
  • Also it's not a great idea to delete the original directory on the original volume after creating the snapshot. That somehow caused a lot of IO regardless of the snapshot. I tried to cancel the rm operation but it doesn't respond to CTRL+C anymore. So lets hope I didn't just trash 200 GB of data... – K. Frank Feb 27 '24 at 05:32
  • No data loss, but it appears to update a ton of blocks on disk though. about 15 minutes later and it is still at 100% disk utilization... I assume it is rewriting everything right now for some reason. Tl;Dr: DO NOT DELETE the original directory... (maybe unlink would have worked better than a "rm -rf" on the original data?) – K. Frank Feb 27 '24 at 05:48
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.
plugwash
  • 4,352
  • 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 Feb 27 '24 at 05:53
3
  1. Yes.
  2. No.

At least not at the moment.


  • 5
    This answer is incomplete. Please expand. – nopcorn Mar 07 '13 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. – Adam Ryczkowski Mar 08 '13 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 Dec 31 '23 at 00:50
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

billkw
  • 123