There are several things a filesystem can do to increase read performance. One is to actually increase the logical block size, meaning that several physical blocks are grouped together into one large virtual block. When a user wishes to access a file that is contained on a physical block, the entire virtual block is loaded into RAM. This saves a lot of transferring of individual blocks from disk to RAM and then back to disk. If several blocks have already been pre-loaded into RAM, it is quite likely that all the data that user required was transferred to RAM in one transfer.

Let's see if we can summarize the considerations of a file system:

There is a finite number of storage blocks, and every storage block has a numbered entry in a table, which in Unix is called the inode table.

If you run out of inode numbers, you have run out of storage blocks; this means that you can no longer create and store files, regardless of how much disk space is left on your drive.

If you need to store a lot of small files, you should fragment your block size to create more inode numbers.

If you wish to increase read performance, you should create a large virtual block size so more blocks are loaded into RAM per disk transfer.

Now, let's see how this applies to FreeBSD. When you use newfs, you are formatting your slice with FFS, or the Berkeley Fast File System. Let's take a peek at the manpage for newfs to see what the defaults are for this file system:

man 8 newfs

We're interested in some of the switches; let's start with the b switch:

The block size of the file system, in bytes. It must be a power of 2. The default size is 8192 bytes, and the smallest allowable size is 4096 bytes.

Notice that this is the block size for the file system; the physical block size is always 512 bytes. 8192 bytes is actually 16 physical blocks, so this switch deals with the virtual block size or how many blocks are loaded into RAM at once. Remember that this is done to increase read performance and is one of the reasons why FFS is "fast."

Now let's look at the f switch:

-f

frag-size

The fragment size of the file system in bytes. It must be a power of two ranging in value between blocksize/8 and blocksize. The default is 1024 bytes.

FFS uses fragments, but it fragments the virtual block size, not the physical block size. The default fragment size is actually two physical blocks or 1024 bytes. Now the i switch:

-i

number of bytes per inode

Specify the density of inodes in the file system. The default is to create an inode for every (4 * frag-size) bytes of data space. If fewer inodes are desired, a larger number should be used; to create more inodes a smaller number should be given. One inode is required for each distinct file, so this value effectively specifies the average file size on the file system.

By default, there is one inode for every 4048 bytes worth of disk space and every file requires its own inode number. Since an inode represents the storage unit for one file, this default assumes an average file size of 4048 bytes.

There are two other switches worth mentioning at this point, as they affect the read/write performance of the FFS filesystem. The first one is the m switch:

-m

free space %

The percentage of space reserved from normal users; the minimum free space threshold. The default value used is defined by MINFREE from <ufs/ffs/fs.h>, currently 8%. See tunefs(8) for more details on how to set this option.

All filesystems suffer when you start to get low on available storage blocks. Filesystems like to store files from the same directory in contiguous (next to each other) blocks; this gets harder to do as the number of available blocks decreases and the filesystem has to start searching for empty blocks. The designers of FFS noticed that performance drastically decreases when a filesystem gets around 90% full. When a filesystem reaches the default free space threshold (8%), meaning the filesystem is 92% full, it won't let regular users save any more files. Instead the users will receive an error message and will probably start complaining to the administrator to rectify the situation. The superuser will still be able to save files and use up the remaining blocks, but his time would be better spent in coming up with a plan to save the filesystem before it runs out of storage blocks.

The second switch that deals with free space is the o switch:

-o

optimization preference

("space" or "time") The file system can either be instructed to try to minimize the time spent allocating blocks, or to try to minimize the space fragmentation on the disk. If the value of minfree (see above) is less than 8%, the default is to optimize for space; if the value of minfree is greater than or equal to 8%, the default is to optimize for time. See tunefs(8) for more details on how to set this option.

Most filesystems use an algorithm to determine which blocks should be used to store which files. This switch tells the FFS algorithm to optimize itself for speed or "time." However, when the filesystem meets the minfree threshhold, finding free blocks or "space" becomes much more important than speed.

From the default parameters, you can see that the FFS has been optimized for speed, while still creating a fair number of inodes to record where files have been stored. For most installations, the default values will be fine; in later articles, we'll look more in-depth on how to determine if the default values are not sufficient for your system and what to do about it.

At this point, you've probably learned more about filesystems than you care to admit. Let's take a break until next week when we take a look at cylinder groups, superblocks, and what type of information is actually recorded in an inode entry.

Dru Lavigne
is a network and systems administrator, IT instructor, author and international speaker. She has over a decade of experience administering and teaching Netware, Microsoft, Cisco, Checkpoint, SCO, Solaris, Linux, and BSD systems. A prolific author, she pens the popular FreeBSD Basics column for O'Reilly and is author of BSD Hacks and The Best of FreeBSD Basics.