đź’ľ mkfs Command

Creating Filesystems on Linux Storage Devices

Overview

The mkfs (make filesystem) command creates a filesystem on a block device such as a hard disk partition, USB drive, or other storage media. It's actually a front-end that calls filesystem-specific utilities (mkfs.ext4, mkfs.xfs, mkfs.vfat, etc.). Understanding mkfs is critical for system administration tasks like preparing new disks, formatting storage devices, and setting up filesystems with specific characteristics for performance or reliability requirements.

Syntax: mkfs [OPTIONS] [-t type] device

Warning: mkfs destroys all existing data on the target device. Always double-check the device name before running this command!

⚠️ CRITICAL SAFETY WARNING

mkfs is DESTRUCTIVE! It will completely erase all data on the specified device. There is NO UNDO.

  • Always verify the device name with lsblk or fdisk -l
  • Double-check you're not formatting your system disk
  • Unmount the device before formatting
  • Back up any important data first
  • Be especially careful with wildcards and variables
Example 1

Creating an ext4 Filesystem (Most Common)

# First, identify the device: $ lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT sda 8:0 0 238.5G 0 disk ├─sda1 8:1 0 512M 0 part /boot └─sda2 8:2 0 238G 0 part / sdb 8:16 1 14.9G 0 disk # Create ext4 filesystem on USB drive: $ sudo mkfs.ext4 /dev/sdb1 mke2fs 1.46.5 (30-Dec-2021) Creating filesystem with 3907072 4k blocks and 977280 inodes Filesystem UUID: 12345678-1234-1234-1234-123456789abc Superblock backups stored on blocks: 32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208 Allocating group tables: done Writing inode tables: done Creating journal (16384 blocks): done Writing superblocks and filesystem accounting information: done # Verify the filesystem: $ sudo blkid /dev/sdb1 /dev/sdb1: UUID="12345678-1234-1234-1234-123456789abc" TYPE="ext4"

What's Happening:

The most common use case: creating an ext4 filesystem on a partition. First, use lsblk to identify the correct device. Then mkfs.ext4 creates the filesystem, setting up superblocks, inode tables, and the journal. Ext4 is the default filesystem for most Linux distributions, offering good performance, reliability, and large file/partition support.

Note: Use mkfs.ext4 directly or mkfs -t ext4. Both work the same way.
Example 2

Formatting with Custom Label and Options

# Create filesystem with a label: $ sudo mkfs.ext4 -L "BACKUP_DRIVE" /dev/sdb1 # Set custom parameters: $ sudo mkfs.ext4 -L "DATA" -N 1000000 -m 1 /dev/sdb1 # -L: Set volume label # -N: Number of inodes (1 million) # -m: Reserved space percentage (1% instead of default 5%) # Check the filesystem: $ sudo tune2fs -l /dev/sdb1 | grep -i "volume\|block\|inode" Filesystem volume name: DATA Block count: 3907072 Reserved block count: 39070 Free blocks: 3823456 Block size: 4096 Inode count: 1000000 # Mount by label: $ sudo mount LABEL=DATA /mnt/backup

What's Happening:

Labels make filesystems identifiable and allow mounting by name instead of device path. The -N option sets the number of inodes (useful if you'll have many small files). The -m option reduces reserved space (default 5% can waste space on large drives). These optimizations are important for specific use cases like backup drives or file servers.

Pro Tip: For large data drives (>1TB) used for big files, reduce reserved space to 1% or even 0% to reclaim storage.
Example 3

Creating XFS Filesystem (High Performance)

# Create XFS filesystem: $ sudo mkfs.xfs -f /dev/sdb1 # -f forces overwrite if filesystem already exists # With label and custom settings: $ sudo mkfs.xfs -f -L "FAST_STORAGE" -d agcount=8 /dev/sdb1 meta-data=/dev/sdb1 isize=512 agcount=8, agsize=122096 blks = sectsz=512 attr=2, projid32bit=1 = crc=1 finobt=1, sparse=0 data = bsize=4096 blocks=976768, imaxpct=25 = sunit=0 swidth=0 blks naming =version 2 bsize=4096 ascii-ci=0 ftype=1 log =internal log bsize=4096 blocks=2560, version=2 = sectsz=512 sunit=0 blks, lazy-count=1 realtime =none extsz=4096 blocks=0, rtextents=0 # Check XFS filesystem: $ sudo xfs_info /dev/sdb1 # Mount it: $ sudo mount /dev/sdb1 /mnt/fast

What's Happening:

XFS is a high-performance 64-bit journaling filesystem excellent for large files and parallel I/O. It's used by many enterprise systems and is RHEL's default filesystem. The -f flag forces creation even if a filesystem exists. The -d agcount option sets allocation groups for parallelism. XFS excels at handling large files and can scale to enormous sizes (up to 8 exabytes).

Use XFS when: You need high performance, large file support, or are running database servers, video editing, or large-scale storage systems.
Example 4

Creating FAT32 Filesystem (Cross-Platform Compatibility)

# Create FAT32 filesystem: $ sudo mkfs.vfat -F 32 -n "USB_DRIVE" /dev/sdb1 mkfs.fat 4.2 (2021-01-31) # Alternative with specific sector size: $ sudo mkfs.fat -F 32 -n "FLASH" -s 2 /dev/sdb1 # -F 32: FAT32 filesystem type # -n: Volume name (label) # -s 2: 2 sectors per cluster # Create exFAT for large files on flash drives: $ sudo mkfs.exfat -n "LARGE_FILES" /dev/sdb1 # Verify: $ sudo blkid /dev/sdb1 /dev/sdb1: LABEL="USB_DRIVE" UUID="1234-5678" TYPE="vfat"

What's Happening:

FAT32 (vfat) is used for maximum compatibility across Windows, Mac, and Linux. It's perfect for USB drives that need to work on multiple platforms. However, FAT32 has limitations: 4GB maximum file size and 32GB maximum partition size (in some implementations). For larger files on removable media, use exFAT instead, which supports large files while maintaining cross-platform compatibility.

Best Use: FAT32 for small USB drives and devices. exFAT for large flash drives or external drives shared between systems.
Example 5

Creating Btrfs Filesystem (Advanced Features)

# Create Btrfs filesystem: $ sudo mkfs.btrfs -L "SNAPSHOTS" /dev/sdb1 btrfs-progs v5.16.2 See http://btrfs.wiki.kernel.org for more information. Label: SNAPSHOTS UUID: 12345678-1234-1234-1234-123456789abc Node size: 16384 Sector size: 4096 Filesystem size: 14.90GiB Block group profiles: Data: single 8.00MiB Metadata: DUP 1.00GiB System: DUP 8.00MiB SSD detected: no Zoned device: no Incompat features: extref, skinny-metadata Runtime features: Checksum: crc32c Number of devices: 1 Devices: ID SIZE PATH 1 14.90GiB /dev/sdb1 # Create with compression: $ sudo mkfs.btrfs -L "COMPRESSED" -f /dev/sdb1 $ sudo mount -o compress=zstd /dev/sdb1 /mnt/compressed # Multi-device Btrfs (RAID): $ sudo mkfs.btrfs -L "RAID1" -d raid1 -m raid1 /dev/sdb1 /dev/sdc1 # -d raid1: Data in RAID1 # -m raid1: Metadata in RAID1

What's Happening:

Btrfs (B-tree filesystem) is a modern copy-on-write filesystem with advanced features: snapshots, compression, RAID, and checksumming for data integrity. It's particularly useful for systems requiring frequent backups (via snapshots) or data integrity verification. Btrfs can handle multiple devices natively, providing software RAID functionality built into the filesystem itself.

Btrfs Features: Built-in snapshots, transparent compression, online defragmentation, and subvolumes make it ideal for desktop and server use cases requiring flexibility.
Example 6

Checking and Preparing Device Before Formatting

# Check all devices and partitions: $ lsblk -f NAME FSTYPE LABEL UUID MOUNTPOINT sda ├─sda1 ext4 ROOT abcd1234-... / └─sda2 swap efgh5678-... [SWAP] sdb └─sdb1 ext4 OLD_DATA ijkl9012-... # Check if device is mounted: $ mount | grep sdb1 /dev/sdb1 on /mnt/old type ext4 (rw,relatime) # Unmount before formatting: $ sudo umount /dev/sdb1 # Wipe existing filesystem signatures: $ sudo wipefs -a /dev/sdb1 /dev/sdb1: 2 bytes were erased at offset 0x00000438 (ext4): 53 ef # Now safe to format: $ sudo mkfs.ext4 -L "NEW_DATA" /dev/sdb1 # Check current usage: $ df -h | grep sdb1

What's Happening:

Before formatting, always verify the correct device, check if it's mounted, and unmount it if necessary. The wipefs command removes old filesystem signatures, preventing confusion. The lsblk -f command shows all block devices with their filesystem types, labels, and UUIDs—essential for confirming you're formatting the right device.

Safety Check: Always run mount | grep device before mkfs to ensure you're not about to format a mounted, actively-used filesystem!
Example 7

Creating Filesystem with Specific Block Size

# Default block size (4096 bytes): $ sudo mkfs.ext4 /dev/sdb1 # Custom 2KB block size (for many small files): $ sudo mkfs.ext4 -b 2048 /dev/sdb1 # Smaller blocks = more space efficient for small files # 8KB blocks (for large files, better performance): $ sudo mkfs.ext4 -b 8192 /dev/sdb1 # Larger blocks = better for big files, less overhead # Check block size after creation: $ sudo tune2fs -l /dev/sdb1 | grep "Block size" Block size: 4096 # XFS with custom block size: $ sudo mkfs.xfs -b size=4096 /dev/sdb1 # Example with rationale: # Email server (many small files): $ sudo mkfs.ext4 -b 1024 -N 5000000 /dev/sdb1 # Video storage (large files): $ sudo mkfs.ext4 -b 8192 -i 262144 /dev/sdb1

What's Happening:

Block size affects performance and space efficiency. Smaller blocks (1K-2K) are better for many small files but have more overhead. Larger blocks (8K-64K) improve performance for large files and reduce metadata overhead but can waste space if you have many small files. The default 4K is a good compromise for general use. Adjust based on your specific workload.

Guidelines: Use 1-2K blocks for mail servers, 4K for general use, 8K+ for video/database storage. Always test with your specific workload.
Example 8

Enterprise: Creating Filesystem with Journal Options

# Create with external journal for performance: # First, create journal device: $ sudo mkfs.ext4 -L "JOURNAL" /dev/sdc1 # Create filesystem using external journal: $ sudo mkfs.ext4 -J device=/dev/sdc1 -L "DATA" /dev/sdb1 # Journal on separate, fast device (like SSD) # Adjust journal size: $ sudo mkfs.ext4 -J size=128 /dev/sdb1 # 128MB journal (default is usually 32-64MB) # Disable journal entirely (for SSDs, testing): $ sudo mkfs.ext4 -O ^has_journal /dev/sdb1 # WARNING: Less data protection, only for specific use cases # Create with lazy journal init (faster initial format): $ sudo mkfs.ext4 -E lazy_itable_init=1,lazy_journal_init=1 /dev/sdb1 # Check journal information: $ sudo tune2fs -l /dev/sdb1 | grep -i journal Filesystem features: has_journal ext_attr resize_inode Journal inode: 8 Journal backup: inode blocks

What's Happening:

Journal configuration significantly impacts performance and reliability. An external journal on a separate, fast device (especially SSD) can improve write performance. Larger journals handle more concurrent writes. Lazy initialization speeds up initial formatting but delays some initialization until first use. Disabling the journal trades data protection for performance—only do this for temporary filesystems or on hardware-RAID with battery-backed cache.

Enterprise Tip: For high-performance database servers, consider external journal on dedicated SSD or even RAM disk (with backup power).
Example 9

Scripted Safe Formatting with Verification

#!/bin/bash # safe-format.sh - Safe filesystem creation with verification DEVICE="" FSTYPE="ext4" LABEL="" DRY_RUN=false # Function to check if device exists check_device() { if [ ! -b "$DEVICE" ]; then echo "ERROR: $DEVICE is not a block device" exit 1 fi } # Function to check if device is mounted check_mounted() { if mount | grep -q "$DEVICE"; then echo "ERROR: $DEVICE is currently mounted!" mount | grep "$DEVICE" exit 1 fi } # Function to show device info show_device_info() { echo "=== Device Information ===" lsblk "$DEVICE" echo "" echo "=== Current Filesystem (if any) ===" sudo blkid "$DEVICE" || echo "No filesystem detected" echo "" } # Parse arguments while getopts "d:t:l:n" opt; do case $opt in d) DEVICE=$OPTARG ;; t) FSTYPE=$OPTARG ;; l) LABEL=$OPTARG ;; n) DRY_RUN=true ;; \?) echo "Usage: $0 -d device -t fstype -l label [-n]"; exit 1 ;; esac done # Verify required arguments if [ -z "$DEVICE" ]; then echo "ERROR: Device required (-d)" exit 1 fi # Safety checks echo "=== Safety Checks ===" check_device check_mounted show_device_info # Confirmation echo "=== WARNING ===" echo "This will DESTROY all data on $DEVICE" echo "Filesystem: $FSTYPE" [ -n "$LABEL" ] && echo "Label: $LABEL" echo "" if [ "$DRY_RUN" = true ]; then echo "DRY RUN - No changes will be made" exit 0 fi read -p "Type 'YES' to continue: " confirm if [ "$confirm" != "YES" ]; then echo "Aborted." exit 0 fi # Unmount if needed (even though we checked) sudo umount "$DEVICE" 2>/dev/null # Wipe old signatures echo "Wiping old filesystem signatures..." sudo wipefs -a "$DEVICE" # Create filesystem echo "Creating $FSTYPE filesystem..." case "$FSTYPE" in ext4) sudo mkfs.ext4 -L "$LABEL" -m 1 "$DEVICE" ;; xfs) sudo mkfs.xfs -f -L "$LABEL" "$DEVICE" ;; btrfs) sudo mkfs.btrfs -L "$LABEL" -f "$DEVICE" ;; vfat) sudo mkfs.vfat -F 32 -n "$LABEL" "$DEVICE" ;; *) echo "ERROR: Unsupported filesystem type: $FSTYPE" exit 1 ;; esac # Verify echo "" echo "=== Verification ===" sudo blkid "$DEVICE" lsblk -f "$DEVICE" echo "" echo "Filesystem created successfully!"

What's Happening:

This production-ready script demonstrates safe filesystem creation practices. It verifies the device exists, checks if it's mounted, shows current configuration, requires explicit confirmation, supports dry-run mode, wipes old signatures, and verifies the result. This is the proper way to automate formatting in production environments where mistakes could be catastrophic.

Usage: sudo ./safe-format.sh -d /dev/sdb1 -t ext4 -l BACKUP -n (dry run)
Then: sudo ./safe-format.sh -d /dev/sdb1 -t ext4 -l BACKUP (actual format)
Example 10

Complete Workflow: From New Disk to Mounted Filesystem

# Step 1: Identify the new disk $ lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT sda 8:0 0 238.5G 0 disk ├─sda1 8:1 0 512M 0 part /boot └─sda2 8:2 0 238G 0 part / sdb 8:16 0 1.8T 0 disk # <-- New disk, no partitions # Step 2: Create partition table $ sudo parted /dev/sdb mklabel gpt # Step 3: Create partition $ sudo parted /dev/sdb mkpart primary ext4 0% 100% # Step 4: Verify partition was created $ lsblk /dev/sdb NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT sdb 8:16 0 1.8T 0 disk └─sdb1 8:17 0 1.8T 0 part # Step 5: Create filesystem $ sudo mkfs.ext4 -L "DATA_DISK" -m 1 -E lazy_itable_init=1 /dev/sdb1 Creating filesystem with 488378368 4k blocks and 122085376 inodes [output continues...] # Step 6: Get UUID for /etc/fstab $ sudo blkid /dev/sdb1 /dev/sdb1: LABEL="DATA_DISK" UUID="a1b2c3d4-..." TYPE="ext4" # Step 7: Create mount point $ sudo mkdir -p /mnt/data # Step 8: Test mount $ sudo mount /dev/sdb1 /mnt/data $ df -h /mnt/data Filesystem Size Used Avail Use% Mounted on /dev/sdb1 1.8T 89M 1.7T 1% /mnt/data # Step 9: Add to /etc/fstab for automatic mounting $ echo "UUID=a1b2c3d4-... /mnt/data ext4 defaults 0 2" | sudo tee -a /etc/fstab # Step 10: Test fstab entry $ sudo umount /mnt/data $ sudo mount -a $ df -h /mnt/data # Step 11: Set permissions $ sudo chown craig:users /mnt/data $ sudo chmod 775 /mnt/data echo "New disk ready for use!"

What's Happening:

This complete workflow shows the entire process of preparing a new disk for use: identifying the disk, creating a partition table (GPT for large disks), partitioning, creating the filesystem with appropriate options, mounting temporarily for testing, adding to /etc/fstab for persistent mounting, and setting appropriate permissions. This is the real-world process administrators follow when adding storage to systems.

Production Note: For production systems, also consider:

Filesystem Comparison

Filesystem Max File Size Max Volume Size Best For Notes
ext4 16 TiB 1 EiB General purpose, Linux default Mature, stable, good performance
XFS 8 EiB 8 EiB Large files, databases, RHEL default Excellent for parallel I/O, can't shrink
Btrfs 16 EiB 16 EiB Snapshots, compression, flexibility Advanced features, active development
FAT32 4 GiB 2 TiB USB drives, cross-platform Maximum compatibility, file size limits
exFAT 128 PiB 128 PiB Large flash drives, external drives Cross-platform, no 4GB limit
NTFS 16 EiB 16 EiB Windows compatibility Full support requires ntfs-3g
ZFS 16 EiB 256 ZiB Enterprise storage, data integrity Not included in kernel, separate install

Best Practices & Safety Guidelines

⚠️ Critical Safety Rules

đź’ˇ Filesystem Selection Guide

📝 Performance Tuning Tips

Quick Reference: Common mkfs Commands

Command Description Example
mkfs.ext4 Create ext4 filesystem sudo mkfs.ext4 /dev/sdb1
mkfs.ext4 -L Create with label sudo mkfs.ext4 -L DATA /dev/sdb1
mkfs.xfs Create XFS filesystem sudo mkfs.xfs -f /dev/sdb1
mkfs.vfat Create FAT32 sudo mkfs.vfat -F 32 /dev/sdb1
mkfs.btrfs Create Btrfs sudo mkfs.btrfs -L NAME /dev/sdb1
wipefs -a Wipe filesystem signatures sudo wipefs -a /dev/sdb1
blkid Show filesystem UUID and type sudo blkid /dev/sdb1
lsblk -f List filesystems on all devices lsblk -f