How to a disk without a partition be “partitioned” without losing data

btrfsdiskfdiskpartitionresize2fs

I have a 1TB portable hard drive that I use for backups. The entire drive (/dev/sdb) has been formatted as an ext4 filesystem.

I have been reading about the benefits of btrfs for backups (checksums, self-healing, etc) and am considering converting this disk from ext4 to btrfs.

I'm pretty sure I can still resize the disk (e2fsck -f /dev/sdb && resize2fs /dev/sdb 500G && fdisk /dev/sdb, or thereabouts). However, I'm not sure how to "introduce" partitions to a device that didn't have partitions to start with.

Can this be done, and if so, how?

(Note that the filesystems themselves – ext4, btrfs, etc – are pretty much irrelevant – the question is purely about partitioning a device that was initially created without a partition – and doing so without losing the existing filesystem.)

Best Answer

Partition tables (at least in MBR or GPT style) live at the start and/or end of disks, so you can introduce them if you can free the required space.

Working with a terabyte disk, I would proceed as follows.

  1. Resize the ext4 file system to 499G (erring on the safe side). This ensures that all the data, file system structure etc. fits within the first 499G’s worth of blocks on the disk. Ideally you should reduce the file system as much as possible, that will reduce the amount of data you need to copy around in subsequent steps.
  2. Copy the blocks to the second half of the disk, using dd or a similar tool.
  3. Partition the disk, creating one partition which is slightly larger than the file system (500G). Use GPT for this; you’ll be overwriting blocks at the start and end of the disk, so the copy of the file system at the start of the disk is now toast.
  4. Copy the raw blocks from the second half of the disk to the newly-created partition, again using dd or something similar. You’ll need to calculate the offsets and sizes based on what you did in step 2, but the target is easy (/dev/sdX1).
  5. Resize the file system again so it occupies all the partition.

With a tool such as ddrescue which can copy in reverse, you could simplify this slightly:

  1. Resize the source file system as much as possible.
  2. Calculate where the first partition would start (without actually creating the partition table).
  3. Move the blocks composing the source file system so that they start where the first partition would start. (This is where you need to start copying from the end.)
  4. Partition the disk.
  5. Resize the file system.

Given the amount of copying involved, it would be easier to back the data up somewhere else and restore it! You could limit the amount of copying by saving the start of the ext4 file system and restoring that followed by the rest of the data, but that requires more careful book-keeping.

Related Question