How to Convert XFS to EXT4 Filesystem Without Data Loss in Linux: A Step-by-Step Guide


2 views

After battling with mysterious I/O errors following system standby on my Ubuntu 10.04 (Lucid Lynx) setup, I traced the problem to XFS filesystem instability during power state transitions. The configuration was:

- / (root) on EXT4 (46GB)
- /home on XFS (63GB) 
- 3GB swap

While Windows has its convert.exe utility for filesystem transitions, Linux requires a different approach.

Unlike FAT-to-NTFS conversions in Windows, Linux filesystems require full recreation for format changes because:

  • XFS and EXT4 use fundamentally different on-disk structures
  • Journaling mechanisms differ significantly
  • There's no equivalent to Windows' conversion utility

Here's the step-by-step method I used to preserve my 63GB home partition:


# 1. Boot from live USB to ensure no mounted partitions
sudo -i
umount /dev/sdaX  # replace X with your partition number

# 2. Create temporary backup (if space permits)
mkdir /mnt/tempbackup
mount /dev/sdaX /mnt/tempbackup
rsync -avz /mnt/tempbackup/ /path/to/external/

# 3. Verify backup integrity
diff -r /mnt/tempbackup/ /path/to/external/

After ensuring data safety, proceed with the conversion:


# 1. Unmount and wipe the partition
umount /dev/sdaX
mkfs.ext4 /dev/sdaX

# 2. Update /etc/fstab (example entry)
UUID=(new-uuid) /home ext4 defaults 0 2

# 3. Restore data
mount /dev/sdaX /mnt/newhome
rsync -avz /path/to/external/ /mnt/newhome/
chown -R user:user /mnt/newhome/*

For those handling multiple migrations, consider this bash script template:


#!/bin/bash
SOURCE_DEV="/dev/sda3"
BACKUP_DIR="/mnt/backup"
TARGET_USER="ubuntu"

# Safety checks
[ ! -b "$SOURCE_DEV" ] && exit 1
df -h | grep -q "$SOURCE_DEV" && umount "$SOURCE_DEV"

# Backup phase
mkdir -p "$BACKUP_DIR"
mount "$SOURCE_DEV" "$BACKUP_DIR"
rsync -aAXv --delete "$BACKUP_DIR/" "/mnt/external/"

# Conversion phase
mkfs.ext4 -F "$SOURCE_DEV"
tune2fs -m 0 "$SOURCE_DEV"

# Restoration
mount "$SOURCE_DEV" "$BACKUP_DIR"
rsync -aAXv --delete "/mnt/external/" "$BACKUP_DIR/"
chown -R "$TARGET_USER":"$TARGET_USER" "$BACKUP_DIR"/*

Through three OS reinstalls, I learned:

  • EXT4 showed better stability with power management
  • XFS performance benefits didn't outweigh reliability concerns
  • Keeping /home separate still makes sense for future migrations

During a recent Ubuntu 10.04 (Lucid Lynx) deployment, I configured my filesystems as:

/       - 46GB ext4
/home   - 63GB xfs (originally misidentified as jfs)
swap    - 3GB

After leaving the machine overnight on battery power, I discovered the /home partition became inaccessible with I/O errors following standby resume. This pointed to potential xfs filesystem compatibility issues with power management states.

Unlike Windows filesystem conversions (FAT to NTFS), Linux doesn't provide native in-place conversion between xfs and ext4 due to fundamental architectural differences:

  • XFS uses B+ trees for metadata while ext4 uses HTrees
  • Journaling implementations differ significantly
  • Inode allocation strategies are incompatible

Here's the reliable procedure I developed after two failed OS reinstalls:

# 1. Create backup (even when working on a copy)
sudo dd if=/dev/sdXN of=xfs_backup.img bs=4M status=progress

# 2. Prepare temporary storage (size >= current usage)
sudo mkdir /mnt/tempstore
sudo mount /dev/sdYN /mnt/tempstore

# 3. Copy data preserving attributes
sudo rsync -avxHAX --progress /home/ /mnt/tempstore/

# 4. Unmount and reformat
sudo umount /home
sudo mkfs.ext4 /dev/sdXN

# 5. Restore data
sudo mount /dev/sdXN /home
sudo rsync -avxHAX --progress /mnt/tempstore/ /home/

# 6. Update fstab
sudo nano /etc/fstab
# Change from:
# /dev/sdXN /home xfs defaults 0 2
# To:
# /dev/sdXN /home ext4 defaults 0 2

For developers managing multiple systems, here's a basic automation script:

#!/bin/bash
SOURCE="/home"
TEMP_MOUNT="/mnt/migrate_temp"
BACKUP_IMG="/var/backups/xfs_home.img"

# Safety checks
[ $(mount | grep "$SOURCE" | wc -l) -eq 0 ] && echo "Source not mounted" && exit 1
[ ! -d "$TEMP_MOUNT" ] && mkdir -p "$TEMP_MOUNT"

echo "Creating backup image..."
dd if=$(findmnt -n -o SOURCE "$SOURCE") of="$BACKUP_IMG" bs=4M status=progress

echo "Mounting temporary storage..."
mount /dev/sdZN "$TEMP_MOUNT"

echo "Starting data migration..."
rsync -avxHAX --progress "$SOURCE/" "$TEMP_MOUNT/"

echo "Reformatting source..."
umount "$SOURCE"
mkfs.ext4 $(findmnt -n -o SOURCE "$SOURCE")

echo "Restoring data..."
mount $(findmnt -n -o SOURCE "$SOURCE") "$SOURCE"
rsync -avxHAX --progress "$TEMP_MOUNT/" "$SOURCE/"

echo "Updating fstab..."
sed -i 's/xfs/ext4/g' /etc/fstab

echo "Migration complete!"

After conversion, always verify your data:

# Check for errors
sudo fsck.ext4 -f /dev/sdXN

# Compare file counts
orig_count=$(find /mnt/tempstore | wc -l)
new_count=$(find /home | wc -l)
echo "Original: $orig_count | New: $new_count"

# Verify critical files
sudo diff -r /mnt/tempstore/important_dir /home/important_dir