Aligning entire LUKS/LVM/Ext4 filesystem stack to 4K sectors

Johnny Dahlberg <[email protected]> Fri, 19 Mar 2021 17:09:01 +0100
Newsgroups gmane.linux.kernel.device-mapper.dm-crypt
Message-ID <CA+3G=9iz_s7de+YW6194nApP2QBWpGduyr3cepxdT_=RGCm6Qg@mail.gmail.com>
Hello everyone!

I'd really like to check if I am missing any steps for setting up a fully
"4K sector" aligned storage stack. If there's anyone who knows the correct
answer, it would be here.

The goal is to have each Ext4 sector mapped exactly to a physical sector on
the SSD. For maximum read/write performance and to have perfectly aligned
TRIM support (yes I know about the minor security issue with encryption and
TRIM, but the SSD lifetime health is way more important to me).

My stack is SSD -> GPT Partition Table -> LUKS encryption -> LVM volume ->
ext4 filesystem, and the whole stack must be aligned to 4096 byte sectors
for this to work.

* Partition Table: Every partition MUST be completely aligned (START and
END) on MiB boundary (the ending alignment is important too since LUKS
can't encrypt partial sectors). Do this by setting GParted's "Align to:
MiB" when creating the partition. As the GParted manual explains, this
forces the partition to START and END on precise MiB boundaries: "Use MiB
alignment for modern operating systems. This setting aligns partitions to
start and end on precise mebibyte (1,048,576 byte) boundaries."

* Use GParted to create a "Filesystem: unformatted" partition. Again, it
must start and end on precise MiB alignment offsets via the "Align to: MiB"
setting.

* Terminal:

# Get device name for the "unformatted" partition, in my case
/dev/nvme0n1p3:
fdisk -l

# Ensure that the encrypted payload starts at 1 MiB (2048 * 512 byte
sectors):
cryptsetup --key-size 256 --type luks2 --sector-size 4096 --align-payload
2048 luksFormat /dev/nvme0n1p3

# Open the LUKS volume and permanently mark it as "allow discards (TRIM) so
that it always opens like that by default:
cryptsetup --allow-discards --persistent open /dev/nvme0n1p3 cryptdata

# Create the LVM volume metadata and enforce "start of payload" alignment
at the nearest 1 MiB boundary after the metadata (by default this means the
payload starts at 1 MiB):
pvcreate -ffy --metadatatype lvm2 --dataalignment 1m --dataalignmentoffset
0 /dev/mapper/cryptdata

# Create the LVM volume group and force it to divide the volume into
aligned 4 MiB chunks (this is the default, but enforcing it just to be
sure):
vgcreate -ffy --physicalextentsize 4m data /dev/mapper/cryptdata

# Create a LVM logical volume using all of the space:
lvcreate -y --name root --extents 100%FREE data

# Format as ext4 with 4096 byte (4 KiB) block size:
mkfs.ext4 -F -b 4096 /dev/mapper/data-root

If all of my research of all man pages and tons of old wikis and guides is
correct, this will create a stack that's completely aligned to 4 KiB
physical sectors.

Is there anything I am missing here, or anything that you would suggest
changing? For example, perhaps I should change "--align-payload 2048" to
"--align-payload 4096" (what would that do/improve?), which I've seen a few
mentions of?

Grateful for any help in clearing this up, or clarifying that my steps are
ready to use. It's been a very long research and I'd like to be sure that I
am doing everything correctly.


With best regards,

Johnny

_______________________________________________
dm-crypt mailing list -- [email protected]
To unsubscribe send an email to [email protected]