Server Fault is a question and answer site for system and network administrators. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

While diffing mounted snapshots would work, it sounds like it could be horribly slow in many cases.

Is there btrfs specific functionality for diffing snapshots? (I was unable to find any in the docs)

share|improve this question
While it might be possible to find out which blocks were changed and how, you need to consider the case when a change has been reversed later, if you really want to compare filesystems (directories). For example if you have file A containing a, write b in its snapshot and later change it back to a, the file didn't really change at all. – Cristian Ciupitu Jun 18 '12 at 19:33
It seems like it would be completely analogous to source code revision control where this sort of thing is done all the time, unless I'm missing something. – Catskul Jun 18 '12 at 19:54
up vote 9 down vote accepted

It sounds like you're looking for btrfs send/receive, which will appear in Linux 3.6. The send command creates a log file of the differences between two snapshots, and the receive command applies the changes from a file. Note that send/receive uses a custom file format, so the file won't look exactly like, say, diff or tar.

share|improve this answer
Nice! That's exactly what I was looking for. – Catskul Aug 21 '12 at 18:51

I'm running Debian stable which does not have btrfs send, so I looked to a solution using btrfs subvolume find-new.

If you have snapshot1 and snapshot2 and you want to know what changed in the later one, snapshot 2, since snapshot1 was made you can use the script below which provides

btrfs-diff oldsnapshot/ newsnapshot/

which will list all files changed in newsnapshot/ since oldsnapshot/.

usage() { echo $@ >2; echo "Usage: $0 <older-snapshot> <newer-snapshot>" >2; exit 1; }

[ $# -eq 2 ] || usage "Incorrect invocation";

[ -d $SNAPSHOT_OLD ] || usage "$SNAPSHOT_OLD does not exist";
[ -d $SNAPSHOT_NEW ] || usage "$SNAPSHOT_NEW does not exist";

OLD_TRANSID=`btrfs subvolume find-new "$SNAPSHOT_OLD" 9999999`
OLD_TRANSID=${OLD_TRANSID#transid marker was }
[ -n "$OLD_TRANSID" -a "$OLD_TRANSID" -gt 0 ] || usage "Failed to find generation for $SNAPSHOT_NEW"

btrfs subvolume find-new "$SNAPSHOT_NEW" $OLD_TRANSID | sed '$d' | cut -f17- -d' ' | sort | uniq

To explain: btrfs subvolume find-new finds files changed after a particular 'generation' of snapshot. It also reports the current generation number.


e.g. take the daily snapshot of a subvolume case:

mkdir test && cd test
btrfs subvolume create live
date >live/foo1
date >live/bar1
btrfs subvolume snapshot live/ snap1
date >live/foo2  # new file
date >>live/bar1 # modify file
rm live/foo1     # delete file
btrfs subvolume snapshot live/ snap2
date >live/foo3  # new file
mv live/bar{1,2} # rename file
rm live/foo2     # delete file

What changed between snap1 and snap2?

$ btrfs-diff snap1/ snap2/

So we can see the new file, see the modified file, but the deletion is not reported. This is because the command reports on files that exist, not ones that now don't.

What changed between snap2 and the live subvolume?

$ btrfs-diff snap2/ live/

the renamed file is not reported. Its data has not changed.

Now what if we add data to the renamed file

date >>live/bar2
btrfs-diff snap2/ live/

OK, makes sense. But let's make a new file

date >live/lala
btrfs-diff snap2/ live/

eh! where's lala?. If you add another file, lala appears. So this behaviour is a bit odd. Which is probably why the wiki says:

The find-new approach has some serious limitations and thus is not really usable for something like send/receive.

However, the oddness comes when you compare a live subvolume against a previous state, not when you're comparing (read-only) snapshots. So this could still be useful unless you want to also identify deleted files.

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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