Ext4 was released as a functionally complete and stable filesystem in Linux 2.6.28, and it's getting included in all the modern distros (in some cases as the default fs), so if you are using a modern distro, it's possible that you already have Ext4 support and you don't need to modify your system to run Ext4.
It's safe to use it in production environments, but as any piece of software, it has bugs (which are more likely to be hit in the first stable versions). Any known critical bug will be quickly fixed. If you find one, you can contact the Ext4 developers at the ext4 mailing list. They sometimes also can be found on IRC.
Any existing Ext3 filesystem can be migrated to Ext4 with an easy procedure which consists in running a couple of commands in read-only mode (described in the next section). This means that you can improve the performance, storage limits and features of your current filesystems without reformatting and/or reinstalling your OS and software environment. If you need the advantages of Ext4 on a production system, you can upgrade the filesystem. The procedure is safe and doesn't risk your data (obviously, backup of critical data is recommended, even if you aren't updating your filesystem :). Ext4 will use the new data structures only on new data, the old structures will remain untouched and it will be possible to read/modify them when needed. This means, that, of course, that once you convert your filesystem to Ext4 you won't be able to go back to Ext3 again (although there's a possibility, described in the next section, of mounting a Ext3 filesystem with Ext4 without using the new disk format and you'll be able to mount it with Ext3 again, but you lose many of the advantages of Ext4).
Bigger File System and File Sizes
Currently, Ext3 support 16 TB of maximum file system size and 2 TB of maximum file size. Ext4 adds 48-bit block addressing, so it will have 1 EB1 of maximum file system size and 16 TB of maximum file size. Why 48-bit and not 64-bit? There are some limitations that would need to be fixed before making Ext4 fully 64-bit capable, which have not been addressed in Ext4. The Ext4 data structures have been designed keeping this in mind, so a future update to Ext4 will implement full 64-bit support at some point. 1 EB will be enough (really :)) until that happens.
- An EB or Exabyte is 1018 bytes or 1,048,576 TB.
Sub directory scalability
Right now the maximum possible number of sub directories contained in a single directory in Ext3 is 32000. Ext4 breaks that limit and allows unlimited number of sub directories.
The traditionally Unix-derived file systems like Ext3 use a indirect block mapping scheme to keep track of each block used for the blocks corresponding to the data of a file. This is inefficient for large files, specially on large file delete and truncate operations, because the mapping keeps an entry for every single block, and big files have many blocks -> huge mappings, slow to handle. Modern file systems use a different approach called "extents". An extent is basically a bunch of contiguous physical blocks. It basically says "The data is in the next n blocks". For example, a 100 MB file can be allocated into a single extent of that size, instead of needing to create the indirect mapping for 25600 blocks (4 KB per block). Huge files are split in several extents. Extents improve the performance and also help to reduce the fragmentation, since an extent encourages continuous layouts on the disk.
When Ext3 needs to write new data to the disk, there's a block allocator that decides which free blocks will be used to write the data. But the Ext3 block allocator only allocates one block (4KB) at a time. That means that if the system needs to write the 100 MB data mentioned in the previous point, it will need to call the block allocator 25600 times (and it was just 100 MB!). Not only this is inefficient, it doesn't allow the block allocator to optimize the allocation policy because it doesn't knows how many total data is being allocated, it only knows about a single block. Ext4 uses a "multiblock allocator" (mballoc) which allocates many blocks in a single call, instead of a single block per call, avoiding a lot of overhead. This improves the performance, and it's particularly useful with delayed allocation and extents. This feature doesn't affect the disk format. Also, note that the Ext4 block/inode allocator has other improvements, described in details in this paper.
Delayed allocation is a performance feature (it doesn't change the disk format) found in a few modern filesystems such as XFS, ZFS, btrfs or Reiser 4, and it consists in delaying the allocation of blocks as much as possible, contrary to what traditionally filesystems (such as Ext3, reiser3, etc) do: allocate the blocks as soon as possible. For example, if a process write()s, the filesystem code will allocate immediately the blocks where the data will be placed - even if the data is not being written right now to the disk and it's going to be kept in the cache for some time. This approach has disadvantages. For example when a process is writing continually to a file that grows, successive write()s allocate blocks for the data, but they don't know if the file will keep growing. Delayed allocation, on the other hand, does not allocate the blocks immediately when the process write()s, rather, it delays the allocation of the blocks while the file is kept in cache, until it is really going to be written to the disk. This gives the block allocator the opportunity to optimize the allocation in situations where the old system couldn't. Delayed allocation plays very nicely with the two previous features mentioned, extents and multiblock allocation, because in many workloads when the file is written finally to the disk it will be allocated in extents whose block allocation is done with the mballoc allocator. The performance is much better, and the fragmentation is much improved in some workloads.
Fsck is a very slow operation, especially the first step: checking all the inodes in the file system. In Ext4, at the end of each group's inode table will be stored a list of unused inodes (with a checksum, for safety), so fsck will not check those inodes. The result is that total fsck time improves from 2 to 20 times, depending on the number of used inodes (http://kerneltrap.org/Linux/Improving_fsck_Speeds_in_Ext4). It must be noticed that it's fsck, and not Ext4, who will build the list of unused inodes. This means that you must run fsck to get the list of unused inodes built, and only the next fsck run will be faster (you need to pass a fsck in order to convert a Ext3 filesystem to Ext4 anyway). There's also a feature that takes part in this fsck speed up - "flexible block groups" - that also speeds up file system operations.
The journal is the most used part of the disk, making the blocks that form part of it more prone to hardware failure. And recovering from a corrupted journal can lead to massive corruption. Ext4 checksums the journal data to know if the journal blocks are failing or corrupted. But journal checksumming has a bonus: it allows one to convert the two-phase commit system of Ext3's journaling to a single phase, speeding the filesystem operation up to 20% in some cases - so reliability and performance are improved at the same time. (Note: the part of the feature that improves the performance, the asynchronous logging, is turned off by default for now, and will be enabled in future releases, when its reliability improves)
"No Journaling" mode
Journaling ensures the integrity of the filesystem by keeping a log of the ongoing disk changes. However, it is known to have a small overhead. Some people with special requirements and workloads can run without a journal and its integrity advantages. In Ext4 the journaling feature can be disabled, which provides a small performance improvement.
(This feature is being developed and will be included in future releases). While delayed allocation, extents and multiblock allocation help to reduce the fragmentation, with usage filesystems can still fragment. For example: You write three files in a directory and continually on the disk. Some day you need to update the file of the middle, but the updated file has grown a bit, so there's not enough room for it. You have no option but fragment the excess of data to another place of the disk, which will cause a seek, or allocate the updated file continually in another place, far from the other two files, resulting in seeks if an application needs to read all the files on a directory (say, a file manager doing thumbnails on a directory full of images). Besides, the filesystem can only care about certain types of fragmentation, it can't know, for example, that it must keep all the boot-related files contiguous, because it doesn't know which files are boot-related. To solve this issue, Ext4 will support online defragmentation, and there's a e4defrag tool which can defragment individual files or the whole filesystem.
Larger inodes, nanosecond timestamps, fast extended attributes, inodes reservation...
- Larger inodes: Ext3 supports configurable inode sizes (via the -I mkfs parameter), but the default inode size is 128 bytes. Ext4 will default to 256 bytes. This is needed to accommodate some extra fields (like nanosecond timestamps or inode versioning), and the remaining space of the inode will be used to store extend attributes that are small enough to fit it that space. This will make the access to those attributes much faster, and improves the performance of applications that use extend attributes by a factor of 3-7 times.
- Inode reservation consists in reserving several inodes when a directory is created, expecting that they will be used in the future. This improves the performance, because when new files are created in that directory they'll be able to use the reserved inodes. File creation and deletion is hence more efficient.
- Nanoseconds timestamps means that inode fields like "modified time" will be able to use nanosecond resolution instead of the second resolution of Ext3.
This feature, available in Ext4 in the latest kernel versions, and emulated by glibc in the filesystems that don't support it, allows applications to preallocate disk space: Applications tell the filesystem to preallocate the space, and the filesystem preallocates the necessary blocks and data structures, but there's no data on it until the application really needs to write the data in the future. This is what P2P applications do in their own when they "preallocate" the necessary space for a download that will last hours or days, but implemented much more efficiently by the filesystem and with a generic API. This have several uses: first, to avoid applications (like P2P apps) doing it themselves inefficiently by filling a file with zeros. Second, to improve fragmentation, since the blocks will be allocated at one time, as contiguously as possible. Third, to ensure that applications has always the space they know they will need, which is important for RT-ish applications, since without preallocation the filesystem could get full in the middle of an important operation. The feature is available via the libc posix_fallocate() interface.
Barriers on by default
This is an option that improves the integrity of the filesystem at the cost of some performance (you can disable it with "mount -o barrier=0", recommended trying it if you're benchmarking). From this LWN article: "The filesystem code must, before writing the [journaling] commit record, be absolutely sure that all of the transaction's information has made it to the journal. Just doing the writes in the proper order is insufficient; contemporary drives maintain large internal caches and will reorder operations for better performance. So the filesystem must explicitly instruct the disk to get all of the journal data onto the media before writing the commit record; if the commit record gets written first, the journal may be corrupted. The kernel's block I/O subsystem makes this capability available through the use of barriers; in essence, a barrier forbids the writing of any blocks after the barrier until all blocks written before the barrier are committed to the media. By using barriers, filesystems can make sure that their on-disk structures remain consistent at all times."
Getting Ext4 code
For people who build their own kernel
1. Start with a 2.6.29 or later kernel. It is highly recommended that you apply the latest patchset (if available) to get the latest bug fixes. In your kernel's .config file, enable EXT4_FS (along with EXT4_FS_XATTR and EXT4_FS_POSIX_ACL if you like).
2. Compile the latest version of e2fsprogs (as of this writing 1.41.5) from kernel.org or from Sourceforge. Note that it is highly important to install the mke2fs.conf file that comes with the e2fsprogs 1.41.x sources in /etc/mke2fs.conf. If you have edited the /etc/mke2fs.conf file, you will need to merge your changes with the version from e2fsprogs 1.41.x.
For people who are running Fedora
Recent Fedora is generally very up to date with respect to ext4 code in kernelspace and userspace.
Fedora 11 uses the ext4 filesystem as the default root filesystem, and as such should generally contain the most uptodate code, features, and fixes. It will initially be based on the 2.6.29.x kernel series.
Fedora 10 currently has a kernel based on 2.6.27 that has working ext4 support. It is missing some of the latest fixes and performance optimizations. A 2.6.29 kernel update should be available soon, with more up-to-date ext4 code.
Fedora 10 and later has all of the basic infrastructure needed to be able to run ext4, including updated udev, blkid, and other bits needed for ext4 to be a transparently recognized filesystem.
Fedora 9 has only rudimentary ext4 support, and no significant ext4 updates are planned in that release.
Fedora 11 and below have NO support in grub for booting from ext4, so /boot must be ext3 or some other supported filesystem. The anaconda installer enforces this restriction. This restriction has been removed in Fedora 12.
For people who are running RHEL
ext4 is currently included as a Technology Preview in RHEL 5.3. To use it, update to 5.3 or later, boot into 2.6.18-128.el5 or higher, and yum install e4fsprogs.
The e4fsprogs package is designed to install alongside stock e2fsprogs without overlapping, so some utilities are renamed; for example e4fsck, debuge4fs, e4image, etc. rpm -q e4fsprogs | grep bin will give a good summary of what is included.
The ext4 code in RHEL5.3 does not support delayed allocation, as it is a backport of an older ext4 snapshot (2.7.27). The RHEL5.4 kernel is expected to have an update, based on the 2.6.29 ext4 codebase with several post-2.6.29 fixes.
For people who are running openSuSE
- Run tune2fs -O extents,uninit_bg /dev/ROOT
- Change ext3 to ext4 in /etc/fstab
- Add "ext4" to INITRD_MODULES in /etc/sysconfig/kernel
- Run sudo mkinitrd (takes about 2 min here, dunno why)
- Run e2fsck on the ROOT fs. As this is currently mounted, you might want to change into single user mode (init 1) and remount read-only (mount -o remount,ro /) or just reboot and the bootprocess will complain a bit and run e2fsck anyway - don't know if this is The Right Thing To Do though.
For people who are running Ubuntu
Ubuntu 9.04 and later include ext4 as a manual partitioning option at installation time, including support for ext4 as the root filesystem.
Between lib-util version 2.12r-19ubuntu1 and 2_16, Ubuntu apparently chose to use the libvolume-id library instead of the more capable libblkid1 library. Their motivation for that is mentioned in the relevant changelog.
- 8.04 Hardy - 2.13.1
- 8.10 Intrepid - 2.14.1
- 9.04 Jaunty - 2.14.1
As of util-linux_2.16 (16 July 2009) Ubuntu has reverted back to using libblkid1, as can be seen in the changelog. Versions used:
9.10 Karmic Koala - 2.16.1
For those who are running Ubuntu and the libvolume-id-based lib-util, it is highly recommended that to download and install a set of modified util-linux packages. Packages for Ubuntu Hardy are available here. These packages revert the change made by Ubuntu to use the libvolume-id library instead of the blkid library. The libvolume-id library has a number of shortcomings, including that it doesn't work on freshly created filesystems or swap devices until after you reboot (since it is tied to udev probing) and it doesn't understand ext4dev filesystems. For other versions of Ubuntu, a patch can be found here.
For people who are running Debian
In Debian Lenny (Stable), the following current packages provide ext4 support:
- ext4dev module in the linux-image package (2.6.26-19lenny2)
- e2fsprogs (1.41.3-1)
It should be noted that the stock 2.6.26 ext4 has problems with delayed allocation and with filesystems with non-extent based files. So until Debian starts shipping a 2.6.27 based kernel or a 2.6.26 kernel with at least the 2.6.26-ext4-7 patchset, you should mount ext4dev filesystems using -o nodelalloc and only use freshly created filesystems using "mke2fs -t ext4dev". (Without these fixes, if you try to use an ext3 filesystem which was converted using "tune2fs -E test_fs -o extents /dev/DEV", you will probably hit a kernel BUG the moment you try to delete or truncate an old non-extent based file.)
Debian Squeeze (Testing) has kernel 2.6.30
For people who are running Ark Linux
Ark Linux dockyard-devel has ext4 support, including ext4 support during installation. grub is also patched to boot from ext4 /boot partitions. To install an Ark Linux system with ext4 as main filesystem, get the dockyard-devel image (or, once released, any 2009.x release), and type "fs=ext4" at the CD boot prompt to override the default setting. Depending the outcome of (pending) performance tests, fs=ext4 may be made the default for 2009.1.
If you're on the stable branch, install the kernel, kernel-filesystem-ext4 and e2fsprogs packages from dockyard-devel.
Creating ext4 filesystems
Creating a new ext4 filesystem is very easy once you have upgraded to e2fsprogs 1.41 or later. Simply type:
# mke2fs -t ext4 /dev/DEV
# mkfs.ext4 /dev/DEV
Once the filesystem is created, it can be mounted as follows:
# mount -t ext4 /dev/DEV /wherever
If you have a sufficiently new system, the "-t ext4" should not be needed.
NOTE: Although very large fileystems are on ext4's feature list, current e2fsprogs currently still limits the filesystem size to 2^32 blocks (16T for a 4k block filesystem). Filesystems larger than 16T is one of the very next high-priority features to complete for ext4.
Booting from an ext4 filesystem
Ext4 support has been added in the 1.97 version of GRUB2
There's also a Google Summer of Code project (from opensuse) which seem to have developed ext4 support for grub legacy ( 0.97). Both projects -GRUB2 and the GSoC projects- seem (sadly) to be different efforts.
The grub package in Ubuntu 9.04 and later includes a patch to support booting from ext4 filesystems (see bug 314350).
Converting an ext3 filesystem to ext4
It is possible to mount both ext3 (and ext2, in kernels 2.6.28 and later) filesystems directly using the ext4 filesystem driver. This will allow you to use many of the in-core performance enhancements such as delayed allocation (delalloc) and multi-block allocation (mballoc), and large inodes if your ext3 filesystem have been formatted with large inodes as is the default with newer versions of e2fsprogs. Simply mounting an ext3 (or ext2) filesystem with a modern (2.6.27+) version of ext4 will not change the on-disk structures, and it is possible to revert to the ext3 (or ext2) driver should there be any problem with ext4. If you plan to use the ext4 driver to boot from an ext2/3 partition, and you compile your kernel without the ext2/3 drivers, you may need to add rootfstype=ext4 to the kernel command line.
In addition to the in-core performance enhancements, there are additional features which modify the on-disk format from what ext3 understands, such as extents, which can significantly improve the ext4 filesystem performance, but mean the filesystem cannot be mounted by kernels that do not support ext4. There are additional ext4 features, such as flex_bg and > 16TB filesystem support that can only be enabled at format time via mke2fs.
To change an ext2 filesystem (should you still have one) to ext3 (enabling the journal feature), use the command:
# tune2fs -j /dev/DEV
To enable the ext4 features on an existing ext3 filesystem, use the command:
# tune2fs -O extents,uninit_bg,dir_index /dev/DEV
WARNING: Once you run this command, the filesystem will no longer be mountable using the ext3 filesystem!
After running this command (specifically, after setting the uninit_bg parameter), you MUST run fsck to fix up some on-disk structures that tune2fs has modified:
# e2fsck -fDC0 /dev/DEV
- Running fsck will complain about "One or more block group descriptor checksums are invalid" - this is expected and one of the reasons why tune2fs requests to fsck.
- by enabling the extents feature new files will be created in extents format, but this will not convert existing files to use extents. Non-extent files can be transparently read and written by Ext4.
- If you convert your root filesystem ("/") to ext4, and you use the GRUB boot loader, you will need to install a version of GRUB which understands ext4. Your system may boot OK the first time, but when your kernel is upgraded, it will become unbootable.
- If you do the conversion for the root fs on a live system you'll have to reboot for fsck to run safely. You might also need to add rootfstype=ext4 to the kernel's command line so the partition is not mounted as ext3.
- WARNING: It is NOT recommended to resize the inodes using resize2fs with e2fsprogs 1.41.0 or later, as this is known to corrupt some filesystems.
- If you omit "uninit_bg" on the tunefs command, you can skip the fsck step.
Portions of this article have been taken from the Ext4 article from the Kernel Newbies website. The Kernel Newbies article was written by Michael Blizek and was released under Creative Commons Attribution-2.5-Generic license.