Create an ext4 Filesystem Safely with mke2fs

mke2fs writes a new filesystem in place, and on the wrong device it erases everything without asking twice. This guide builds one in a disposable image, inspects the result and checks it without repairing anything. The same decisions apply when the final target is a real partition, but the example itself never touches a disk device. Allow about 15 minutes, plus the time to identify the correct production device if you are preparing one.

This guide uses e2fsprogs 1.47.0, installed here as package version 1.47.0-2.4~exp1ubuntu4.1. You need a shell and enough space for a 64 MiB temporary file. The image commands are ordinary user commands. Creating a filesystem on a real device requires elevated privileges and destroys its existing filesystem.

1. Check the command and target

Confirm which implementation will run and read the version before choosing options:

$ command -v mke2fs
/usr/sbin/mke2fs
$ mke2fs -V
mke2fs 1.47.0 (5-Feb-2023)
	Using EXT2FS Library version 1.47.0

Do not substitute a production disk until you have checked it independently. A device name such as /dev/sdb can change after a reboot or hardware change. Inspect the device, its partitions and mounts with your normal inventory tools, for example:

$ lsblk -o NAME,SIZE,TYPE,FSTYPE,MOUNTPOINTS,UUID

Stop if the target contains data you need. mke2fs creates filesystem metadata; it is not an in-place conversion tool.

2. Create a disposable ext4 image

First make an empty 64 MiB file in /tmp, then format that file. The -F option is needed because the target is a regular file rather than a block device. It is also a dangerous option on a real device: it bypasses the normal warning about an apparently mounted or non-device target.

$ image=$(mktemp /tmp/mke2fs-guide.XXXXXX)
$ truncate -s 64M "$image"
$ mke2fs -t ext4 -F -L guide-test "$image"
mke2fs 1.47.0 (5-Feb-2023)
Creating filesystem with 16384 4k blocks and 16384 inodes
Creating journal (1024 blocks): done
Writing superblocks and filesystem accounting information: done

The progress lines can include terminal control characters and may look untidy when copied from a log. The useful result is a zero exit status and a filesystem created on the named image. On a real target, omit -F unless you have a specific, reviewed reason to force the operation. Use sudo only for the final device command, not for this temporary-file exercise.

Checkpoint: Keep the value of $image in the same shell. If you open a new shell, locate the file with find /tmp -maxdepth 1 -name 'mke2fs-guide.*' -type f before continuing.

3. Inspect the filesystem identity

Use tools that read the image rather than mounting it. The label and type should agree with the values requested:

$ file "$image"
/tmp/mke2fs-guide.XXXXXX: Linux rev 1.0 ext4 filesystem data ... volume name "guide-test" ...
$ blkid "$image"
/tmp/mke2fs-guide.XXXXXX: LABEL="guide-test" ... BLOCK_SIZE="4096" TYPE="ext4"
$ dumpe2fs -h "$image" 2>/dev/null | sed -n '1,18p'
Filesystem volume name:   guide-test
Filesystem state:         clean
Filesystem OS type:       Linux
Block size:               4096
Inode size:               256

The UUID is generated unless you provide one with -U. Treat it as an identifier, not a secret. A copied image will also copy its UUID, so cloned images may need a deliberate UUID change before they are used together.

4. Run a read-only filesystem check

Before using a newly created filesystem, run e2fsck in no-modify mode. The -n option answers questions negatively and prevents repairs; -f asks for a check even when the clean flag would otherwise allow it to be skipped:

$ e2fsck -fn "$image"
e2fsck 1.47.0 (5-Feb-2023)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
guide-test: 11/16384 files, 2065/16384 blocks

For a real, mounted filesystem, do not run a repair check casually. Unmount it first and follow your system's maintenance procedure. A check that needs repair is a service and data-availability decision, not a reason to add -y to a command copied from a terminal.

5. Understand the defaults before changing them

When you omit options, mke2fs reads /etc/mke2fs.conf. This machine's configuration sets a 4096-byte default block size, 256-byte inodes, a 16384-byte inode ratio, and default mount options of acl,user_xattr. The ext4 filesystem type adds features such as a journal, extents, flex groups, metadata checksums and 64-bit support. These are local defaults, not universal promises.

The configuration uses INI-style stanzas. The [defaults] stanza supplies general values, while [fs_types] can refine them for a filesystem or usage type. A command-line option takes precedence over the configuration. Read the file before changing it:

$ sed -n '1,120p' /etc/mke2fs.conf
$ mke2fs -n -t ext4 "$image"
mke2fs 1.47.0 (5-Feb-2023)
Creating filesystem with 16384 4k blocks and 16384 inodes

-n performs a dry run and does not write a filesystem. It is useful for checking the selected size and inode count, but it does not prove that a real device is safe to overwrite.

6. Translate the image workflow to a real device

Only after the target has been identified, unmounted and backed up should you format it. This is the destructive boundary:

$ lsblk -o NAME,SIZE,TYPE,FSTYPE,MOUNTPOINTS,UUID
$ sudo umount /dev/DEVICE_PARTITION
$ sudo mke2fs -t ext4 -L DATA_LABEL /dev/DEVICE_PARTITION
$ sudo blkid /dev/DEVICE_PARTITION
$ sudo e2fsck -fn /dev/DEVICE_PARTITION

Replace /dev/DEVICE_PARTITION and DATA_LABEL only after checking them. Do not use a whole-disk path when you mean a partition. Do not format a mounted target. If the command refuses because the target appears mounted, investigate the mount rather than forcing it. If you have changed the wrong target, stop immediately and preserve the device for recovery work; repeated writes reduce recovery options.

To undo the temporary example, unmount it first if you mounted it, then remove only the exact image path. That deletion is irreversible:

$ printf 'Delete %s? [type the path exactly] ' "$image"
$ read answer
$ test "$answer" = "$image" && rm -- "$image"

Done means