I just got an SSD and wanted to migrate my current Ubuntu installation to take advantage of its performance.

So I booted to an Ubuntu live CD, mounted source (ext4) and target (SSD, btrfs mounted with compress-force=zlib,nodatacow,noatime,rw,ssd) drives and began copying files using rsync:

sudo rsync -av --exclude=/home/ '/media/username/source/' '/media/username/target'

# /home stays on HDD for now

Rsync finished the job without problems. The file count is similar (about 1.2 million files average, number obtained by right click > properties on Nautilus), but the resultant copy is 31GB, way larger than the source which is only 18GB.

Checked sizes by various methods:

  • df
  • Right click > Properties
  • btrfs filesystem df
  • Baobab

All gave similar results, source is way smaller.

I know that btrfs uses some kind of metadata journal and "shadow copies" of files when COW is on. But COW is off and even if it were on, is the first population of data plus noway 12GB out of 31GB could be metadata; right? o.o

Any idea on WTH is going on? or better yet, how to fix it?

  • Does the source have a lot of hard-linked files? You can check with find /media/user/source -type f -links +2 – muru Apr 26 '15 at 3:54
  • One should be careful with some hot-looking devices like ssd and sub-note-books and so on, many of them have hidden flash-cards on its mainboards or inside the ssd-components, who knows, but they are smart and truely smart ... even the manufacturer is annoyed about being double cheated : first by China, and second by those who managed to simply delete some ssd-devices or mainboards with hidden flash-cards or simply "freezed" them ( ;o) ) – dschinn1001 Apr 26 '15 at 4:11
  • @muru Yes. 3 in /bin and 256 in /usr. – eridani Apr 26 '15 at 4:32
  • Ran rsync again but now using '-avlHx' flags (copy hard/symlinks as such + don't cross Fs boundaries). Got the same result. – eridani May 1 '15 at 15:32

By default, btrfs puts files smaller than 4 KiB into metadata blocks (to avoid the extra seeks that would occur if the data were placed far away from the metadata); this is controlled by the max_inline mount option. In addition, btrfs will duplicate metadata by default unless mkfs.btrfs detects that the selected device is non-rotational when creating the filesystem; this is controlled by the --metadata option in mkfs.btrfs. Taken together, this means that the on-disk size of each file less than 4 KiB is at least twice its actual data size.

At 1.2 million files and 18 GB, the average size of your files is 16 KB, and I suspect a lot of these are smaller than 4 KiB. This might explain the significant increase in disk space usage over ext4.

However, this explanation is suspicious because ext4—like most filesystems—is also inefficient in storing files less than 4 KiB since it defaults to a sector size of 4 KiB, which means that every file occupies at least that much space on disk. Btrfs is different here in that it tightly packs the inlined data in its metadata blocks. I expect btrfs to become more space-efficient than ext4 (under current default options) for files smaller than 2 KiB.

Thus, I think my explanation here is wrong unless you have a lot of files that are between 2 KiB and 4 KiB, or you are using non-default options for ext4 or btrfs.

But if this explanation is right, then you can reduce disk space usage in btrfs by not duplicating metadata: simply specify the --metadata single option when invoking mkfs.btrfs (obviously, this reduces redundancy, so the filesystem will be less resilient against metadata corruption). For an existing btrfs filesystem, you can convert duplicated metadata into single metadata using balance filters.

It is possible to disable data inlining using the max_inline=0 mount option, but I don't recommend this because it runs into the space-efficiency problem for small files that ext4 and other filesystems face.

| improve this answer | |

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.