1

I have a 3TB disk with btrfs which starts at the beginning of disk (i.e. /dev/sdx instead of /dev/sdx1). Meanwhile, I have decided I want to fully encrypt the disk (with luks), but I have no spare disk to take the data. Fortunately this disk is filled with only ~1TB, and I have already shrunk the filesystem. I know one can mount filesystems at byte offset, but is there a way to create filesystems at byte offset?

To solve my problem I would like to create a filesystem at 1.5TB, move data there, create 1TB btrfs on luks filesystem at beginning of disk, move data back, expand btrfs. Is there another solution which does not require extra disks/space? And would this solution work on SSD? (the last question is for mere curiousity, I've got an HDD)

Note: I would use dd to cp btrfs to other part of disk, but I've heard btrfs would not handle that very well due to same uid, or something.

0

The normal way to access a filesystem at an offset on a disk is with a partition. However, since you don't have room for a partition table at the beginning of the disk, you'll have to go through a more complex method.

You can use a loop device. Loop devices are mostly used to make a file appear as a block device, but you can make the block device start at an offset (and end at an offset, too), and the underlying file can itself be a block device, so you get a block device that corresponds to a segment of another block device. The command to manipulate loop devices is losetup.

losetup -o 1600g /dev/loop0 /dev/sda

Make sure that your filesystem indeed ends before the start of the loop device. Then you can copy it wholesale. I don't see why you would need to make a different filesystem¹: you shouldn't duplicate a btrfs filesystem on the same machine, but moving one (i.e. you won't ever access both at the same time) is ok.

head -c 1100g /dev/sda >/dev/loop0
mount -r /dev/loop0 /mnt
# Check that the filesystem looks fine
umount /mnt
losetup -d /dev/loop0

You could also do that by a suitable invocation of dd, but that's error-prone. It's easier to proceed step by step and to verify sizes before destroying data if you first set up block devices and then shuffle data around.

Now that you've moved the filesystem, create partitions, so that you won't run into this problem again.

fdisk /dev/sda
…

Create a partition that starts at the same offset that you passed to losetup above. Write the changes and verify that you can mount that partition.

Now create a partition for the LUKS volume, create the LUKS volume (cryptsetup luksFormat), and move the btrfs filesystem again onto the LUKS volume. Verify that the filesystem is still fine. Delete the partition at the end of the disk and extend the partition at the beginning of the disk. Extend the LUKS volume (cryptsetup resize), then extend the filesystem.

¹ It's straightforward to do it — mkfs.btrfs /dev/loop0 — but this is not the best solution to your problem.

  • Very nice answear! I can't find the source of the reason for having used the whole block-device is, except in this answear. Partitioning only helps to do precisely what you now answeared, so it's only an extra bit of work if things actually change (which is not expected at all). But thanks for the advice anyway :) Also, when I decided to use whole device I had an answear for this, but now I couldn't find it again (it seems the internet is dynamic :P) – Olivetree Jul 31 '16 at 11:48
  • While you did not answear (exactly) the question in bold/title (you did solve my problem though), I understood the underlying concept that losetup can be used to achieve it. Since it is easier to check consistency between 2 open filesystems, perhaps you should edit to mention that /dev/loop0 can be used in mkfs.btrfs? Then one can cp the files, use find with sha256sum, or some complex scripts. Might be useful for someone else. – Olivetree Jul 31 '16 at 13:01
  • @Olivetree Added — but I disagree, moving the data is safer: there's less risk of omitting some metadata, or a subvolume or something. – Gilles Jul 31 '16 at 13:10
  • That is indeed a good point. But for data verification, you anyway have to go through all files. I value my files more than subvolume structure. If for some reason moving silently fails, you have no way to checksum, since btrfs behaves oddly with both volumes open, and since metadata is already copied, the file structure is there (but no contents on some files). Hmm... Perhaps a diff on a list of files checksum. OTOH, my data might take more than 1TB without cow, and I might not have space left. I think I'll go with filelist checksum, or would a binary diff work? – Olivetree Jul 31 '16 at 14:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.