This article introduces the reader to the JFS file system. In particular, procedures for implementation, maintenance and optimization will be presented along with background information on the file system itself and some cautionary notes on precarious implementations.
- 1 Background
- 2 Implementing on Linux
- 3 Optimizations
- 4 fsck and recovery
- 5 Cautionary Notes
- 6 Benchmarks
- 7 Conclusions
- 8 References
The Journaled File System (JFS) is a journaling file system that was open-sourced by IBM in 1999 and was available in the linux kernel as of 2002. JFS was original created to run on IBM's AIX line of Unix servers; subsequently it was ported for use on IBM's OS/2 operating system. The current Linux port of JFS is based off the OS/2 port.
NOTE: While there are potential issues, JFS file systems created on either OS/2 or Linux are inter-operable.
While it is difficult to make general comparisons between JFS and other file systems available on UNIX, it is claimed that JFS uses less CPU than other Linux file systems . With certain optimizations, JFS has also been claimed to be faster for certain file operations, as compared to other Linux file systems (see below).
Linux Development Team
The development of the Linux JFS port is headed by the JFS core team (all currently at IBM):
- Dave Kleikamp (shaggy at austin dot ibm dot com)
- Dave Blaschke (blaschke at us dot ibm dot com)
- Steve Best (sbest at us dot ibm dot com)
- Barry Arndt (barndt at us dot ibm dot com)
JFS is a modern file system supporting many features, a few of which are listed here.
- fully 64-bit
- dynamic space allocation for i-nodes, i.e. no running out of i-nodes on file systems with large number of small files
- Directory structures designed for speed and efficiency:
- - directories with eight or fewer entries have their contents storied inline within that directory's i-node.
- - directories with more than eight entries have their contents stored in a B+ tree keyed on name.
- JFS utilizes extents for allocating blocks for large files.
- support for extended attributes in additions to standard Unix-style permissions.
- support for both internal and external logs (see below)
A more comprehensive (and technical) overview of the features in JFS can be found in the JFS Overview authored by developer Steve Best.
Implementing on Linux
Implementing a JFS file system is just like implementing most other file systems under Linux. JFS was merged into the Linux kernel as of version 2.4  and has its driver built as a module in the standard Arch kernel packages. If building a custom kernel on a machine that will be (or does) use JFS file systems, be sure to enable JFS in your kernel config:
File systems ---> [*/M] JFS filesystem support
If extended attributes are desired, one will also need to enable "JFS POSIX Access Control Lists" and/or "JFS Security Labels"
File systems ---> [*/M] JFS filesystem support ---> [*] JFS POSIX Access Control Lists ---> [*] JFS Security Labels
Next, the JFS utilities package will be needed to perform all file system related tasks:
pacman -S jfsutils
Actual creation of a JFS file system can be done with the either
Both commands are equivalent.
NOTE: No specific considerations need to be made for using JFS as a root file system, but it is NOT advisable to use JFS as the file system on a boot partition (see below).
There are several concepts that can be implemented with a JFS filesystem to boost its performance:
- periodic deframentation the file system
- using the deadline I/O schedulere
- utilizing an external journal
- attaching the noatime attribute the the file system in /etc/fstab
JFS file systems will degrade in performance over time due to file fragmentation . While there is in-place defragmentation code in the JFS utilities, this is code held over from the OS/2 port and has yet to be implemented . For file systems that can be taken off-line for a time, one can execute a script like the following to defragment their JFS file system
NOTE: This script is dangerous and may result in the wiping of an entire hard disk, if arguments get switched! Doing this type of operation is only recommended for people who have confidence in doing backups and file system operations
umount /dev/hdc1 dd bs=4k if=/dev/hdc1 of=/dev/hdj1 jfs_fsck /dev/hdj1 mount -o ro /dev/hdj1 /fs/hdj1 jfs_mkfs /dev/hdc1 mount -o rw /dev/hdc1 /fs/hdc1 (cd /fs/hdj1 && tar -cS -b8 --one -f - .) | (cd /fs/hdc1 && tar -xS -b8 -p -f -) umount /dev/hdj1
In this example, /dev/hdc1 is the device with the data that needs backing up and /dev/hdj1 is the device that holds the backup.
Basically, this script copies the data off the JFS file system to a backup drive, formats the original JFS file system and finally writes back the data from the backup to the freshly formatted drive in a way that JFS will write its allocation trees in a defragmentated way.
NOTE: If a VMWare session is sitting on an underlying JFS partition that is highly fragmented, performance of the virtual machine may be significantly degraded.
Deadline I/O Scheduler
JFS seems to preform better when the kernel has been configured to use the Deadline I/O Scheduler. Indeed, JFS's performance seems to exceed that of other Linux file systems with this particular scheduler being employed . To utilize this schedules, the kernel must be recompiled with the Deadline I/O scheduler set to the default:
Block layer ---> I/O Schedulers ---> [*] Deadline I/O scheduler ---> Default I/O scheduler (Deadline) --->
NOTE: As this is a relatively new feature to the Linux port of JFS, it is recommended to upgrade to the very latest version of jfsutils before attempting to implement an external journal (earlier versions seem to give errors when trying to create the journal device).
As with any journaled file system, a journal is constantly accessed in accordance with disk activity. Having the journal log on the same device as the its corresponding file system thus can cause a degradation in I/O through put. This degradation can be alleviated by putting the journal log on a separate device all together.
To make a journal device, first create a partition that is 128MB. Using a partition that is bigger than 128MB results in the excess being ignored, according to mkfs.jfs. You can either create an external log for an already-existing JFS file system by executing the following:
mkfs.jfs -J journal_dev /dev/external_journal #creates a journal on device /dev/external_journal mkfs.jfs -J device=/dev/external_journal /dev/jfs_device #attaches the external journal to the existing file system on /dev/jfs_device
or a command can be issued to create both a new external journal and its corresponding JFS fil esystem:
mkfs.jfs -j /dev/external_journal /dev/jfs_device
This last command formats BOTH the external journal and the JFS file system.
noatime fstab attribute
Every time a file is accessed (read or write) the default for most file systems is to append the metadata associated with that file with an updated access time. Thus, even read operations incur an overhead associated with a write to the file system. This can lead to a significant degradation in performance in some usage scenarios. Appending noatime to the fstab line for a JFS file system stops this action from happening. As access time is of little importance in most scenarios, this alteration has been widely touted as a fast and easy way to get a performance boost out of one's hardware. Indeed, this 'noatime' tag can be used for performance benefit on other file systems besides JFS.
Here is an example /etc/fstab entry with the noatime tag
/dev/sdb1 /media/backup jfs rw,users,noauto,noatime 0 0
NOTE: Access time is NOT the same as the last-modified time. Disabling access time will still enable you to see when files were last modified by a write operation.
Variable block sizes
While the OS/2 port of JFS supports block sizes of 512, 1024, 2048, and 4096 bytes, the Linux port of JFS is only able to use 4k blocks. Even though code exists in JFS utilities that correspond to file systems using variable size blocks, this has yet to be implemented . As larger block sizes tend to favor performance (smaller ones favor efficient space usage), implementing smaller block sizes for JFS in Linux has been given a low priority.
fsck and recovery
In the even that the file system does not get properly unmounted before being powered down, one will usually have to run fsck on a JFS file system in order to be able to mount it again. This procedure usually only takes a few seconds, unless the log somehow gets damaged. If running fsck returns with an unrecognized file system error, try running fsck.jfs on the target device. Normally, fsck is all that is needed.
In the event that the superblock on your file system gets destroyed, it may be possible to recovery some parts of the file system. Currently, the only tool able to do this is a utility called 'jfsrec'. Unfortunately, no packages exist as of yet that provide this utility, so it needs to be downloaded and installed manually. Running jfsrec on the partition with the damaged file system will yield a bunch of directories corresponding to the inodes in the JFS file system. For more information see the jfsrec Sourceforge page.
While JFS is very stable in its current stage of development, there are some cautionary notes on using this file system.
JFS on Boot partitions
Using JFS on a boot partition with the Grub boot loader can work, but can lead to problems. In particular, using JFS on a boot partition has a habit of corrupting the master boot recorder on a Grub update. This happens quite frequently and requires a full repartitioning+formating of the drive with the boot partition in order to remedy.
A personal recommendation is to create a boot partition of 50-100MB with an ext2 file system (which works perfectly with grub and is extremely fast) and format the root partition with JFS. As the boot partition is rarely written to, it makes little sense to put a journaled file system on this.
It is unclear whether or not the same issue is present with using LILO and a JFS boot partition.
As benchmarks measuring file system performance tend to be focused at specific types of disk usage, it is difficult to decipher good general comparisons rating how well JFS performs against other files systems. As mentioned before, it has been noted that JFS has a tendency to use less CPU than other Linux file systems and (with the right optimizations) is faster than other Linux file systems for certain types of file operations. In the references are some links to benchmarks; but as always, it best to test and see what works best for your own system and work load.
JFS is a stable, feature-rich file system that hasn't been publicized as much as some of the other Linux file systems. With optimizations JFS is stable, CPU efficient and fast. In particular, VMWare sessions stand to benefit enormously from a properly optimized and defragmented, underlying JFS file system.