50Mのディスクに何バイトのファイルが置けるかな？

#TL;DR 物理容量と有効容量とユーザー容量を分けて考えよう

下手すると、1000Gの物理ディスクでも840Mぐらいしかデータ置けないかもよ！

#はじめに

「50Mのデータ領域を確保しておいて」と言われたとき、人は何をするべきなのか。

`dd if=/dev/zero of=tmp.img bs=1M count=50 ` で、
`mkfs.ext4 tmp.img`して、
`sudo mount -t ext4 -o loop tmp.img ./tmptmp` か？

## すなおにファイルを作ってやってみる。

では、普通にファイルを作って、availableを確認してみよう。

```bash
kmtr@ubuntu2010:~$  dd if=/dev/zero of=tmp.img bs=1M count=50

50+0 レコード入力
50+0 レコード出力
52428800 bytes (52 MB, 50 MiB) copied, 6.359 s, 8.2 MB/s
kmtr@ubuntu2010:~$
kmtr@ubuntu2010:~$ mkfs.ext4 tmp.img
mke2fs 1.45.6 (20-Mar-2020)
Discarding device blocks: done
Creating filesystem with 12800 4k blocks and 12800 inodes

Allocating group tables: done
Writing inode tables: done
Creating journal (1024 blocks): done
Writing superblocks and filesystem accounting information: done

kmtr@ubuntu2010:~$ sudo mount -t ext4 -o loop tmp.img tmp
tmp.img  tmptmp/
kmtr@ubuntu2010:~$ sudo mount -t ext4 -o loop tmp.img tmptmp/
kmtr@ubuntu2010:~$ df -B1 tmptmp
Filesystem     1B-blocks  Used Available Use% Mounted on
/dev/loop9      46579712 49152  42860544   1% /home/kmtr/tmptmp
```

結果、52428800 bytesのディスクイメージで確保サイズは46,579,712 Byteになってしまった。
実際に利用できるAvailableに至っては、42,860,544 Byte。おお・・・神よ…。

# 予約領域を解放する

少しでも認識に近づけるために、Reserved block countを0にしよう。

```bash
root@ubuntu2010:/home/kmtr# tune2fs -l test2.img  | grep "Reserved block count" -A3 -B3
Filesystem OS type:       Linux
Inode count:              12800
Block count:              12800
Reserved block count:     640
Free blocks:              11360
Free inodes:              12789
First block:              0
```

```bash

tune2fs -m 0 test.img

root@ubuntu2010:/home/kmtr# tune2fs -l test.img  | grep "Reserved block count" -A3 -B3
Filesystem OS type:       Linux
Inode count:              12800
Block count:              12800
Reserved block count:     0
Free blocks:              11360
Free inodes:              12789
First block:              0

root@ubuntu2010:/home/kmtr/tmptmp# df . -B1
Filesystem     1B-blocks  Used Available Use% Mounted on
/dev/loop9      46579712 49152  45481984   1% /home/kmtr/tmptmp
```

Availableが、`42,860,544` から `45,481,984` に増えている！

640 block ✕ 4096 = 2,621,440 Bytesなのでちょうど計算も合ってる。

ただし、この予約領域サイズはdisk fullになってもrootが処理できるように確保しているらしいから、むやみやたら減らしてもいいものではない。


# 20Mのファイルを置くのに、何バイト使うのか？
では、このtmptmpの上で20MBのファイルを作るとUsedはどうなるのか？

```bash
root@ubuntu2010:/home/kmtr# df -k tmptmp -B1
Filesystem     1B-blocks  Used Available Use% Mounted on
/dev/loop9      46579712 49152  45481984   1% /home/kmtr/tmptmp
root@ubuntu2010:/home/kmtr# dd if=/dev/zero of=tmptmp/20M bs=1M count=20
20+0 レコード入力
20+0 レコード出力
20971520 bytes (21 MB, 20 MiB) copied, 0.0206479 s, 1.0 GB/s
root@ubuntu2010:/home/kmtr# df -k tmptmp -B1
Filesystem     1B-blocks     Used Available Use% Mounted on
/dev/loop9      46579712 21090304  24440832  47% /home/kmtr/tmptmp
```

