Moving a Linux directory to a new filesystem

Posted on Monday, March 23, 2015

Moving a Linux directory to a new filesystem

This document will cover the issue of moving a Linux directory to a new partition because the current one has run out of space (or for any other reason). For simplicity, we will suppose that this directory is /home, although it could be almost any other one without major changes. For example, let's assume that the new partition you want to locate that directory is /dev/sdb1 and that this partition is already formatted. If it is not formatted, I understand that everybody knows how to get it. If not, is not the aim of this document to explain how to create and format partitions on Linux: it is a very basic task and there is abundant documentation.

Then, what are the steps to achieve our purpose?

First, boot the computer without logging in to X. If you have already logged in, then log out.

Go to a text console with Control+Alt+F1 (or Control+Alt+F2, F3, F4, etc. in some systems that do not have the console 1 enabled.)

If you use a system like Ubuntu which has root user access disabled, you will have to log in as a normal user. This puts you at your home directory which will be something like /home/username. You will need to go out of there and put yourself in any other directory so /home directory is not in use:

cd /tmp

So, now that /home is not in use, you can become root:

sudo bash

Now ensure that there is no file in use in /home:

lsof -n | fgrep /home

If there is still some process using any file in /home, close it or kill it.

Mount the new home partition in an empty directory (remember to change /dev/sdb1 as appropriate):

mkdir /mnt/home
mount /dev/sdb1 /mnt/home

Move all files in /home to the new filesystem:

mv /home/* /mnt/home

Make sure you have not left any hidden file (the hidden files are not included in *) and, if there is any, move it:

ls -a /home

Watch out for mv with .* since it doesn't have the result you could expect at first.

Unmount the partition:

umount /dev/sdb1
rmdir /mnt/home

Add a new line in /etc/fstab to always mount the partition at boot:

/dev/sdb1 /home ext3 defaults,noatime,nodiratime 1 2

For more information about the meaning of each column, see the fstab(5) man page.

Tip: imagine that you open your computer, you touch the wires and end up with the disk plugged into a different SATA bus and instead of sdb it becomes sdc. This fstab line will no longer work. So it is better to use the filesystem UUID, which never changes unless you format the partition. You can get the filesystem UUID with:

blkid /dev/sdb1

Take note of the UUID and use it in fstab instead of the device name. For example:

UUID=911013a0-e6e3-401c-88ca-23532284b7de /home ext3 defaults,noatime,nodiratime 1 2

Of course, replacing ext3 with the file system you used: ext2, ext3, ext4, btrfs, xfs, ...

By default, each time you access a file, its last access date is updated. This converts a read operation to a read/write one affecting performance and life of the drive. So it is always advisable to mount the device with noatime and nodiratime options unless you have a good reason to need access dates.

Now you can check if /home partition is mounted correctly:

mount /home

And finally, you reboot the computer and, before logging in X, return to the text console ( Control+Alt+F1) and log in to check with mount if the new /home filesystem is correctly mounted at startup.