Linuxでスパースファイルを操作する関数とは何ですか? (Cで言うと、他のシステムに関するメモは大歓迎です)例:
環境:
私が頭に浮かんだ最初の質問は、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 を使用して実現できます。