タイトル通りの問題が起こって、その原因調査と対応策を調べた話です。


【発生したこと】
自分は公私で Windows を使っています。プログラミング関連の作業をする時は WSL(2) を使って、Ubuntu 環境でコーディング&テスト・動作確認を行っています。プログラミング以外でも面白そうな GitHub リポジトリを見つけては Fork して Clone したりします。なので WSL 内でそれなりにディスク容量を使っていることは自覚しています。

ある頃から Windows が不安定な挙動を見せるようになりました。空きディスク容量がないことが直接の原因なのですが、原因そのものを示すメッセージが出てくれるのはまだいい方で、一時ファイルが作れなくなることでアプリの挙動が不安定になることも珍しくありません(ウェブブラウザや VS Code はこのタイプ)。エクセルやパワポを編集していて、いざ保存しようとしたタイミングで「ディスクが足りない」と言われるのは寿命が縮みます。

根本的な解決策を後回しにしてごまかしていましたが、「WSL で使いすぎ」という自覚はあったので、後ろ髪を引かれる思いでデカいリポジトリ数点をディスクから消しました。ちなみにカレントディレクトリ(例えば ~/src/ ディレクトリ)のサブディレクトリ内で、容量の多いサブディレクトリを調べるには以下のコマンドが便利です(容量の大きいサブディレクトリでソートして表示します):
$ du -h --max-depth=1 | sort -hr

AI で使うバカでかいモデルファイル(ギガバイト単位)を含んだサブディレクトリがあり、それらは「まあ手元になくてもよい」と判断して削除しました。これで Windows のディスク容量不足は解消するはず・・・

・・・だったのですが、再起動して確認しても一向に減っていません。空き容量の数字だけみると「全く変わってない」感じ。え、なんで? 消しただけ損した??


【なぜ空き容量は増えなかったのか?】
実はこれ、WSL の仕様らしいのです。WSL では・・・
・WSL で使うディスクを Windows 内の `ext4.vhdx` というファイルで管理している
・このファイルは WSL にデータを追加していくとデータ量に応じて自動で拡張される
・ただし WSL のデータを削除しても自動では縮小されない
という動きになるらしいです。つまり WSL 内でファイルを削除しても、Windows ファイルとしての `ext4.vhdx` ファイルのサイズは変わりません(ディスク利用率が下がるだけ)。「中で空きが増えても、(それだけだと)外側からみたファイルサイズはそのまま変わらない」ということです。


【WSL で減らした分の空き容量を増やすには】
WSL で削除した分の空き容量を増やすには、`ext4.vhdx` ファイルのサイズを減らす必要があります。ファイルを削除したことで使っていない部分が増えたはずなので、そこを圧縮することで `ext4.vhdx` ファイルを小さくして、Windows の空き容量を増やす、ということです。

その手順を以下に紹介します。Windows Pro で使える簡単な方法と、Windows Home でも使える少し面倒な方法があり、両方紹介します:


(Pro/Home 共通)手順0: WSL のファイルシステムで未使用の部分を破棄する

まずは WSL にログインして以下のコマンドを実行します:
$ sudo fstrim -av

このコマンドでファイルシステムで未使用な部分を破棄します。これにより、この後の作業での圧縮効率が高まります。この手順0は実施しなくても圧縮はできますが、圧縮効率を高めるためのコマンドだと思ってください。


(Pro/Home 共通)手順1: WSL を完全停止

次に Windows のコマンドプロンプト/PowerShell で以下を実行します:
> wsl --shutdown

これで WSL を停止します。なお Docker Desktop などを実行中の場合はそれらも停止して、WSL を完全に停止させておきます。


(Pro/Home 共通)手順2: VHDX ファイルの場所を調べる

圧縮する VHDX ファイル(`ext4.vhdx`)の格納場所はシステムごとに異なります。自分の環境での、このファイルのフルパスを調べておく必要があります。

このコマンドがこちらです。PowerShell で以下を実行します(要は LocalAppData ディレクトリ内で `ext4.vhdx` というファイルを検索するコマンドです):
> Get-ChildItem $env:LOCALAPPDATA -Recurse -Filter ext4.vhdx 2>$null

成功すると以下のような出力になります:
2026060101


上図では一部モザイクにしていますが、

C:\Users\xxxxxx\AppData\Local\Packages\CanonicalGroupLimited.UbuntuonWindows_79rhxxxxxxxxxx\LocalState

というフォルダで `ext4.vhdx` というファイルが見つかった、という結果でした。つまりフルパスだと、
C:\Users\xxxxxx\AppData\Local\Packages\CanonicalGroupLimited.UbuntuonWindows_79rhxxxxxxxxxx\LocalState\ext4.vhdx

というファイルとして見つかったことになります。このフルパスは以下で使います。


ここから先は Windows Pro と Windows Home で手順が異なります:


(Pro)手順3: 管理者権限の PowerShell から VHDX を圧縮

Windows Pro の場合、管理者権限の PowerShell を使って、手順2で見つかった `ext4.vhdx` ファイルを圧縮できます:
> Optimize-VHD -Path "c:\Users\xxxxxx\AppData\Local\Packages\CanonicalGroupLimited.UbuntuonWindows_79rhxxxxxxxxxx\LocalState\ext4.vhdx" -Mode Full

圧縮に少し時間がかかりますが、このコマンドが完了すると Windows の空き容量が増えているはずです。


(Home)手順3: 管理者権限の diskpart コマンドで VHDX を圧縮

Windows Home でも以下のコマンドを順次実行することで手順2で見つかった `ext4.vhdx` ファイルを圧縮できます:
> diskpart

 select vdisk file="C:\Users\xxxxxx\AppData\Local\Packages\CanonicalGroupLimited.UbuntuonWindows_79rhxxxxxxxxxx\LocalState\ext4.vhdx"
 attach vdisk readonly
 compact vdisk
 detach vdisk
 exit



自分のような WSL のヘビーユーザー向け情報でした。