Is there a standard approach, when using snapper on btrfs, to exclude directories under users' home folders? Say... ~/.cache/yay on Arch. Or possibly even ~/.cache as a whole.

Of course, I know the SOP is to create a subvolume any time you want a folder's contents excluded from a snapshot of a subvolume higher in the mounted folder hierarchy. But that means making a subvolume for each excluded folder under ~/ each time a user is added. Which is, in addition to getting messy to maintain, quite a few extra steps on top of normal user creation.

I suppose I could create wrapper scripts for useradd and userdel and toss them in /usr/local/sbin so they take priority. But I thought I'd see if there isn't a more elegant approach.


It's not critical. The only system I currently have snapper deployed on is a home gateway and it's unlikely to ever have more than one non-root user. But it would be nice to know for the future.

subvolumes (excluding existing snapshots):

$ sudo btrfs subvolume list /
ID 258 gen 33625 top level 5 path home
ID 262 gen 33553 top level 5 path opt
ID 264 gen 33555 top level 5 path var-www
ID 266 gen 33630 top level 5 path arch
ID 267 gen 33631 top level 5 path var-log
ID 268 gen 33566 top level 5 path pacman-cache
ID 270 gen 45 top level 266 path var/lib/portables
ID 271 gen 46 top level 266 path var/lib/machines
ID 274 gen 33566 top level 266 path .snapshots
ID 276 gen 33556 top level 258 path home/.snapshots
ID 278 gen 33556 top level 262 path opt/.snapshots
ID 279 gen 33556 top level 264 path var-www/.snapshots


# /dev/sda6 LABEL=system
UUID=18f47506-31c6-4d22-939d-684ace61301f / btrfs rw,noatime,compress=zstd:3,ssd,space_cache,subvolid=266,subvol=/arch,subvol=arch 0 0

# /dev/sda6 LABEL=system
UUID=18f47506-31c6-4d22-939d-684ace61301f /.snapshots btrfs rw,nodev,noexec,noatime,compress=zstd:3,ssd,space_cache,subvolid=274,subvol=/arch/.snapshots,subvol=arch/.snapshots 0 0

# /dev/sda1
UUID=27d5943f-e74d-480f-be46-a370c5b1f37f /boot ext4 rw,noatime,nodev,nosuid,noexec 0 2

# /dev/sda6 LABEL=system
UUID=18f47506-31c6-4d22-939d-684ace61301f /home btrfs rw,noatime,nodev,compress=zstd:3,ssd,space_cache,subvolid=258,subvol=/home,subvol=home 0 0

# /dev/sda6 LABEL=system
UUID=18f47506-31c6-4d22-939d-684ace61301f /home/.snapshots btrfs rw,nodev,noexec,noatime,compress=zstd:3,ssd,space_cache,subvolid=276,subvol=/home/.snapshots,subvol=home/.snapshots 0 0

# /dev/sda6 LABEL=system
UUID=18f47506-31c6-4d22-939d-684ace61301f /opt btrfs rw,noatime,nodev,nosuid,compress=zstd:3,ssd,space_cache,subvolid=262,subvol=/opt,subvol=opt 0 0

# /dev/sda6 LABEL=system
UUID=18f47506-31c6-4d22-939d-684ace61301f /opt/.snapshots btrfs rw,nodev,noexec,noatime,compress=zstd:3,ssd,space_cache,subvolid=278,subvol=/opt/.snapshots,subvol=opt/.snapshots 0 0

# /dev/sda6 LABEL=system
UUID=18f47506-31c6-4d22-939d-684ace61301f /var/log btrfs rw,noatime,nodev,nosuid,noexec,compress=zstd:3,ssd,space_cache,subvolid=267,subvol=/var-log,subvol=var-log 0 0

# /dev/sda6 LABEL=system
UUID=18f47506-31c6-4d22-939d-684ace61301f /var/www btrfs rw,noatime,nodev,nosuid,noexec,compress=zstd:3,ssd,space_cache,subvolid=264,subvol=/var-www,subvol=var-www 0 0

# /dev/sda6 LABEL=system
UUID=18f47506-31c6-4d22-939d-684ace61301f /var/www/.snapshots btrfs rw,nodev,noexec,noatime,compress=zstd:3,ssd,space_cache,subvolid=279,subvol=/var-www/.snapshots,subvol=var-www/.snapshots 0 0

# /dev/sda6 LABEL=system
UUID=18f47506-31c6-4d22-939d-684ace61301f /var/cache/pacman/pkg btrfs rw,noatime,nodev,nosuid,noexec,compress=zstd:3,ssd,space_cache,subvolid=268,subvol=/pacman-cache,subvol=pacman-cache 0 0

# /dev/sda5
UUID=5415bf33-0a89-4a36-a224-27dbb4c43977 none swap defaults 0 0
  • when a subvolume is mounted, nested subvolumes are mounted as well, automatically, no need to be in fstab – André Werlang Mar 29 '20 at 19:55
  • @Andre While true, my understanding is that such would create problems when rolling back a snapper snapshot. The solution for which is to explicitly mount subvolumes where they belong. – Cliff Armstrong Mar 30 '20 at 13:52

The granularity of snapper (with BTRFS) is the BTRFS snapshot. Given the boundary of snapshots is the BTRFS subvolume, no you cannot configure snapper to exclude directories/folders. snapper simply doesn't have any control over this.

On my system I do exactly as you mentioned; Create subvolumes for the directories I don't want to snapshot.

To set up this approach during the creation of user accounts, you can create a skelleton (skell) directory which contains a shell script which upon user login creates the necessary subvolumes, if they don't already exist; With BTRFS, non-root users can create subvolumes (but cannot delete them).

Said skelleton directory will be copied to the user's home directory when using useradd. Then, when the user first logs in the subvolumes for, say .cache, would be created. No need for wrapper scripts. See man useradd.

  • Ah, I didn't realize subvolumes could be created by non-root users. That does simplify things. TY! – Cliff Armstrong Aug 20 '19 at 19:50

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.