fsync()なしで既存のファイルを置き換えると「破損」しますか?

fsync()なしで既存のファイルを置き換えると「破損」しますか?

Linuxのmount(2)マニュアルページで次の抜粋を見つけました。

次のパターンで既存のファイルを置き換えると、破損した多くのアプリケーションはfsync()を使用しません。

fd = open("foo.new")/write(fd,...)/close(fd)/ rename("foo.new", "foo")

またはもっと悪い

fd = open("foo", O_TRUNC)/write(fd,...)/close(fd).

auto_da_allocが有効になっている場合、ext4はrenameによる交換と切り捨てによる交換モードを検出し、名前変更()操作の後にデフォルトのdata = orderedモードで次のログコミットに遅延割り当てブロックを強制的に割り当てます。新しいファイルがディスクに強制的に保存されます。これはext3とほぼ同じレベルの保証を提供し、遅延割り当てられたブロックがディスクに強制的に書き込まれる前にシステムがクラッシュしたときに発生する可能性がある「長さのない」問題を防ぎます。

このコードはどのような意味で「壊れていますか?」コードが違法であるか、非標準規格(POSIXなど)と言っていますか?

fsync()システムがクラッシュするとどうなるか心配している人にとっては、これは良い考えかもしれません。しかし、システムがクラッシュしていないと仮定すると、両方のバージョンのサンプルコード(なし)がfsync()正しい動作をしますか?

ベストアンサー1

rename期待は原子的です。完全に完了するか、まったく完了しません。 Bの代わりにAの名前を変更した場合は、AとBの両方がそのままになるか(まったく発生しない)、Aの内容をBの名前の下に入れる必要があります(完全に完了)。

これは、システムがクラッシュしない限り、呼び出しなどに関係なくfsync発生します。

ただし、システムがクラッシュした場合は、名前変更自体がディスクに到達して完了したことがわかります。名前を覚えてください! =ファイル。ファイル/インデックスノードは複数の名前を持つことができます。名前を変更すると、デフォルトのファイル/データではなく名前が変更されます。

したがって、プログラムがAを書き、Bを置き換えるように名前を変更し、電源が切れる状態になる可能性があります。その結果、ファイルシステムは、Aの実際のデータの代わりにディスクに名前変更を記録します。いいえ。fsyncしたがって、長さ0のBまたは0で埋められたBになります。

アプリケーションがファイルを上書きするのではなく、一時ファイルに書き込んで名前を変更する理由は次のとおりです。〜したい衝突安全。重要な文書の半分だけが作成された一時コピーを変更されていない良好なコピーの横に置いても、ユーザーはあまり気分が悪くなります。しかし、良いコピーを残さないと、ユーザーは満足できません。

おすすめ記事