104.1 Create partitions and filesystems¶
Weight: 2
Candidates should be able to configure disk partitions and then create filesystems on media such as hard disks. This includes the handling of swap partitions.
Objectives
- Manage MBR and GPT partition tables
- Use various mkfs commands to create various filesystems such as ext2/ext3/ext4, XFS, VFAT, exFAT
- Basic feature knowledge of Btrfs, including multi-device filesystems, compression and subvolumes.
Terms
fdisk, gdisk, parted, mkfs, mkswap
Block devices¶
A block device is a nonvolatile mass storage device whose information can be accessed in any order, like hard disks, USB memories, floppy disks and CD-ROMs. We format these devices into fixed sized blocks.
We can check all block devices using the lsblk command. In addition, in a long ls format (-l), block devices are shown with a b in the first column:
nagato@debianamd:~$ ls /dev/ -l | grep "^b"
brw-rw---- 1 root disk 8, 0 Feb 3 2023 sda
brw-rw---- 1 root disk 8, 16 Feb 3 2023 sdb
brw-rw---- 1 root disk 8, 17 Feb 3 2023 sdb1
brw-rw---- 1 root disk 8, 18 Feb 3 2023 sdb2
brw-rw---- 1 root disk 8, 19 Feb 3 2023 sdb3
brw-rw----+ 1 root cdrom 11, 0 Feb 3 2023 sr0
That b in the first column is the same file type character from 103.3. The grep "^b" filters the listing down to block devices only.
It is possible to create partitions on a block device, splitting it and using it as multiple disks. Systems with old BIOS boot loaders use the Master Boot Record (MBR) method for partitioning, and newer UEFI systems use the GUID Partition Table (GPT) format.
Linux systems use udev to add block devices and their partitions to /dev in the form /dev/sdb1, meaning the second disk (b) and its first partition (1).
/dev/sdb1
|||
||+--- partition number, 1 = first partition
|+---- disk letter, b = second disk
+----- sd = SCSI/SATA disk
The two schemes side by side, which is the heart of this objective:
| MBR | GPT | |
|---|---|---|
| Where the table lives | first sector, the Boot Sector | its own area, with a backup copy |
| Max disk size | 2 TB | no practical limit |
| Max partitions | 4 primary | 128 in the standard table |
| Needs extended partitions | yes, to get past 4 | no |
| Usual firmware | BIOS | UEFI |
| Dates from | PC-DOS 2.0, 1983 | modern UEFI machines |
Editing Partition Tables¶
fdisk¶
fdisk is the main command for viewing, changing and creating partitions on MBR systems. The -l switch lists the partitions:
# fdisk -l /dev/sdb
Disk /dev/sdb: 20 GiB, 21474836480 bytes, 41943040 sectors
Disk model: QEMU HARDDISK
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: 11D48091-5AA7-422A-85F7-A23F476CDFD7
Device Start End Sectors Size Type
/dev/sdb1 2048 1050623 1048576 512M EFI System
/dev/sdb2 1050624 39942143 38891520 18.5G Linux filesystem
/dev/sdb3 39942144 41940991 1998848 976M Linux swap
- The Boot flag shows which partition starts the boot on DOS PCs and has no importance for LILO and GRUB
- Start and End show where this partition is located on the disk.
- Size shows each partition size.
- ID indicates the partition format (82 is swap, 83 is linux data, check all with
lin interactive mode)
Note Disklabel type: gpt in that output. fdisk reads GPT disks fine on modern versions, even though it is the MBR tool by tradition.
It is also possible to run fdisk in interactive mode. m will show you the help menu:
~# fdisk /dev/sda
Welcome to fdisk (util-linux 2.36.1).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.
Device does not contain a recognized partition table.
Created a new DOS disklabel with disk identifier 0xe2dbaded.
Command (m for help): m
Help:
DOS (MBR)
a toggle a bootable flag
b edit nested BSD disklabel
c toggle the dos compatibility flag
Generic
d delete a partition
F list free unpartitioned space
l list known partition types
n add a new partition
p print the partition table
t change a partition type
v verify the partition table
i print information about a partition
Misc
m print this menu
u change display/entry units
x extra functionality (experts only)
Script
I load disk layout from sfdisk script file
O dump disk layout to sfdisk script file
Save & Exit
w write table to disk and exit
q quit without saving changes
Create a new label
g create a new empty GPT partition table
G create a new empty SGI (IRIX) partition table
o create a new empty DOS partition table
s create a new empty Sun partition table
Command (m for help):
Read the greeting again, because it is the most important safety fact about fdisk. Changes stay in memory until you press w. So you can experiment freely and leave with q, and the disk is untouched.
n, d, t, ... ---> changes held in memory only
|
+-------------+-------------+
| |
w q
write to disk throw away
(permanent) (disk untouched)
That said, do not practise on a disk that matters. Use a spare disk or a USB stick.
To check the current partition list, try the p (print) command:
Command (m for help): p
Disk /dev/sdb: 20 GiB, 21474836480 bytes, 41943040 sectors
Disk model: QEMU HARDDISK
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: 11D48091-5AA7-422A-85F7-A23F476CDFD7
Device Start End Sectors Size Type
/dev/sdb1 2048 1050623 1048576 512M EFI System
/dev/sdb2 1050624 39942143 38891520 18.5G Linux filesystem
/dev/sdb3 39942144 41940991 1998848 976M Linux swap
You should remember the disk layout concepts from chapter 102.1. So let's create some partitions using fdisk. I will use n for new:
# fdisk /dev/sda
Welcome to fdisk (util-linux 2.36.1).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.
Device does not contain a recognized partition table.
Created a new DOS disklabel with disk identifier 0x40bd0f72.
Command (m for help): n
Partition type
p primary (0 primary, 0 extended, 4 free)
e extended (container for logical partitions)
Select (default p): p
Partition number (1-4, default 1):
First sector (2048-8388607, default 2048):
Last sector, +/-sectors or +/-size{K,M,G,T,P} (2048-8388607, default 8388607): +1G
Created a new partition 1 of type 'Linux' and of size 1 GiB.
Command (m for help): p
Disk /dev/sda: 4 GiB, 4294967296 bytes, 8388608 sectors
Disk model: QEMU HARDDISK
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x40bd0f72
Device Boot Start End Sectors Size Id Type
/dev/sda1 2048 2099199 2097152 1G 83 Linux
Note the +1G for the last sector. You do not have to calculate sector numbers. Giving a size with K, M, G, T or P after a plus sign lets fdisk work it out.
Let's create another Extended partition and add a Linux (83) and a Swap (82) partition there.
Command (m for help): n
Partition type
p primary (1 primary, 0 extended, 3 free)
e extended (container for logical partitions)
Select (default p): e
Partition number (2-4, default 2):
First sector (2099200-8388607, default 2099200):
Last sector, +/-sectors or +/-size{K,M,G,T,P} (2099200-8388607, default 8388607):
Created a new partition 2 of type 'Extended' and of size 3 GiB.
Command (m for help): p
Device Boot Start End Sectors Size Id Type
/dev/sda1 2048 2099199 2097152 1G 83 Linux
/dev/sda2 2099200 8388607 6289408 3G 5 Extended
Command (m for help): n
All space for primary partitions is in use.
Adding logical partition 5
First sector (2101248-8388607, default 2101248):
Last sector, +/-sectors or +/-size{K,M,G,T,P} (2101248-8388607, default 8388607):
Created a new partition 5 of type 'Linux' and of size 3 GiB.
Command (m for help): p
Device Boot Start End Sectors Size Id Type
/dev/sda1 2048 2099199 2097152 1G 83 Linux
/dev/sda2 2099200 8388607 6289408 3G 5 Extended
/dev/sda5 2101248 8388607 6287360 3G 83 Linux
Notice the jump from partition 2 to partition 5. On an MBR disk, numbers 1 to 4 are reserved for primary partitions, so logical partitions inside an extended one always start at 5.
MBR disk
+----------+--------------------------------+
| sda1 | sda2 (extended, a container) |
| primary | +---------+ +---------+ |
| | | sda5 | | sda6 | |
| | | logical | | logical | |
| | +---------+ +---------+ |
+----------+--------------------------------+
numbers 1-4 = primary, 5 and up = logical
Oh, I forgot to allocate space for the swap partition. Let's delete the previous one and add two new ones:
Command (m for help): d
Partition number (1,2,5, default 5): 5
Partition 5 has been deleted.
Command (m for help): n
All space for primary partitions is in use.
Adding logical partition 5
First sector (2101248-8388607, default 2101248):
Last sector, +/-sectors or +/-size{K,M,G,T,P} (2101248-8388607, default 8388607): +1G
Created a new partition 5 of type 'Linux' and of size 1 GiB.
Command (m for help): p
Device Boot Start End Sectors Size Id Type
/dev/sda1 2048 2099199 2097152 1G 83 Linux
/dev/sda2 2099200 8388607 6289408 3G 5 Extended
/dev/sda5 2101248 4198399 2097152 1G 83 Linux
Command (m for help): n
All space for primary partitions is in use.
Adding logical partition 6
First sector (4200448-8388607, default 4200448):
Last sector, +/-sectors or +/-size{K,M,G,T,P} (4200448-8388607, default 8388607):
Created a new partition 6 of type 'Linux' and of size 2 GiB.
And now I have to change the type of partition 6 to swap:
Command (m for help): t
Partition number (1,2,5,6, default 6): 6
Hex code or alias (type L to list all): L
00 Empty 24 NEC DOS 81 Minix / old Lin bf Solaris
01 FAT12 27 Hidden NTFS Win 82 Linux swap / So c1 DRDOS/sec (FAT-
02 XENIX root 39 Plan 9 83 Linux c4 DRDOS/sec (FAT-
03 XENIX usr 3c PartitionMagic 84 OS/2 hidden or c6 DRDOS/sec (FAT-
04 FAT16 <32M 40 Venix 80286 85 Linux extended c7 Syrinx
05 Extended 41 PPC PReP Boot 86 NTFS volume set da Non-FS data
06 FAT16 42 SFS 87 NTFS volume set db CP/M / CTOS / .
07 HPFS/NTFS/exFAT 4d QNX4.x 88 Linux plaintext de Dell Utility
08 AIX 4e QNX4.x 2nd part 8e Linux LVM df BootIt
0b W95 FAT32 51 OnTrack DM6 Aux a0 IBM Thinkpad hi ea Linux extended
0c W95 FAT32 (LBA) 52 CP/M a5 FreeBSD eb BeOS fs
0e W95 FAT16 (LBA) 53 OnTrack DM6 Aux a6 OpenBSD ee GPT
0f W95 Ext'd (LBA) 54 OnTrackDM6 a7 NeXTSTEP ef EFI (FAT-12/16/
83 Linux 65 Novell Netware af HFS / HFS+ fd Linux raid auto
Aliases:
linux - 83
swap - 82
extended - 05
uefi - EF
raid - FD
lvm - 8E
linuxex - 85
Hex code or alias (type L to list all): swap
Changed type of partition 'Linux' to 'Linux swap / Solaris'.
Command (m for help): p
Disk /dev/sda: 4 GiB, 4294967296 bytes, 8388608 sectors
Disklabel type: dos
Disk identifier: 0x40bd0f72
Device Boot Start End Sectors Size Id Type
/dev/sda1 2048 2099199 2097152 1G 83 Linux
/dev/sda2 2099200 8388607 6289408 3G 5 Extended
/dev/sda5 2101248 4198399 2097152 1G 83 Linux
/dev/sda6 4200448 8388607 4188160 2G 82 Linux swap / Solaris
The two codes to memorise for the exam are in that list: 83 is Linux and 82 is Linux swap. Modern fdisk also accepts the aliases, so typing swap works as well as 82.
An important warning: do not confuse the partition type with the filesystem on it. They used to line up, but no longer do. A type 83 partition can hold ext4, XFS, Btrfs or anything else. The type code is only a hint to the operating system.
Satisfied! Let's verify and then write the results:
Command (m for help): v
No errors detected.
Remaining 4094 unallocated 512-byte sectors.
Command (m for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.
root@debianamd:~# fdisk -l /dev/sda
Disk /dev/sda: 4 GiB, 4294967296 bytes, 8388608 sectors
Disk model: QEMU HARDDISK
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x40bd0f72
Device Boot Start End Sectors Size Id Type
/dev/sda1 2048 2099199 2097152 1G 83 Linux
/dev/sda2 2099200 8388607 6289408 3G 5 Extended
/dev/sda5 2101248 4198399 2097152 1G 83 Linux
/dev/sda6 4200448 8388607 4188160 2G 82 Linux swap / Solaris
Two more fdisk details. F shows unallocated space:
Command (m for help): F
Unpartitioned space /dev/sdd: 881 MiB, 923841536 bytes, 1804378 sectors
Units: sectors of 1 * 512 = 512 bytes
Start End Sectors Size
1050624 2099199 1048576 512M
3147776 3903577 755802 369M
And a trap worth knowing. Those two free blocks add up to 881 MB, but a new 700 MB partition still fails:
Command (m for help): n
Last sector, +/-sectors or +/-size{K,M,G,T,P} (1050624-2099199, default 2099199): +700M
Value out of range.
The reason is that a partition has to be contiguous. The largest single gap is only 512 MB, and a new partition cannot reach over partition 3 to use the space beyond it.
Also, deleting an extended partition deletes every logical partition inside it.
gdisk¶
As seen in chapter 102.1, we have used gdisk on GPT machines. It is not that different from fdisk. Let's have a look at its main commands:
root@debianamd:~# gdisk /dev/sda
GPT fdisk (gdisk) version 1.0.6
Warning: Partition table header claims that the size of partition table
entries is 0 bytes, but this program supports only 128-byte entries.
Adjusting accordingly, but partition table may be garbage.
Partition table scan:
MBR: MBR only
BSD: not present
APM: not present
GPT: not present
***************************************************************
Found invalid GPT and valid MBR; converting MBR to GPT format
in memory. THIS OPERATION IS POTENTIALLY DESTRUCTIVE! Exit by
typing 'q' if you don't want to convert your MBR partitions
to GPT format!
***************************************************************
Command (? for help): ?
b back up GPT data to a file
c change a partition's name
d delete a partition
i show detailed information on a partition
l list known partition types
n add a new partition
o create a new empty GUID partition table (GPT)
p print the partition table
q quit without saving changes
r recovery and transformation options (experts only)
s sort partitions
t change a partition's type code
v verify disk
w write table to disk and exit
x extra functionality (experts only)
? print this menu
As you can see, the partition table has to be compatible with your BIOS/UEFI setup.
The commands are deliberately the same as fdisk: p print, n new, d delete, t type, w write, q quit. The help key is ? instead of m.
This is what a GPT partition table looks like from gdisk:
Command (? for help): p
Disk /dev/sdb: 3903578 sectors, 1.9 GiB
Model: DataTraveler 2.0
Sector size (logical/physical): 512/512 bytes
Disk identifier (GUID): AB41B5AA-A217-4D1E-8200-E062C54285BE
Partition table holds up to 128 entries
Main partition table begins at sector 2 and ends at sector 33
First usable sector is 34, last usable sector is 3903544
Partitions will be aligned on 2048-sector boundaries
Total free space is 1282071 sectors (626.0 MiB)
Number Start (sector) End (sector) Size Code Name
1 2048 2099199 1024.0 MiB 8300 Linux filesystem
2 2623488 3147775 256.0 MiB 8300 Linux filesystem
Three differences from fdisk output stand out:
- Each disk has a unique GUID, a random 128 bit number. It is used to identify a filesystem at boot time without depending on a device path like
/dev/sdb, which can change. - It says the table holds up to 128 entries. That is why GPT needs no extended or logical partitions at all.
- Free space is printed on the last line, so there is no need for the
Fcommand.
The type codes differ too. On GPT they are four digits, so 8300 is Linux filesystem and 8200 is Linux swap, matching the MBR 83 and 82.
GPT also allows partitions to be renumbered with s to close gaps. Delete partition 2 out of three, press s, and the old partition 3 becomes partition 2.
Because GPT keeps a backup copy of its header and table, gdisk has a recovery menu under r. From there, b and c rebuild a corrupt main header or table from the backup, d and e rebuild the backup from the main copy, and f and g convert between MBR and GPT.
parted¶
parted is the GNU tool to edit partitions. Its main advantage is the ability to resize currently defined partitions, but using it is a bit trickier than fdisk and gdisk:
# parted
GNU Parted 3.4
Using /dev/sda
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) help
align-check TYPE N check partition N for TYPE(min|opt) alignment
help [COMMAND] print general help, or help on COMMAND
mklabel,mktable LABEL-TYPE create a new disklabel (partition table)
mkpart PART-TYPE [FS-TYPE] START END make a partition
name NUMBER NAME name partition NUMBER as NAME
print [devices|free|list,all|NUMBER] display the partition table, available devices, free space, all found partitions, or a particular partition
quit exit program
rescue START END rescue a lost partition near START and END
resizepart NUMBER END resize partition NUMBER
rm NUMBER delete partition NUMBER
select DEVICE choose the device to edit
disk_set FLAG STATE change the FLAG on selected device
disk_toggle [FLAG] toggle the state of FLAG on selected device
set NUMBER FLAG STATE change the FLAG on partition NUMBER
toggle [NUMBER [FLAG]] toggle the state of FLAG on partition NUMBER
unit UNIT set the default unit to UNIT
version display the version number and copyright information of GNU Parted
Two warnings that matter a great deal here.
First, parted writes changes immediately. There is no w step and no safe q escape. This is the opposite of fdisk and gdisk.
fdisk / gdisk parted
--------------- --------------------
change change -> written to disk NOW
change change -> written to disk NOW
w = commit
q = cancel there is no cancel
Second, running parted with no device name selects the primary disk, usually /dev/sda, automatically. Always name the device.
Getting information. print shows the current disk, print devices lists all disks, print free includes the gaps:
(parted) print
Model: ATA CT120BX500SSD1 (scsi)
Disk /dev/sda: 120GB
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Disk Flags:
Number Start End Size Type File system Flags
1 2097kB 116GB 116GB primary ext4
2 116GB 120GB 4295MB primary linux-swap(v1)
(parted) print free
Number Start End Size Type File system Flags
32.3kB 2097kB 2065kB Free Space
1 2097kB 116GB 116GB primary ext4
116GB 116GB 512B Free Space
2 116GB 120GB 4295MB primary linux-swap(v1)
120GB 120GB 2098kB Free Space
Creating a partition table with mklabel. Note that parted calls MBR by its old name, msdos:
Creating a partition with mkpart PARTTYPE FSTYPE START END:
The single most confusing thing about parted is that END is not a size. It is the position on the disk where the partition finishes, counted from the start of the disk:
fdisk: last sector +1G means "make it 1 GB big"
parted: mkpart ... 1m 100m means "end at the 100 MB mark"
Also, parted does not create the filesystem. The FSTYPE just sets a flag saying what kind of data to expect.
rm NUMBER deletes a partition. If you delete one by mistake, rescue START END scans that area and offers to put it back:
(parted) rescue 90m 210m
Information: A ext4 primary partition was found at 99.6MB -> 200MB.
Do you want to add it to the partition table?
Yes/No/Cancel? y
rescue only finds partitions that had a filesystem on them. Empty partitions are invisible to it.
Resizing is what parted is really for, with resizepart NUMBER END:
But the partition is only half the job. The filesystem inside it also has to be resized, and for ext2/3/4 that is resize2fs:
$ sudo resize2fs /dev/sdb3
resize2fs 1.44.6 (5-Mar-2019)
Resizing the filesystem on /dev/sdb3 to 146212 (1k) blocks.
The filesystem on /dev/sdb3 is now 146212 (1k) blocks long.
$ df -h /dev/sdb3
Filesystem Size Used Avail Use% Mounted on
/dev/sdb3 135M 1.6M 123M 2% /media/carol/part3
The order matters and getting it wrong destroys data:
GROWING SHRINKING
1. resizepart (bigger) 1. resize2fs (smaller)
2. resize2fs (bigger) 2. resizepart (smaller)
the rule: the filesystem must never be
larger than the partition holding it
The partition must also be unmounted while resizing, and there has to be free space right after it to grow into. resize2fs -M shrinks a filesystem to the smallest size its files allow.
hint? use gparted¶
The gparted tool is a graphical tool to manage your partitions. It has the ability to resize partitions and is super easy to use. It is not part of the LPIC exam but it is good to know about it, just in case. See gparted.org
Formatting the partition¶
Filesystems¶
After you have partitioned your block devices, you have to format them to make them usable to store files and directories. Formatting a file system creates a map which stores the location and name of files and directories, and makes it possible to move files between folders, delete them or rename them. Think of it as the index of a book.
There are several filesystems in the linux world, but these are the most commonly used ones:
| Format | Description |
|---|---|
| ext2 | second extended filesystem was developed to address shortcomings in the older Unix/Minix filesystem used in early versions of Linux. It has been used extensively on Linux for many years. There is no journaling in ext2, and it has largely been replaced by ext3 and more recently ext4. |
| ext3 | ext2 + journaling, max file size is 2TB and max filesystem size is 16TB |
| ext4 | current version of ext, max file size is 16TB and max filesystem size is 1EB (1000*1000TB) |
| XFS | journaling, caches to RAM, great for uninterruptible power supplies, Max file and filesystem size is 8EB |
| swap | Swap is used when the system needs to use more ram than it has. It is like extra ram on disk |
| VFAT | FAT32, no journaling, good for data exchange with windows, does not understand permissions and symbolic links |
| exFAT | Extended FAT. A newer version of FAT which is used mainly for extended devices which should work on all machines, like USB disks |
| btrfs | A new high performance file system. Max file and filesystem size is 16 EB. Has its own form of RAID and LVM and built-in snapshots and fault tolerance and data compression on the fly. |
The word journaling appears three times in that table and is the key idea. A journal is a log the filesystem writes before it makes a change. If the power fails halfway through, the system reads the journal on the next boot and finishes or undoes the change, instead of leaving the disk in a broken state. That is the main reason ext3 replaced ext2.
Several details per filesystem:
- XFS was made by Silicon Graphics in 1993 for IRIX, and is common on servers needing high, guaranteed throughput. Red Hat Enterprise Linux 7 uses it by default. Its journal, called the log section, normally sits inside the data section but can be put on a separate disk for speed.
- VFAT is FAT16 extended to support long file names up to 255 characters. FAT16 tops out at a 4 GB volume and a 2 GB file, FAT32 at a 2 PB volume and a 4 GB file. Both are handled by
mkfs.fat, withmkfs.vfatas an alias. - exFAT was made by Microsoft in 2006 to fix that file size limit, reaching 16 EB per file and 128 PB per disk. Windows, Linux and macOS all support it, which is why the SD Association picked it as the default for SDXC cards over 32 GB.
- Btrfs has been developed since 2007 by Oracle and others. It is copy-on-write: when you change part of a file, the new data is written to free space first, the metadata is then pointed at the new data, and only then is the old data released. Nothing is overwritten in place, so a crash mid-write cannot corrupt the file.
Creating filesystems¶
You can format your partitions with the mkfs command, and mkswap for swap. This is a front end to commands like mkfs.ext3 for ext3, mkfs.ext4 for ext4 and mkfs.reiserfs for ReiserFS. The full list installed on your system is here:
# ls /sbin/mk*
/sbin/mkdosfs /sbin/mkexfatfs /sbin/mkfs.bfs /sbin/mkfs.exfat /sbin/mkfs.ext3 /sbin/mkfs.fat /sbin/mkfs.msdos /sbin/mkfs.vfat /sbin/mkinitramfs /sbin/mkntfs
/sbin/mke2fs /sbin/mkfs /sbin/mkfs.cramfs /sbin/mkfs.ext2 /sbin/mkfs.ext4 /sbin/mkfs.minix /sbin/mkfs.ntfs /sbin/mkhomedir_helper /sbin/mklost+found /sbin/mkswap
If using mkfs, the main switch is -type (or -t) to specify the format:
# mkfs -t ext4 /dev/sda1
mke2fs 1.46.2 (28-Feb-2021)
Discarding device blocks: done
Creating filesystem with 262144 4k blocks and 65536 inodes
Filesystem UUID: 63625ecd-857a-419f-a300-12395aaad89f
Superblock backups stored on blocks:
32768, 98304, 163840, 229376
Allocating group tables: done
Writing inode tables: done
Creating journal (8192 blocks): done
Writing superblocks and filesystem accounting information: done
root@debianamd:~# mkfs.exfat /dev/sda5
mkexfatfs 1.3.0
Creating... done.
Flushing... done.
File system created successfully.
Read the mkfs -t ext4 output line by line, since it names the parts of an ext filesystem:
262144 4k blocks and 65536 inodes= the space is divided into 4 KB blocks, and there are 65536 inodes, one per file or directory the filesystem can hold.Filesystem UUID: ...= the unique identifier just created for this filesystem.Superblock backups stored on blocks:= copies of the superblock, the master record of the filesystem, kept at several places so a damaged one can be repaired. This comes back in 104.2.Creating journal (8192 blocks)= ext4 is a journaling filesystem, so a journal was made.
An important detail about the ext tools: mkfs.ext2, mkfs.ext3 and mkfs.ext4 are all symbolic links to one program, mke2fs, which changes its defaults based on which name it was called by. So these two lines do the same thing:
The mke2fs options worth knowing, all of which work with mkfs.ext2/3/4 too:
-b SIZEblock size, 1024, 2048 or 4096 bytes-ccheck for bad blocks first, and-c -cfor a slower thorough check-d DIRECTORYpre-populate the new filesystem with the contents of a directory-Fforce, ignoring warnings.-F -Fwill even format a mounted device, which is a very bad idea-L LABELset a volume label, at most 16 characters-na trial run, showing what would happen without doing it-qquiet, for use in scripts-U IDset the UUID, or useclear,randomortime-Vverbose
The -n option is the one to remember for safety. It lets you check a mkfs command before running it for real.
The other filesystems have their own options:
XFS, with mkfs.xfs: -b size=VALUE block size, default 4096; -m crc=1 metadata checksums, on by default; -m uuid=VALUE set the UUID; -f force; -l logdev=DEVICE put the journal on another disk; -l size=10m limit the journal size; -L LABEL label, max 12 characters; -N trial run.
FAT/VFAT, with mkfs.fat: -c check bad blocks; -C FILENAME BLOCK_COUNT create a disk image file rather than formatting a device; -F SIZE pick 12, 16 or 32 for FAT12, FAT16 or FAT32; -n NAME label, max 11 characters; -v verbose. Note that mkfs.fat cannot create a bootable filesystem.
exFAT, with mkfs.exfat: -i VOL_ID volume ID; -n NAME label, max 15 characters; -p SECTOR first sector; -s SECTORS sectors per cluster, must be a power of two.
Btrfs, with mkfs.btrfs, has features the others do not. It takes more than one device at once, spanning the filesystem across them:
# mkfs.btrfs /dev/sdb1
# mkfs.btrfs /dev/sdb1 -L "New Disk"
# mkfs.btrfs -d single -m single /dev/sdb /dev/sdc
-m sets how metadata is spread across the devices, accepting raid0, raid1, raid5, raid6, raid10, single and dup. Btrfs labels can be up to 256 characters. Spanning several disks with single means one disk failing loses all the data, and the risk grows with each disk added.
Subvolumes are filesystems inside a filesystem. Unlike partitions they do not reserve fixed space, they share the free space of the parent and grow as needed:
# btrfs subvolume create /mnt/disk/BKP
$ ls -lh /mnt/disk/
total 0
drwxr-xr-x 1 root root 0 jul 13 17:35 BKP
drwxrwxr-x 1 carol carol 988 jul 13 17:30 Images
A subvolume looks like an ordinary directory but can be mounted on its own:
Snapshots are subvolumes pre-filled with the contents of the volume they came from. They take almost no space at first, because they copy the filesystem tree while still pointing at the same data:
From that point the two diverge. Deleting files from the original leaves them intact inside the snapshot:
$ rm LG-G8S-ThinQ-*
$ ls -lh
-rw-rw-r-- 1 carol carol 109K jul 10 16:22 Galaxy_Note_10.png
-rw-rw-r-- 1 carol carol 484K jul 5 15:01 geminoid2.jpg
drwx------ 1 carol carol 366 jul 13 17:56 snap
$ ls -lh snap/
-rw-rw-r-- 1 carol carol 109K jul 10 16:22 Galaxy_Note_10.png
-rw-rw-r-- 1 carol carol 484K jul 5 15:01 geminoid2.jpg
-rw-rw-r-- 1 carol carol 467K jul 2 11:48 LG-G8S-ThinQ-Mirror-White.jpg
-rw-rw-r-- 1 carol carol 654K jul 2 11:39 LG-G8S-ThinQ-Range.jpg
The two deleted files are still in snap/ and can be restored. Adding -r makes a read-only snapshot, frozen in time.
Compression on Btrfs is transparent and per file, switched on by mounting with -o compress. The default algorithm is ZLIB, with LZO (faster, compresses less) and ZSTD (faster than ZLIB, similar ratio) also available. It detects files that will not compress and leaves them alone, so one directory can hold a mix of compressed and uncompressed files.
If you need to assign a label to the partition, you have to use the -L label_name option. Note that on recent systems people use UUIDs instead of labels. The UUID of a disk can be viewed with:
# blkid /dev/sda1
/dev/sda1: UUID="63625ecd-857a-419f-a300-12395aaad89f" BLOCK_SIZE="4096" TYPE="ext4" PARTUUID="40bd0f72-01"
That UUID is the same one mkfs printed when it created the filesystem. UUIDs matter because device names can move. If you add a disk, today's /dev/sdb1 might be tomorrow's /dev/sdc1, but the UUID never changes. This is why /etc/fstab uses UUIDs, which comes up in 104.3.
And as the last task, let's create a swap on /dev/sda6:
# mkswap /dev/sda6
Setting up swapspace version 1, size = 2 GiB (2144333824 bytes)
no label, UUID=6a59cf20-8fd6-4d86-b044-89f7bc67993b
and then
In chapter 104.3 we will see how we can mount and unmount these filesystems.
The three steps for swap, in order:
1. make the partition, type 82 on MBR or 8200 on GPT
2. mkswap /dev/sda6 prepare it as swap space
3. swapon /dev/sda6 start using it
swapoff with the device name stops using it again.
Linux can also use a swap file instead of a partition. You make an empty file with dd, then treat it exactly like a partition:
$ dd if=/dev/zero of=myswap bs=1M count=1024
1024+0 records in
1024+0 records out
1073741824 bytes (1.1 GB, 1.0 GiB) copied, 7.49254 s, 143 MB/s
# mkswap myswap
Setting up swapspace version 1, size = 1024 MiB (1073737728 bytes)
no label, UUID=49c53bc4-c4b1-4a8b-a613-8f42cb275b2b
# swapon myswap
That dd line is the one from 103.3: if= input, of= output, bs=1M one megabyte blocks, count=1024 of them, giving 1 GB of zeros. The swap file should be owned by root with permissions 0600, or both mkswap and swapon will complain. A swap file set up this way lasts only until reboot unless it is added to /etc/fstab.
Real world use for a swap file: a running server has too little swap and no free partition to spare. A swap file can be created, enabled and removed without touching the partition table at all.
Summary¶
I have a Linux system where a disk has to be partitioned before it can hold anything, and the partition table comes in two forms. MBR is the old scheme, stored in the first sector, limited to 2 TB disks and four primary partitions, which is why extra partitions have to live inside an extended container and get numbered from 5 upward. GPT is the modern scheme used with UEFI, with no practical size limit, room for 128 partitions, a unique GUID per disk and a backup copy of its own table.
I edit MBR tables with fdisk and GPT tables with gdisk, and the two share almost the same keys: p to print, n to add, d to delete, t to change the type, v to verify, w to write and q to leave. Both keep my changes in memory until I press w, so I can back out safely. parted is the third tool and behaves differently in two ways I have to remember: it writes every change immediately with no undo, and its mkpart takes an ending position rather than a size. What parted gives me in return is resizepart, and resizing means resizing the filesystem too, growing the partition first and the filesystem second, but shrinking the filesystem first and the partition second.
Once a partition exists it still needs a filesystem, which I create with mkfs -t TYPE or one of the named forms like mkfs.ext4, mkfs.xfs, mkfs.fat or mkfs.exfat. The ext family are all one program, mke2fs, reached under different names. I pick ext4 for normal Linux use, XFS for servers wanting throughput, VFAT or exFAT when a Windows or macOS machine has to read the disk too, and Btrfs when I want subvolumes, snapshots and transparent compression. Journaling is what separates ext3 and later from ext2, and copy-on-write is what makes Btrfs resilient. Useful options across the tools are -L for a label and -n or -N for a trial run that shows what would happen without touching anything.
Swap is a partition of type 82 on MBR or 8200 on GPT, prepared with mkswap and switched on with swapon, and off again with swapoff. If I have no spare partition I can make a swap file instead, using dd to create an empty file and then treating it exactly like a partition, as long as it is owned by root with permissions 0600. Whether I use a partition or a file, it only survives a reboot once it is listed in /etc/fstab. Finally, every filesystem gets a UUID when it is made, which I can read back with blkid. That UUID is worth using in place of a device path, because /dev/sdb1 can become /dev/sdc1 the moment I add another disk, while the UUID never changes.