Skip to main content

FS_LOCK

Static FS_LOCK 

Source
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_enginecloud.rs 等)を含め 全て Core 0spawn_on_core で固定された単一プロセス gui_shell_processmain.rs)の実行文脈内でのみ呼ばれており、 Core 1usb_poll_thread。USB/HID ポーリングのみ)・Core 2net_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 と同じ扱いにする。