Windows 秘話バグの力

Raymond Chen

Windows 95 では、 トラブルシューティングのページにアクセスして、[バッファの同期を取らない] チェック ボックスをオンにすることができました。しかし、このチェック ボックスがどのような処理を行い、なぜ用意されたのかをご存知ですか。

MS-DOS® の Commit 関数の正常な動作は、特定のファイルからディスクに書き込まれていないデータをフラッシュすることで、データが書き込まれたことを確認してから制御を戻します。[バッファの同期を取らない] チェック ボックスがオンになっていると、データが書き込まれるまで待機することなく、すぐに制御が戻ります。もちろん、これは機能仕様に違反します。機能仕様では、データが書き込まれるまで制御を戻さないように規定されています。このオプションにより、フラッシュの要求を発行するプログラムで、実際にはデータがディスクに書き込まれていないのに、データがディスクに書き込まれたと判断されるというリスクが増大します。サポート技術情報の記事 139669 では、これを婉曲的に "ファイルの整合性の問題" と呼んでいます。

データベース プログラムでは、ディスク上のファイルの状態がプログラムで予期している状態と一致する時点を確立する目的に、Commit 関数を使用することがあります。更新中にコンピュータの電源が供給されなくなった場合、データベース プログラムでは、最後にコミットを実行した時点で記録されている情報を使用して、データベースの整合性を回復することができます。コミットが完了する前に Commit 関数から制御が戻ると、この整合性のチェックポイントが失われることになります。その結果、データベースが破損します。

不適切な結果が生じるのに、なぜこのオプションが提供されたのでしょうか。その理由は、Windows® 3.11 にあるバグです。

図 1 Windows Server 2003 でバグの動作を有効にする

図 1** Windows Server 2003 でバグの動作を有効にする **(画像を拡大するには、ここをクリックします)

Windows 3.11 では "32 ビット ファイル アクセス" が導入されました。これは、下位レベル ファイル I/O インターフェイスの 32 ビット実装です。しかし、Commit 関数の実装には、ファイル バッファをフラッシュする要求を完全に無視するバグがありました。そのため、ファイル バッファをフラッシュするプログラムを Windows 3.11 で実行すると、フラッシュの呼び出しの効果はありません。その結果、不適切なタイミングでコンピュータの電源供給がなくなると、データベースが破損します。

Windows 95 のファイル システムの開発に携わったメンバが、このバグを修正したところ、新しいバグが報告されるようになりました。ある企業の支払勘定プログラムのパフォーマンスが低下したり、他の企業のデータベース プログラムのパフォーマンスが低下したりするなどの報告を受けました。一体何が起こったのでしょうか。

これらのプログラムでは、フラッシュの呼び出しが絶えず行われていたことが判明しました。プログラマは、Windows 3.11 ではフラッシュの要求が非常に高速に行われることを発見したので、プログラムのあらゆる部分にフラッシュの呼び出しを使用しました。バイトを書き込んではフラッシュし、文字列を書き込んではフラッシュし、という具合です。フラッシュは非常に高速な処理だったので、アプリケーションでは、1 つの操作ごとにデータをコミットしても、パフォーマンスが低下することはありませんでした。しかし、このバグが Windows 95 で修正されたことで、Commit 関数が実際の役割を果たすようになり、このバグに依存したプログラムのパフォーマンスが大幅に低下しました。

もちろん、ファイル システム チームが、この報告に対して何の対策も取らなければ、このようなプログラムのパフォーマンスは依然として低いままで、ユーザーは、Windows 95 に問題があるという勘違いをしてしまったことでしょう。そして、「Windows 95 は動作が遅い」と他の人に話したことでしょう。一方、ファイル システムを以前の Windows 3.11 の動作に戻した場合、前述の厄介な "ファイルの整合性の問題" を引き起こすことになります。

そのため、このバグを修正し、バグの修正によって問題が発生するプログラムを実行しているユーザーのために Windows 3.11 の動作に戻すチェック ボックスを追加するという結論に至りました (とはいうものの、このチェック ボックスはトラブルシューティングのページに用意されています)。

歴史は繰り返されるということが判明しました。Windows Server® 2003 では、I/O の開発メンバが、Forced Unit Access (FUA) としてタグ付けされている要求が、FUA タグを失い、通常の I/O として実行されるバグを発見しました。これはフラッシュの要求を無視するという問題の現代版です。開発チームは、このバグを修正しましたが、以前のバグの動作に戻すオプションを用意しました。Windows Server 2003 に用意されたチェック ボックスは "拡張処理能力を有効にする" という名前ですが、この記事を読んだ皆さんは、このチェック ボックスが以前のバグの動作に戻すためのものであることがおわかりですね。

Raymond Chen は自分の Web サイト The Old New Thing および同じタイトルの書籍 (Addison-Wesley、2007) で、Windows の歴史と Win32 プログラミングについて扱っています。彼は枕のネームタグを外す主義です。

© 2008 Microsoft Corporation and CMP Media, LLC. All rights reserved; 許可なしに一部または全体を複製することは禁止されています.