BTRFS is still relatively new as file systems go. This file system is not at all like the older ones you may be used to and the procedures can be quite different. One function that is vastly different is resizing a partition with a btrfs file system on it. This file system itself is not "attached" to the under-lying device (partition or drive) in the way you may be used to. You must resize the partition and file system separately and you must do it in the correct order or risk losing your data.
The latest versions of GParted can handle this, but if you want to learn the command line way - or if you're working on a remote server with no available desktop like me - continue reading...
If you're new to btrfs, one interesting feature is that most file system level commands are done while the file system is mounted! This is a surprise to new btrfs users. This means you can continue to use the file system while acting on it - expanding, shrinking, balancing (a btrfs feature to reclaim space and better distribute data), defrag-ing, and more - all done while still using the file system. However, this does not hold true when resizing the partition itself - that still requires it to be unmounted.
Expanding a BTRFS file system is fairly straight forward: expand the partition in any manner that you like and then tell btrfs to grow to fill the new size (use your btrfs file system mount in place of /mnt);
sudo btrfs filesystem resize max /mnt
That's about it for expanding. BTRFS will automagically fill the partition to it's maximum size.
However, Shrinking a partition with BTRFS on it; you must first shrink the file system, then resize the partition. The hard part is: How to you exactly determine how much to shrink the partition after shrinking the file system?
There is a command to determine the number of bytes used by a btrfs file system while mounted. Here's one of mine:
Note here that I was logged in as root, otherwise you must use "sudo" in front of the btrfs command.
**Pro Tip** BTRFS commands can be shortened to the least number of unambiguous letters in the command. So "btrfs filesystem usage" can be shortened to "btrfs f u" instead, since there are no other commands starting with "f" or "u".
But when I reduce my partition, the tools for this (fdisk, gdisk or parted) use sectors not bytes. So now we must determine exactly how many bytes are in each sector so we know how many sectors we can reduce the partition by. These numbers are quite large and if I mess up here, I risk losing the entire file system.
Thank goodness there is a safer and easier way to accomplish this task in three steps:
I want to shrink my BTRFS file system and partition from it's current 56GB by 1GB so it ends up at 55GB.
Here's how I will get this done:
First, I reduce the file system by 2GB:
Here's the file system before resizing:
Here's the command to reduce it by 2GB:
And here it is after the resizing command completes:
You can see the space actually used by data is 21.80GiB and the filesytem currently occupies 30.02Gib of the available 53.90GiB. This illustrates what I meant by BTRFS not being "attached" to the partition. The partition remains 55.90GiB, at this moment, the file system can add data up to it's sze of 53.90GiB, currently the file system is only using 30.02GiB of it's available space, and data fills only 21.80GiB. All of this occurs without user instruction, but it's interesting to take note of.
Now I need to shrink the partition by 1GB. I use GPT partition table formatting so I can use gdisk or parted to resize the partition. If you're still using MBR partition table formatting, you can use fdisk instead of gdisk.
The steps for using gdisk or fdisk are the same:
Delete the old partition
Recreate the new partition starting at the same sector but ending at a new sector to create a smaller partition (you can use size to automatically select the ending sector needed to achieve your desired size).
Save the partition table.
With parted, you can actually issue a re-size command. Here's what that looks like:
The commands I used were select, print, resizepart, print, and of course quit. You can start parted on the correct disk by launching it with the drive device like parted /dev/sdb and avoid using the select command if you wish.
The resizepart command prompts you through the steps and makes it pretty easy to reduce the partition size (by 1GB in this example) and the print command lets me see the partition sizes before and after the resize.
I suggest you use the help command and have a look at the available commands of this very useful tool.
Now that I reduced the partition size, I ran the partprobe command to force the kernel to re-read the partition tables. If it completes without error, I am good to go to resize the file system again without rebooting.
So now I simply remount /dev/sdb2 and run the resize command again using the "max" parameter;
and when it's doen we check the size:
So now I can see that I've reduced it's size by exactly 1GB. Notice here that while the amount of bytes used for data is the same as before - 21.80GiB - the file system size is smaller both in total size and allocated space. The resize process ended with less total space allocated than before - 28.02GiB vs 30.02GiB - as well as a smaller total size, but the total size reduction was 1GB vs. 2GB taken out of the allocated size. Another interesting but transparent effect of the BTRFS file system.
Since this file system was less than half full and the reduction was so small, all these commands completed almost immediately. If you were working on a larger partition with more data, it might take longer. Whatever you do, don't begin the partition resizing until you are sure the file system resizing is complete. The resizing command should not exit (return the command prompt) until it's done but a check of iotop isn't a bad idea before proceeding. Launch iotop in a second terminal and look for the busiest thread that's doing all the I/O that's not a kworker/something.
A final comment: You are only as good as your last backup. Don't ever muck about with a file system or partition table without a good, current, and usable backup!
[#]btrfs[/#]
The latest versions of GParted can handle this, but if you want to learn the command line way - or if you're working on a remote server with no available desktop like me - continue reading...
If you're new to btrfs, one interesting feature is that most file system level commands are done while the file system is mounted! This is a surprise to new btrfs users. This means you can continue to use the file system while acting on it - expanding, shrinking, balancing (a btrfs feature to reclaim space and better distribute data), defrag-ing, and more - all done while still using the file system. However, this does not hold true when resizing the partition itself - that still requires it to be unmounted.
Expanding a BTRFS file system is fairly straight forward: expand the partition in any manner that you like and then tell btrfs to grow to fill the new size (use your btrfs file system mount in place of /mnt);
sudo btrfs filesystem resize max /mnt
That's about it for expanding. BTRFS will automagically fill the partition to it's maximum size.
However, Shrinking a partition with BTRFS on it; you must first shrink the file system, then resize the partition. The hard part is: How to you exactly determine how much to shrink the partition after shrinking the file system?
There is a command to determine the number of bytes used by a btrfs file system while mounted. Here's one of mine:
Code:
[FONT=monospace][COLOR=#000000]root@server:~# btrfs filesystem usage --raw /mnt/sdb2 [/COLOR] Overall: Device size: 60021411840 Device allocated: 31163678720 Device unallocated: 28857733120 Device missing: 0 Used: 24151150592 Free (estimated): 30882480128 (min: 16453613568) Data ratio: 1.00 Metadata ratio: 2.00 Global reserve: 251658240 (used: 0) Data,single: Size:24704450560, Used:22679703552 /dev/sdb2 24704450560 Metadata,DUP: Size:3221225472, Used:735707136 /dev/sdb2 6442450944 System,DUP: Size:8388608, Used:16384 /dev/sdb2 16777216 Unallocated: /dev/sdb2 28857733120 [/FONT]
**Pro Tip** BTRFS commands can be shortened to the least number of unambiguous letters in the command. So "btrfs filesystem usage" can be shortened to "btrfs f u" instead, since there are no other commands starting with "f" or "u".
But when I reduce my partition, the tools for this (fdisk, gdisk or parted) use sectors not bytes. So now we must determine exactly how many bytes are in each sector so we know how many sectors we can reduce the partition by. These numbers are quite large and if I mess up here, I risk losing the entire file system.
Thank goodness there is a safer and easier way to accomplish this task in three steps:
- Shrink the file system to a smaller size than eventually needed.
- Shrink the partition to the desired target size, but not as small as the BTRFS file system.
- Expand the BTRFS file system to fill the new partition size.
I want to shrink my BTRFS file system and partition from it's current 56GB by 1GB so it ends up at 55GB.
Here's how I will get this done:
First, I reduce the file system by 2GB:
Here's the file system before resizing:
Code:
[FONT=monospace][COLOR=#000000]root@server:~# btrfs filesystem show /mnt/sdb2[/COLOR] Label: 'first_backup' uuid: b10bea4a-54dc-4174-ac5c-f278a3164606 Total devices 1 FS bytes used 21.80GiB devid 1 size 55.90GiB used 30.02GiB path /dev/sdb2[/FONT]
Code:
[FONT=monospace][COLOR=#000000]root@server:~# btrfs filesystem resize -2g /mnt/sdb2[/COLOR] Resize '/mnt/sdb2' of '-2g'[/FONT]
Code:
[FONT=monospace][COLOR=#000000]root@server:~# btrfs fi sh /mnt/sdb2[/COLOR] Label: 'first_backup' uuid: [/FONT][COLOR=#333333]b10bea4a-54dc-4174-ac5c-f278a3164606[/COLOR][FONT=monospace] [/FONT][FONT=monospace] Total devices 1 FS bytes used 21.80GiB devid 1 size 53.90GiB [/FONT][FONT=monospace]used 30.02GiB[/FONT][FONT=monospace] path /dev/sdb2[/FONT]
Now I need to shrink the partition by 1GB. I use GPT partition table formatting so I can use gdisk or parted to resize the partition. If you're still using MBR partition table formatting, you can use fdisk instead of gdisk.
The steps for using gdisk or fdisk are the same:
Delete the old partition
Recreate the new partition starting at the same sector but ending at a new sector to create a smaller partition (you can use size to automatically select the ending sector needed to achieve your desired size).
Save the partition table.
With parted, you can actually issue a re-size command. Here's what that looks like:
Code:
[FONT=monospace][COLOR=#000000]root@server:~# parted [/COLOR] GNU Parted 2.3 Using /dev/sda Welcome to GNU Parted! Type 'help' to view a list of commands. (parted) select /dev/sdb Using /dev/sdd (parted) print Model: ATA WDC WD2002FAEX-0 (scsi) Disk /dev/sdb: 2000GB Sector size (logical/physical): 512B/512B Partition Table: gpt Number Start End Size File system Name Flags 1 17.4kB 1049kB 1031kB BIOS boot partition bios_grub 2 1049kB 60.0GB 60.0GB btrfs Linux filesystem 3 60.0GB 2000GB 1940GB btrfs Linux filesystem (parted) resizepart Partition number? 2 End? [60.0GB]? 59.0GB Warning: Shrinking a partition can cause data loss, are you sure you want to continue? Yes/No? y (parted) print Model: ATA WDC WD2002FAEX-0 (scsi) Disk /dev/sdb: 2000GB Sector size (logical/physical): 512B/512B Partition Table: gpt Number Start End Size File system Name Flags 1 17.4kB 1049kB 1031kB BIOS boot partition bios_grub 2 1049kB 59.0GB 59.0GB btrfs Linux filesystem 3 60.0GB 2000GB 1940GB btrfs Linux filesystem (parted) quit Information: You may need to update /etc/fstab. [/FONT]
The resizepart command prompts you through the steps and makes it pretty easy to reduce the partition size (by 1GB in this example) and the print command lets me see the partition sizes before and after the resize.
I suggest you use the help command and have a look at the available commands of this very useful tool.
Now that I reduced the partition size, I ran the partprobe command to force the kernel to re-read the partition tables. If it completes without error, I am good to go to resize the file system again without rebooting.
So now I simply remount /dev/sdb2 and run the resize command again using the "max" parameter;
Code:
[FONT=monospace][COLOR=#000000]root@server:~# mount /dev/sdb2 /mnt/sdb2[/COLOR] root@server:~# btrfs filesystem resize max /mnt/sdb2 Resize '/mnt/sdb2' of 'max' root@server:~# [/FONT]
Code:
[FONT=monospace][COLOR=#000000]root@server:~# btrfs fi sh /mnt/sdb2[/COLOR] Label: 'first_backup' uuid: b10bea4a-54dc-4174-ac5c-f278a3164606 Total devices 1 FS bytes used 21.80GiB devid 1 size 54.95GiB used 28.02GiB path /dev/sdb2[/FONT]
Since this file system was less than half full and the reduction was so small, all these commands completed almost immediately. If you were working on a larger partition with more data, it might take longer. Whatever you do, don't begin the partition resizing until you are sure the file system resizing is complete. The resizing command should not exit (return the command prompt) until it's done but a check of iotop isn't a bad idea before proceeding. Launch iotop in a second terminal and look for the busiest thread that's doing all the I/O that's not a kworker/something.
A final comment: You are only as good as your last backup. Don't ever muck about with a file system or partition table without a good, current, and usable backup!
[#]btrfs[/#]
Comment