migration2024-05-15·13 min·304/348

Converting ext4 to xfs on Linux: Filesystem Migration Guide

How to convert a Linux filesystem from ext4 to xfs, including data migration, performance comparison, and when to choose each filesystem.

Introduction

ext4 and xfs are the two most common Linux filesystems, each with different strengths. ext4 is the default on many distributions and excels at general-purpose use. xfs is preferred for large files and parallel I/O workloads. Converting between them requires a data migration strategy since there is no in-place conversion tool. This post covers the migration process and when to choose each filesystem.

Environment

The examples convert a 500 GB ext4 partition to xfs on Ubuntu 22.04 LTS. The partition contains a mix of small files and large media files.

df -T /data
# Filesystem     Type 1K-blocks      Used Available Use% Mounted on
# /dev/sdb1      ext4  524288000 123456789 376831211  25% /data

blkid /dev/sdb1
# /dev/sdb1: UUID="12345678-1234-1234-1234-123456789abc" TYPE="ext4"

Problem

You want to migrate from ext4 to xfs for better performance with large files, or because your distribution defaults to xfs. The challenge is that there is no direct conversion tool. The migration requires:

  1. Backing up data
  2. Recreating the partition as xfs
  3. Restoring data
  4. Updating system configuration

Analysis

ext4 vs xfs comparison:

Featureext4xfs
Max file size16 TB8 EB
Max volume size1 EB8 EB
Default onDebian, UbuntuRHEL, CentOS
JournalMetadata onlyData + metadata
Online defragYesYes (xfs_fsr)
QuotaYesYes (better)
SnapshotsNoNo
AllocationBlock-basedExtent-based

When to choose xfs:

  • Large files (media, databases)
  • High parallel I/O
  • Large volumes (> 16 TB)
  • Server workloads

When to choose ext4:

  • General-purpose use
  • Many small files
  • USB drives, SD cards
  • Recovery tools are more mature

Solution

1. Back up the data

# Create a full backup
sudo rsync -av /data/ /backup/data/

# Or use tar
sudo tar -czf /backup/data-backup.tar.gz -C / data

# Verify backup
ls -lh /backup/data-backup.tar.gz

2. Unmount the partition

# Stop any services using the partition
sudo systemctl stop nginx  # If serving web content

# Unmount
sudo umount /data

# If the partition is busy, find what is using it
sudo lsof +D /data
sudo fuser -m /data

3. Recreate the partition as xfs

# Check partition table
sudo fdisk -l /dev/sdb
# Device     Boot   Start       End   Sectors  Size Id Type
# /dev/sdb1          2048 1048575999 1048573952  500G 83 Linux

# Create new xfs filesystem
sudo mkfs.xfs -f /dev/sdb1
# meta-data=/dev/sdb1              isize=512    agcount=4, agsize=32768000 blks
#          =                       sectsz=512   attr=2, projid32bit=1
# data     =                       bsize=4096   blocks=131072000, imaxpct=25
#          =                       sunit=0      swidth=0 blks
# naming   =version 2              bsize=4096   ascii-ci=0 ftype=1
# log      =internal log           bsize=4096   blocks=64000, version=2
#          =           sectsz=512   sunit=0 blks, lazy-count=1
# realtime =none                   extsz=4096   blocks=0, rtextents=0

4. Mount the new filesystem

# Create mount point (if not exists)
sudo mkdir -p /data

# Mount
sudo mount /dev/sdb1 /data

# Update /etc/fstab
# Find the old entry
grep /data /etc/fstab
# UUID=12345678-1234-1234-1234-123456789abc /data ext4 defaults 0 2

# Update to xfs with new UUID
sudo blkid /dev/sdb1
# /dev/sdb1: UUID="abcdef01-2345-6789-abcd-ef0123456789" TYPE="xfs"

# Edit /etc/fstab
sudo nano /etc/fstab
# UUID=abcdef01-2345-6789-abcd-ef0123456789 /data xfs defaults 0 2

5. Restore data

# Restore from rsync
sudo rsync -av /backup/data/ /data/

# Or restore from tar
sudo tar -xzf /backup/data-backup.tar.gz -C /

# Verify data
du -sh /data
ls -la /data

6. Set permissions

# Set ownership
sudo chown -R root:root /data

# Set permissions
sudo chmod -R 755 /data

# For specific directories
sudo chown -R www-data:www-data /data/web
sudo chmod -R 750 /data/web

7. Enable xfs-specific features

# Enable discard for SSDs
sudo mount -o remount,discard /data

# Or update /etc/fstab
# UUID=abcdef01-... /data xfs defaults,discard 0 2

# Enable user quotas
sudo mount -o remount,usrquota /data

# Initialize quota
sudo quotacheck -cmu /data
sudo quotaon /data

8. Verify the migration

# Check filesystem type
df -T /data
# Filesystem     Type 1K-blocks      Used Available Use% Mounted on
# /dev/sdb1      xfs   524288000 123456789 376831211  25% /data

# Check mount options
mount | grep /data
# /dev/sdb1 on /data type xfs (rw,relatime,attr2,inode64,logbufs=8,logbsize=256k,noquota)

# Run a performance test
dd if=/dev/zero of=/data/test bs=1M count=1024 oflag=direct

9. Performance comparison

# Test read performance
dd if=/data/test of=/dev/null bs=1M

# Test write performance
dd if=/dev/zero of=/data/test bs=1M count=1024 oflag=direct

# Test random I/O with fio
fio --name=test --rw=randwrite --bs=4k --size=1G --numjobs=4 --runtime=60

10. Cleanup

# Remove backup (after verifying)
# sudo rm -rf /backup/data

# Remove old backup archive
# sudo rm /backup/data-backup.tar.gz

Lessons Learned

Filesystem migration from ext4 to xfs requires a backup-and-restore approach since there is no in-place conversion tool. Always verify backups before proceeding. xfs excels for large files and server workloads, while ext4 remains excellent for general-purpose use. The migration is straightforward but requires planning and downtime. Test the migration procedure in a staging environment before applying to production.


This blog does not accept any external sponsorships, affiliate marketing, or ad revenue.