rename()を使用して既存のファイルを置き換えるときにfsync()がクラッシュから安全でなければならないファイルシステムは何ですか?

rename()を使用して既存のファイルを置き換えるときにfsync()がクラッシュから安全でなければならないファイルシステムは何ですか?

auto_da_alloc広範な苦情が提起された後、ext4は基本的に衝突安全保証を有効にしました。他のファイルシステムはどうですか?最もよく知られているファイルシステムの中で、同じ保証を提供するファイルシステムと提供しないファイルシステムは何ですか?

個人的には、次のことを聞きたいです。

  • XFS - Red Hat Enterprise Linux の基本ファイルシステムです。
  • btrfs - SuSE Enterpriseの基本ファイルシステム。
  • bcachefs- bcacheから派生したツリー外部Linuxファイルシステム。 「LinuxのCOWファイルシステムはデータを占有しません。」

以下の記録に基づいて、この質問は主にLinuxに関するものです。 ZFSがどのように動作するかを見るのも興味深いでしょう。しかし、私はZFSがそれを実装しないと仮定したいと思います。

何ですかauto_da_alloc

fsync() は、テキストエディタで「保存」を押すときなど、ファイルデータを書き込む正しい方法でよく文書化されています。たとえば、テキストエディタは通常、ファイルをアトミックに置き換えるために rename() を使用する必要があることが一般的に受け入れられます。これは停電を防ぎ、常に古いファイルを保持したり新しいファイルをインポートしたりするためです(名前を変更する前にfsync()されています)。新しいファイルの半分だけが作成されたバージョンだけを残したくありません。

ただし、最も一般的なLinuxファイルシステムであるext3でfsync()を呼び出すと、システム全体が数十秒間中断される可能性があるという問題があります。アプリケーションがこれを行うことができないため、fsync()の代わりにrename()を楽観的に使用するのが一般的です。このモードは、システムの電源が切れても、このファイルシステムで合理的にうまく機能するようです。

そのため、fsync() を正しく使用しないアプリケーションがあります。

ファイルシステムの次のバージョンext4は、通常fsync()の中断を防ぎます。同時に、fsync()の正しい使用にもっと依存し始めました。

すべて悪いです。議論の余地がありますが、多くの競合するカーネル開発者が使用する無視するフレーズは、この歴史を理解するのに役立ちません。

この問題はext4で解決されました。衝突を防ぐために、fsync()なしでrename()モードをサポートしています。以前のext3ファイルシステムと同じ競合動作を提供します。オプションを使用してマウントすると、この動作を再び無効にできますnoauto_da_alloc

ベストアンサー1

この質問にはバグがあります。この質問は、シナリオが次のようになることを意味します。完全衝突安全auto_da_alloc。 ext4ではそうではありません。私はこれが古いext3でも同じだとは思わない。しかしそれははいこれはbtrfsとbachefsの両方に当てはまります。

最近のext4には、名前を変更するときに新しいデータブロックを強制的に削除して、名前の置き換えで長さ0のファイルを生成する可能性を減らす特別な回避策があります。ただし、名前の変更はリフレッシュが完了するのを待たないため、原子性は保証されません。クラッシュ後、部分的な新しいコンテンツのみを取得できます。私たちがテストしたファイルシステムの中で、btrfsは名前変更による交換原子性を保証する唯一のシステムです。

https://homes.cs.washington.edu/~lijl/papers/ferrite-asplos16.pdf


優れたbtrfs文書rename() を使用してファイルを置き換えると、完全な原子性が得られ、データの破損を防ぐために明示的な fsync() が必要ないことを示します。これが追加されたと思います。ext4とほぼ同じ時期auto_da_alloc。また、 btrfs 実装は rename() の呼び出しを待たないため、パフォーマンスの低下を防ぐという主張も確認しました。しかし、最近のカーネルでは、少なくともfsync()を使用すると、次の rename()fsync() 親ディレクトリを呼び出し、「ログツリー全体」が書き込まれるまで待ちます。

bcachefs現在文書が見つかりませんが、完全な保護があるようです。コードを確認してください。 「filemap_write_and_wait_range」関数への呼び出しが表示されます。

XFS持つ拒否するrename() の競合防止回避策を追加します。さまざまなシナリオでデータ損失のリスクを減らす(削除しませんが)コードを取得しているようです。

UBIFS(例:多くのOpenwrtデバイスで使用されています)rename()への競合からの安全な回避策は含まれていません。受け入れることはできますが、多くの努力が必要です。 http://www.linux-mtd.infradead.org/doc/ubifs.html#L_sync_Exceptionions

おすすめ記事