Announcement

Collapse
No announcement yet.

Resizing a btrfs partition

Collapse
This topic is closed.
X
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    Resizing a btrfs partition

    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:

    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]
    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:
    1. Shrink the file system to a smaller size than eventually needed.
    2. Shrink the partition to the desired target size, but not as small as the BTRFS file system.
    3. 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]
    Here's the command to reduce it by 2GB:
    Code:
    [FONT=monospace][COLOR=#000000]root@server:~# btrfs filesystem resize -2g /mnt/sdb2[/COLOR]
    Resize '/mnt/sdb2' of '-2g'[/FONT]
    And here it is after the resizing command completes:
    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]
    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:
    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 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;
    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]
    and when it's doen we check the size:
    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]
    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[/#]
    Last edited by oshunluvr; Oct 06, 2017, 12:00 PM.

    Please Read Me

    #2
    Excellent!

    Although obvious in the last part of the tutorial, the reader should note that the first appearance of "/mnt/sdb2"
    btrfs filesystem usage --raw /mnt/sdb2

    had to be preceded by
    mount /dev/sdb2 /mnt/sdb2
    as root.
    "A nation that is afraid to let its people judge the truth and falsehood in an open market is a nation that is afraid of its people.”
    – John F. Kennedy, February 26, 1962.

    Comment


      #3
      Originally posted by GreyGeek View Post
      ...the reader should note that the first appearance of "/mnt/sdb2"...
      I added "while mounted" to that reference. Thanks.

      Please Read Me

      Comment

      Working...
      X