A walkthrough shrinking partitions in Linux
Understanding 4k and 512B blocks
So it’s been a great weekend and I finally got some time off studies amidst those final examinations at college. The devil in my mind popped a random thought from nowhere — ”Let’s dual boot Android x86!” Well well, and it began.
I’m running Arch Linux with KDE on my Alienware 15 on a dual boot with Windows 10 Pro and the system’s got a handsome disk configuration that looks like this — 2 M.2 SSDs and a SATA SSD. I’ve kept the M.2s aside just for operating systems and am running Windows on the bigger 250GB and Arch on the smaller 128GB, the SATA is but a data pool. Now that I’m set on installing Android, the debatable question arises — where am I going to even put it? I need a partition and I’m going to have to create it. Logically speaking, I’ve kept the 128 gig M.2 only for Linux OSes and since Android kernel is Linux so deductive logic has it — that’s where Droid’s going!
The Partition
Getting the partitions right is what makes the game enduring. Creating a partition off Windows is a piece of cake — make a few taps here and there and poof, you’ve got a new shiny partition ready to be put to work! Only if it was that simple with Linux, duh.
Since I’m going to have to create an ext4 partition, I can’t do that natively off Windows and wouldn’t recommend using third party tools either. What am I left with? A bootable media running a live Linux system that would let me accomplish that. There are a bunch out there to choose from but I’d stick to the Arch Live system as it just gives me the degree of manual control that’s arguably safe when it comes to playing around with disks and partitions where you’re solely responsible for your deeds and can’t blame the system like, “hey why’d you rip that EFI volume off?”
So with Arch Linux running of a live media, I’m presented with that monotonous, monochrome zshell prompt. Go ahead and run `fdisk -l` and you’ll see a list of disks connected to your PC and their partitions. I’m looking at /dev/sdc which is my 128GB SSD, right now containing just one volume with Arch installed. I need to squeeze about 16GB off this volume and create a new partition for throwing in Android and that’s the plan on paper.
Running `e2fsck -f /dev/sdc1` on the only volume in that SSD shows me no errors on the filesystem — a great place to start. If you’re coming from Windows, you’ll be perplexed to know that shrinking a volume to create a partition is trifold in Linux! Yeah, you’ve got to shrink the filesystem first, then shrink the volume and finally ‘inform’ the kernel of all changes. Why do you think the laymen prefer Windows? Let’s go ahead and do all that.
Resizing the Filesystem
Since I need to pull 16GB off, I’ve got to shrink the volume to (128–16)GB = 112GB, let’s go ahead and run `resize2fs /dev/sdc1 112G`. Another thing here that a lot of newbies-to-Linux miss — G and GB aren’t the same! A quick detour, for instance 5G converts to bytes as 5*(1024)*(1024)*(1024)B, whereas 5GB converts to bytes as 5*(1000)*(1000)*(1000). This renders the unit GB entirely inaccurate and not beyond a simple cue. Part one, done.
Shrinking the Volume
Now to resize the volume itself (what actually matters to me, us). I’m going to run GNU Parted in interactive mode as `parted` and use the resizepart command for the rest. Use the `print` in the current parted shell session to view all volumes on the current drive and their corresponding IDs — the volume in concern in my case is marked 1.
What matters to me is as simple as getting a 112GB volume at the end of the resizepart command’s execution. But it’s not as simple as running `resizepart 1 112GB` as we just learnt how GB is different from G. Exploring GNU Parted’s unit command, we see that it allows interchangeability of units but let me tell you one thing, things are going to mess up even when the units are in G. Digging in deeper goes beyond the scope of this article so let’s stop here and cut right to the chase.
It’s best to keep things at their lowest complexity and hence let’s shift everything to the blocks unit. (lowest complexity and blocks — is that an oxymoron?) Run in parted interactive `unit s`. Run `print` and you’d see how GNU Parted displays all the start, end sectors and volume size in blocks of 512-byte size. Now I’ve got to convert 112GB to 512B blocks and can do that as,
size_in_512B_blocks = size_in_GB * 2 * 1024 * 1024
Do the math for 112GB in 512B blocks and run in parted interactive `resizepart 1 new_end_value` where,
new_end_value = start_sector (as seen from the print command’s output for the volume) + size_in_512B_blocks_for_112GB
Informing the Kernel — The 4k and 512b block conflict!
Yeah, now for accounting everything to the kernel just as the whining school boy informed his mum everyday. Exit parted interactive by `quit`.
The new resizepart command (from util-linux package) I’m going to be using to inform the kernel is quite different from what we saw in GNU Parted. The third parameter here, isn’t the end sectors but the size of the new shrunken partition (112GB) ‘in blocks’. You’d ask me how’s that so different?
Blocks. Blocks not of 512B that we’d seen. Blocks of 4k sectors as the manual says.
Here’s where a good understanding of the above seen formula is required. The multiplication factor 2 is introduced for standardization. The standard says 1024B for every 1MB, 1024MB for every 1GB and so on. Hence the 512B blocks are standardized by introducing the multiplication factor.
Now we need 112GB in 4k blocks! The manual would leave a layman wandering to understand what 4k really boils down to. But it’s as simple as 4096 and not 4000. That’s the catch.
size_in_4k_blocks = size_in_GB * 1024 * 1024 / 4, since 4096 is 4 times 1024. Now we’ve got the whole thing clear!
I’d inform mother kernel now, by running `resizepart /dev/sdc1 size_in_4k_blocks_for_112GB` and we’re done! Cross check for errors by running `fsck /dev/sdc1` and if you’ve got no errors, bingo.
The Conclusion
It’s already been a documentary of an article for you I suspect, yet I hope this article gives you a grip on how filesystems roughly work in Linux, the trifold method to resize partitions and in the process how to not get lost when resizepart says, “buddy, no…not 512B blocks. It’s 4k…4k-byte blocks. Lost? That’s Linux.”
Thanks for reading!