Availableは、45,481,984 から 24,440,832 に減少した。 つまり、21,440,832 byte消費された。これは、20,971,520 byteのファイルを作っているのに対して、469,312 byte だけ管理領域が使われていると…。これが約2.2%弱と。

この管理に必要なサイズをざっくり3%と見積もれば、実際におけるファイルサイズは、45481984 / 1.03 = 44,157,266 ってなりますね

まあこれは当たり前で、ファイルを管理するのにデータが全く要らないわけがないと。

# まとめ：物理容量と有効容量とユーザー容量を分けて考えよう

ここまでに出てきた数値をまとめると、下表になる。
これにジャーナルの大きさとかもあるからなあ……　ということも踏まえつつ。

|  | 50M確保したときの容量 | 物理容量に対する割合| 備考 |
|:-:|:-:|:-:|:-:|
| 物理容量  | 52,428,800 | 100% | 外見のサイズ  |
| 有効容量  | 42,860,544 | 81.75% | Available / 予約領域5%  |
| 有効容量  | 45,481,984 | 86.75% | Available / 予約領域0%  |
| ユーザ容量 | 44,157,266 | 84.22% | ユーザーが置けるデータサイズ(※１） / 予約領域0% |

※１：管理領域に用いられるオーバーヘッドを、ざっくり3%と見積もっている。

ということで、50Mのデータ領域を確保しておくには、ざっくり、50M / 0.85 = 58M くらい確保しないとダメなんじゃないかな？

```bash
root@ubuntu2010:/home/kmtr# dd if=/dev/zero of=tmp3.dat bs=1M count=58
mkfs.ext4 tmp3.dat
tune2fs -m 0 tmp3.dat
sync
mount -t ext4 -o loop tmp3.dat tmptmp
58+0 レコード入力
58+0 レコード出力
60817408 bytes (61 MB, 58 MiB) copied, 0.0681551 s, 892 MB/s
root@ubuntu2010:/home/kmtr# mkfs.ext4 tmp3.dat
df -B1 tmptmpmke2fs 1.45.6 (20-Mar-2020)
Discarding device blocks: done
Creating filesystem with 14848 4k blocks and 14848 inodes

Allocating group tables: done
Writing inode tables: done
Creating journal (1024 blocks): done
Writing superblocks and filesystem accounting information: done

root@ubuntu2010:/home/kmtr# tune2fs -m 0 tmp3.dat
tune2fs 1.45.6 (20-Mar-2020)
Setting reserved blocks percentage to 0% (0 blocks)
root@ubuntu2010:/home/kmtr# sync
root@ubuntu2010:/home/kmtr# mount -t ext4 -o loop tmp3.dat tmptmp
root@ubuntu2010:/home/kmtr# df -B1 tmptmp
Filesystem     1B-blocks  Used Available Use% Mounted on
/dev/loop9      54706176 53248  53440512   1% /home/kmtr/tmptmp
root@ubuntu2010:/home/kmtr# dd if=/dev/zero of=tmptmp/50M.dat bs=1M count=50
50+0 レコード入力
50+0 レコード出力
52428800 bytes (52 MB, 50 MiB) copied, 0.0498229 s, 1.1 GB/s
root@ubuntu2010:/home/kmtr# df -B1 tmptmp
Filesystem     1B-blocks     Used Available Use% Mounted on
/dev/loop9      54706176 52641792    851968  99% /home/kmtr/tmptmp
```

ただし、これが10MB ✕ 5 だと…　まあそうなりますわな！

```bash
root@ubuntu2010:/home/kmtr# df -B1 tmptmp
Filesystem     1B-blocks     Used Available Use% Mounted on
/dev/loop9      54706176 52666368    827392  99% /home/kmtr/tmptmp
```

以上になります。