Tuesday, August 30, 2011

FreeBSD 9 newfs block size and fragment size

In FreeBSD 9.0 beta1 2 new defaults for newfs(8) were introduced:

#define DFL_FRAGSIZE    4096
#define DFL_BLKSIZE     32768

Previous values (FreeBSD ≤ 8.2) were 2 times smaller. This means that by default new UFS filesystems will have 2 times less inodes.

This can be an unpleasant surprise if you want to quick install FreeBSD into a virtual machine with a small virtual hdd. For example, a quite modest setup with 4GB virtual hdd may bring you a /usr partition ~ 2.7GB. How many inodes is that?

The rough formula is:

10242s / 4f

where s is a partition size in MB and f is a magic number called fragment size. The new default is 4096 bytes (controlled by -f newfs(8) option).

So, for our example, the /usr partition will contain max 172,800 inodes. [1] Isn't that enough? (And why should I care?)

For a partitions larger than, say 6GB, you'll rarely ever bother with the word inode. But for smaller ones and such as /usr which usually holds full ports tree directory, you can put yourself into a strange situation when after a fresh FreeBSD install your /usr has ~ plenty of a free space but almost no free inodes.

Returning to our 2.7GB partition example, just after the installation and csup'ing of the ports tree, the number of files is:

# find /usr | wc -l

Or 94.4% of max possible files.

To make things worse, a new installer in FreeBSD 9.0 beta1 doesn't allow you to specify the fragment size & block size (b) values at all. The last one is important too, because the condition b/8 ≤ f ≤ b must be satisfied.

[1]After that number you'll get a dismal message from the kernel: /usr: create/symlink failed, no inodes free.


  1. Interesting post!

    For my own curiosity I had to recheck this on a fresh 8.2 machine. /usr is a bit larger there but with /usr/src, /usr/obj and /usr/ports I easily have over 300.000 inodes in use just there.

    From what I understand from Ivan Voras' blog the reason why FreeBSD, and the industry as a whole, is moving toward 4k block sizes is because it's the standard block size for new hard drives and performance is abysmal when pretending it's still 512 bytes. Sounds good enough for me, but some configuration options during installation seem like a pretty good idea...

    I haven't been following freebsd-hackers@ lately but I take it there will be options? People like options :)

  2. As of 9.0 RC3, a virtualbox default install with 6gb drive used up 84% inodes (my smaller 2 drives failed with inode error) Seems that smaller drives maybe should default to smaller block / fragment size. Seems ports should move towards a more file count efficient system too.