6

I have a Linux/Windows dual boot setup on my notebook, in which I used to keep most of the data on the Windows partition to be able to access it from both systems. Since I almost never use Windows I shrunk the NTFS partition and plan to move the data to the Linux partition which is formatted as btrfs. Beforehand the btrfs partition needs to be expanded at the beginning where the now free space is.

fdisk can move the beginning of a partition but leaves the filesystem untouched. parted cannot handle the filesystem, either, since version 3.0.

One solution to the problem would be to create a partition in the free space and add it as a backing device to the btrfs, then removing the original btrfs from btrfs (using btrfs device) and the partition table and after that expanding the remaining btrfs+partition to the end of the drive. The problems here are that the new free space must be big enough to hold all the files from the btrfs and that all the data has to be moved.

So my question is: Is there some other, preferably more elegant and generally applicable, way to expand a btrfs at the beginning?

Edit: (Solution)

Even if GParted might be able to resize at the beginning by automatically moving the filesystem, I tried the way described above since I have the free space. As it took ages (perhaps because of many subvolumes), used many cpu and I/O resources and then aborted with an I/O error, I used btrfs replace instead which worked just fine: It took a few hours during which the computer was perfectly usable.

3
  • 1
    What about moving the partition to the beginning with fdisk (you said that would work), then extending the partition. And then you could grow the file-system with btrfs filesystem resize max /your/fs as in btrfs.wiki.kernel.org/index.php/… Oct 31, 2017 at 10:25
  • 1
    Is it a problem to have btrfs cover two partitions? Oct 31, 2017 at 15:24
  • @daftaupe: If I moved the beginning of the partition usung fdisk the fs would stay untouched. The fs would start in the middle of the partition and, hence, not be found. btrfs filesystem resize only expands the fs at the end.
    – jorsn
    Oct 31, 2017 at 17:17

2 Answers 2

0

No, there isn't another way. In fact, I don't know of any filesystem which allows resizing at the beginning.

So either you can add the new partition to the pool and thus not have to move your data, or proceed as you described.

0

One solution to the problem would be to create a partition in the free space and add it as a backing device to the btrfs, then removing the original btrfs from btrfs (using btrfs device) and the partition table and after that expanding the remaining btrfs+partition to the end of the drive. The problems here are that the new free space must be big enough to hold all the files from the btrfs and that all the data has to be moved.

This can be done in multiple steps. The number of steps depends on how much free space you have in the filesystem and on the sizes of the relevant partitions. The procedure will move data back and forth, it will strain the disk, it will take time and your effort; but the filesystem will be online all the time.

I have done it once with about 2 TB of data. It was on a home router/server working 24/7 anyway, so I could afford checking every few hours to eventually start the next step. I vaguely remember this took more than a week. Your mileage may vary.

In general you will need to create many partitions (temporarily), not in the disk order, so I'm not sure if it can easily (or at all) be done with a dos partition table in MBR. I have done it with GPT and I assume this is the type you are using.

The procedure:

  1. Add the new partition (N) to the old filesystem, like you described: btrfs device add … /the/mountpoint.
  2. Shrink the filesystem specifically on the old partition (O): btrfs filesystem resize <devid>:-… /the/mountpoint. You must specify the right <devid>, run btrfs filesystem show /the/mountpoint to find it. I advise to shrink by significantly less than the free space in the filesystem (this will become clear in step 11, keep reading).
  3. Shrink the old partition by the same amount by changing its end sector. Do not change the start sector.
  4. Now you have free space after the old partition. Create a new temporary partition (A) there.
  5. Add the new temporary partition to the filesystem.
  6. Repeat from step 2, until the old partition (after being resized again and again) is small enough (in comparison to free space in the filesystem), so you can remove it from the filesystem. In this loop you will create several temporary partitions (B, C, D, …).
  7. Remove the old partition from the filesystem: btrfs device remove /dev/… /the/mountpoint.
  8. Remove the old partition (O) from the partition table.
  9. Expand the new partition (N) to the right as much as you can.
  10. Maximally resize the filesystem on the new partition: btrfs filesystem resize <devid>:max /the/mountpoint.
  11. Remove the temporary partition adjacent to the new partition from the filesystem. This step may fail if there is not enough free space in the filesystem. This is the reason you should not shrink the filesystem too much in step 2. Working with partitions significantly smaller than free space in the filesystem gives you a safety margin, especially if the filesystem is in active use and free space may fluctuate.
  12. Remove the temporary partition adjacent to the new partition from the partition table.
  13. Repeat from step 9, until you cannot do 11 because there are no temporary partitions left.

The following diagram is a visualization of the procedure. The disk spans from left to right, time flows from top to bottom. Legend:

  • O – the old partition
  • N – the new partition
  • A, B, C, … – temporary partitions
  • - – unallocated space
  • – steps omitted for brevity
NNNNNNNNOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
NNNNNNNNOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO----
NNNNNNNNOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOAAAA
NNNNNNNNOOOOOOOOOOOOOOOOOOOOOOOOOO----AAAA
NNNNNNNNOOOOOOOOOOOOOOOOOOOOOOOOOOBBBBAAAA
NNNNNNNNOOOOOOOOOOOOOOOOOOOOOO----BBBBAAAA
…
NNNNNNNNOOOOOOGGGGFFFFEEEEDDDDCCCCBBBBAAAA
NNNNNNNNOO----GGGGFFFFEEEEDDDDCCCCBBBBAAAA
NNNNNNNNOOHHHHGGGGFFFFEEEEDDDDCCCCBBBBAAAA
NNNNNNNN--HHHHGGGGFFFFEEEEDDDDCCCCBBBBAAAA
NNNNNNNNNNHHHHGGGGFFFFEEEEDDDDCCCCBBBBAAAA
NNNNNNNNNN----GGGGFFFFEEEEDDDDCCCCBBBBAAAA
NNNNNNNNNNNNNNGGGGFFFFEEEEDDDDCCCCBBBBAAAA
…
NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNBBBBAAAA
NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN----AAAA
NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNAAAA
NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN----
NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN

Done. The entire filesystem is inside a single partition that begins and ends where you wanted.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .