web-dev-qa-db-ja.com

Linuxでスパースファイルを操作する関数とは何ですか?

Linuxでスパースファイルを操作する関数とは何ですか? (Cで言うと、他のシステムに関するメモは大歓迎です)例:

  • ファイルの内側の一部を削除して、ファイルの内側に穴を開けます
  • 構造を調査します。分離された連続データブロックの開始と終了を示すペアのシーケンスを生成します
  • ブロックの範囲を再割り当てすることにより、ある時点でファイルを2つに分割します(つまり、実際のデータを移動せずに)
  • iノードやその他の関連する側面を調査しますか? (コピーオンライト方式で複数のファイルにいくつかのブロックを割り当てることはおそらく可能ですか?)

環境:

私が頭に浮かんだ最初の質問は、man rsyncオプションの--sparseの後でした。

rsync--sparseオプションが--inplaceと競合するのはなぜですか?

それはAPIを呼び出すファイルシステムの制限ですか?

データ構造の観点から、ソーススパースファイルがデータの非連続ブロックのシーケンスと見なされる場合、「r」同期から、ソースに存在しない範囲の割り当てを解除し、欠落している範囲を割り当て、残りを行うと予想されるよりもそれに応じて更新します(標準のrsyncローリングハッシュアルゴリズムを使用する場合でも、残りのすべてのシーケンスを1つとして扱うか、それぞれで個別に実行します)。

参照:

man rsync
   -S, --sparse
          Try to handle sparse files efficiently so they take up less space on the destination.  Conflicts with --inplace because it's

スパースな方法でデータを上書きすることはできません。

スパースファイルは、ユーザースペースに対して透過的になるように設計されています。ホールは、過去の未使用領域を探すことによって作成され、ゼロのブロックとして読み取られます。少なくともまだ、標準のユーザースペースAPIを使用して検出することはできません— 指摘 by StéphaneChazelas 、少なくともSolarisとLinuxは_SEEK_DATA_と_SEEK_HOLE_ lseek(2) ユーザースペースプログラムが穴を見つけることを可能にするフラグ。これらのフラグは POSIXに追加 ある時点である可能性があります。

これは、rsync'_--sparse_オプションと_--inplace_オプションの間の非互換性を説明しています:既存のファイルに書き込むときポータブル 、既存のデータに穴を作成することはできません。 _--sparse_は、ファイル全体を書き換え、ゼロの(長い)シーケンスをスキップすることで機能します。これにより、OSおよびそれらをサポートするファイルシステム上のスパースファイルが生成されます。

Linuxでは、 fiemap ioctl および_e2fsprogs_' filefrag(8) ;を使用して、ファイルのスパースネスの詳細を取得できます。 Linuxの詳細なスパースファイル情報 を参照してください。書き込み側では、 fallocate(2) (および便利な fallocate(1) ユーティリティ)を使用して、既存のファイルに穴を開けることができます。穴がブロック全体を覆っている場合はまばらになります。サポートはファイルシステムに依存します—現在、XFS、btrfs、ext4、およびtmpfsのみがこれらの操作をサポートしています。最近のカーネル(4.1以降)およびvery最近のバージョンの_util-linux_は、ファイルへの穴の挿入、穴の後のコンテンツのシフトをサポートしています(_fallocate -i_、_util-linux_ 2.30で導入されました。まもなくリリースされる予定です)。

最後の2つの質問はファイルシステムの手術ですが、そのような操作を実行するために利用できる一般的なシステムコールまたはioctlがあるかどうかはわかりません。 reflink互換のファイルシステムでは、ファイルでコンテンツを共有できます。これは、 FICLONEおよびFICLONERANGE ioctls を使用して実現できます。

10
Stephen Kitt