pub static FS_LOCK: RecoverableMutex<()>Expand description
グローバルなファイルシステムインスタンスを取得
§SMP 安全性についての注記(2026-07-14 調査)
この関数は static mut の生ポインタから &'static mut を無条件に発行
するため、型システム上はマルチコアからの並行呼び出しに対して無防備
(排他ロックを一切持たない)。spec/TODO.md「デバッグ・検証候補」節の
P1 疑いとして監査した結果、get_fs()(および read_file/write_file
等)を実際に呼ぶコードは、kernel/fs/mod.rs 以外の21ファイル
(JS/Aura ビルトイン・各アプリ・web_engine・cloud.rs 等)を含め
全て Core 0 に spawn_on_core で固定された単一プロセス
gui_shell_process(main.rs)の実行文脈内でのみ呼ばれており、
Core 1(usb_poll_thread。USB/HID ポーリングのみ)・Core 2
(net_service_thread。NTP 同期のみ)はいずれもファイルシステムへ
一切アクセスしないことを確認済み。したがって現状のアーキテクチャでは
実際の並行アクセスは発生せず実害は無い。ただし、この安全性は
コンパイラ/型システムが保証するものではなく「今のところ誰も他コアから
呼んでいない」という運用上の不変条件に過ぎないため、今後 FS へ
アクセスするコードを Core 1〜3 側(spawn_on_core の新規呼び出し等)に
追加する場合は、先に排他機構(spin::Mutex 等)の導入を検討すること。
ファイルシステム全体を直列化するロック。
【2026-08-05】上の注記が予告していた事態が実際に起きた。
リソース取得を 4 並列にしたことで、複数のワーカースレッドが
同時に web_engine/cache.rs 経由で FS を触るようになり、
空きセクタビットマップが壊れた。実測の症状:
[SylFS] Failed to read bitmap sector 10
read '...': data sector 19997 unreadable: both primary and mirror corrupted
read_file('...') failed: extent list unreadable
[CACHE] 保存は成功したのに読み返せない key=... bytes=5327688結果として 5.3MB のフォントも 3.7MB の画像もキャッシュに残らず、 毎回 14MB を取り直していた(速度にも直結する)。
get_fs() は &'static mut を返すので、ロックを関数の中へ隠せない
(借用が呼び出し側へ渡るため)。呼び出し側が操作の間だけ保持する。
今後 FS を触るコードを増やすときは必ずこのロックを取ること。
【2026-08-25】以前ここに「現状の取得者は cache.rs だけ」と書いてあり、
その記述が古いまま放置された結果、番人なしで FS を触る箇所が
4 つ増えていた(layout/values.rs の画像サイズ解決、
apps/browser/mod.rs のローカルパス読み込み 2 箇所、
js/builtins/web_forms.rs の localStorage 書き出し)。
とくに最後のひとつは書き込みで、ワーカーの書き込みと重なると
空きセクタビットマップが二重確保され、無関係なファイルが壊れる。
判定の基準は「ブラウザのワーカースレッドと同時に走りうるか」。 ブラウザが動いている間、フォント・画像・ローダの各ワーカーは 常時 FS へ書いている。UI スレッドだから安全、とは言えない。
取得者を個別に数え上げる書き方はまた古くなるので、ここには書かない。
探すときは FS_LOCK を grep し、get_fs() の呼び出しと突き合わせること。
【2026-08-25 バグ修正】ここは素の spin::Mutex だった。
AtmOS は panic = "abort" で巻き戻しが無いので、ロックを持ったまま
パニックするとそのロックは永久に解放されない。だから
#[panic_handler] はヒープ・ネットワーク・USB のロックを
死んだコアから強制的に取り上げている。
FS_LOCK は後から足したためその手当てが漏れていた。
画像ワーカーは os_lib/webp(panic 禁止ポリシーの対象外と
明記されたベンダリング済みデコーダ)を回しながら FS_LOCK を取る。
壊れた WebP 一枚で番人が居座り、以後 OS 全体の FS 操作が
永久に止まる。ネットワークや USB と同じ扱いにする。