TRIM/Discard事情 on RPI4

# このメモを一言で言うと。
RPI4bにubuntu 20.04 LTSを入れて常時サーバ化しているが、デフォルトのインストール設定ではパーティションが8MB単位にアラインされていないことが判明した。このままではおそらくTRIM/Discardが効かないと思われる。
常用しているNILFS2ファイルシステムの標準ブロックサイズがこれまた8MBなので、合わせてみた。


# 背景。
SDcardの長寿命化には TRIM/discardに対応したファイルシステムがいいらしい。ときいて。
ext4でも nilfsともに discardには対応しているらしい。サーバ用途であることもあり、私はnilfs推し。

# lsblk -Dで TRIM/discardにブロックレベルで対応しているかどうか分かるらしい。
<pre>
ubuntu@ubuntu:~$ lsblk -D /dev/mmcblk0
NAME        DISC-ALN DISC-GRAN DISC-MAX DISC-ZERO
mmcblk0            0        8M   455.4G         0
├─mmcblk0p1  7340032        8M   455.4G         0
└─mmcblk0p2  7340032        8M   455.4G         0
</pre>
・・・うん？ ALI(alignment)が非ゼロのやつがいる。
7340032/1024/1024 = 7MB。どうゆうこっちゃ？

# デフォルトのパーティション構成確認
諸事情あって USBアダプタ経由でチェック。
<pre>
ubuntu@ubuntu:~$ sudo fdisk -l /dev/sda
Disk /dev/sda: 57.101 GiB, 62260248576 bytes, 121602048 sectors
Disk model: SD/MMC         
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: 0xab86aefd

Device     Boot  Start       End   Sectors  Size Id Type
/dev/sda1  *      2048    526335    524288  256M  c W95 FAT32 (LBA)
/dev/sda2       526336 121602014 121075679 57.8G 83 Linux
</pre>
確かに、第2パーティションの開始が 1MBずれている。(526336*512B /1024/1024 = 257 = (256+1)MB)
また、どこで判定しているのか不明だが、TRIM/discardの最小単位が8MBらしいので、Offset=7MBは正しい。
さて、どうするか・・・？

# 結論
第１パーティションのサイズを1MB縮めて255MBにする。→ 第2パーティションの開始を256MBにアライン。
<pre>
ubuntu@ubuntu:~$ sudo fdisk -l /dev/mmcblk0
Disk /dev/mmcblk0: 57.101 GiB, 62260248576 bytes, 121602048 sectors
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: 0xab86aefd

Device         Boot  Start       End   Sectors  Size Id Type
/dev/mmcblk0p1        2048    524287    522240  255M  b W95 FAT32
/dev/mmcblk0p2      524288 121602047 121077760 57.8G 83 Linux
</pre>
第１パーティションはしょせんDOS(FAT32)だから、どうでもいいでしょう。
<pre>
ubuntu@ubuntu:~$ lsblk -D /dev/mmcblk0
NAME        DISC-ALN DISC-GRAN DISC-MAX DISC-ZERO
mmcblk0            0        8M   455.4G         0
├─mmcblk0p1  7340032        8M   455.4G         0
└─mmcblk0p2        0        8M   455.4G         0
</pre>

# 備考、考察
- RPI4bのsdcardコントローラがTRIM/Discard対応とは恐れ入った。おそらく RPI3bとかも事情同じと想像。
- USB経由(mass-storageドライバ)ではTRIM非対応の模様。(uasp対応のマイクロSDカードアダプタとかあるのかね？)
- NILFS2は完全な追記型のログ構造化ファイルシステム。デフォルトでは8MB単位で書き込み＆消去(garbage collection)を行うので、アラインメント調整は結構重要、、、なんじゃないかな？

# 追記 -- ラズパイ以外のPCでlsblk -Dをしまくった結果。
- カードリーダーが/dev/mmcblk0に見えている奴はdiscardできそうだ。
    - 古ーいネットブック(DELL mini12)はダメだった。SDカードスロットだがmass storage classに見えてしまう。
    - USB接続のSDカードアダプタは全滅だった。(mass storage class)
    - UAS対応のSDカードリーダ、なんて世の中にないんでしょうか。
- SSDは消去単位が512Bのようだ。(DISC-GRAN)
    - SSDといわれるデバイスはみなウェアレベリングを頑張っているということか。
    - そういえば、TRIMに対応してない(!)SSDが押入れにあったな。。。(未確認)
- NILFS2での消去パターンを確認してみた。
    - 参考：https://sh2.hatenablog.jp/entry/20110123
    - 消去単位が8MBだったが、なぜか16MB単位（まれに32MB）で消去されている。ま、いいけど。
    - ここまでやってみて思ったが、NILFS2なら（ほぼ）完全にシーケンシャルに消去しているので、TRIM/Discardしてもさほど書き込み回数は変わらない気がする。せいぜい2倍？
<pre>
nilfs_cleanerd, sector=98893824, nr_sects=32768, return=0 (49446912 - 49463295 KiB)
nilfs_cleanerd, sector=98926592, nr_sects=32768, return=0 (49463296 - 49479679 KiB)
nilfs_cleanerd, sector=98959360, nr_sects=32768, return=0 (49479680 - 49496063 KiB)
nilfs_cleanerd, sector=98992128, nr_sects=32768, return=0 (49496064 - 49512447 KiB)
nilfs_cleanerd, sector=99024896, nr_sects=32768, return=0 (49512448 - 49528831 KiB)
</pre>