内部から希少ファイルを非希少ファイルに変換

内部から希少ファイルを非希少ファイルに変換

Linuxでスパースファイルがある場合、それをスパースファイルにする方法は?
copyを使用できますが、cp --sparse=never ...ファイルが10Gでホールが2Gの場合(つまり、割り当てられたスペースが8Gの場合)、元の8Gを新しいファイルにコピーせずにファイルシステムに残りの2Gを割り当てる方法を教えてください。

ベストアンサー1

表面的にこれは簡単ですdd

dd if=sparsefile of=sparsefile conv=notrunc bs=1M

ファイル全体を読み、内容全体を書き換えます。

穴自体のみを書き込むには、まず穴がどこにあるかを確認する必要があります。filefragまたは、以下を使用してこれを実行できますhdparm

ファイルの断片:

# filefrag -e sparsefile
Filesystem type is: 58465342
File size of sparsefile is 10737418240 (2621440 blocks of 4096 bytes)
 ext:     logical_offset:        physical_offset: length:   expected: flags:
   0:        0.. 1048575:  187357696.. 188406271: 1048576:            
   1:  1572864.. 2621439:  200704128.. 201752703: 1048576:  188406272: last,eof
sparsefile: 2 extents found

HDパラメータ:

# hdparm --fibmap sparsefile

sparsefile:
 filesystem blocksize 4096, begins at LBA 0; assuming 512 byte sectors.
 byte_offset  begin_LBA    end_LBA    sectors
           0 1498861568 1507250175    8388608
  6442450944 1605633024 1614021631    8388608

あなたが言ったように、このサンプルファイルにはサイズに穴が10Gあります。2Gこれには、最初のカバー0-1048575と2番目のカバーの2つの範囲があります1572864-2621439。これは、穴が1048576-1572864(図のように4kサイズのチャンクfilefrag)であることを意味します。表示される情報hdparmは同じですが、別の方法で表示されます(最初の範囲は83886080から始まる512バイトのセクタを含むため、バイトである0-4294967295ため、脆弱性は4294967296-6442450944バイト単位です)。

断片化がある場合は、より多くの範囲を表示できます。残念ながら、両方のコマンドは脆弱性を直接表示せず、どのコマンドも脆弱性を表示しないため、表示された論理オフセットからこれを推論する必要があります。

1048576-1572864これで、適切な(同じ)/値sumを追加して、上記のようにこの穴を埋めることができます。上記で使用したセクタを使用するように調整されました。 ( の場合、チャンクサイズを反映するようにナビゲーション/スキップ/カウント値を調整する必要があります。)ddseekskipcountbs=4kfilefragbs=1M1M

dd if=sparsefile of=sparsefile conv=notrunc \
   bs=4k seek=1048576 skip=1048576 count=$((-1048576+1572864))

ファイル自体を読み取る代わりに(0のみが作成された)穴を埋めることもできますが、オフセットが間違っている場合はデータが破損しないように/dev/zero読み取る方が安全です。sparsefile

最新バージョンでは、GNU ddより大きなブロックサイズに固執し、すべての値をバイト単位で指定できます。

dd if=sparsefile of=sparsefile conv=notrunc bs=1M \
   iflag=skip_bytes,count_bytes oflag=seek_bytes \
   seek=4294967296 skip=4294967296 count=$((-4294967296+6442450944))

filefrag実行後:

# sync
# filefrag -e sparsefile 
Filesystem type is: 58465342
File size of sparsefile is 10737418240 (2621440 blocks of 4096 bytes)
 ext:     logical_offset:        physical_offset: length:   expected: flags:
   0:        0.. 1572863:  187357696.. 188930559: 1572864:            
   1:  1572864.. 2621439:  200704128.. 201752703: 1048576:  188930560: last,eof
sparsefile: 2 extents found

断片化のため、まだ2つの範囲です。しかし、論理オフセットによると、今回は穴がないため、ファイルはもはや希薄ではありません。

もちろん、このddソリューションは非常に受動的なアプローチです。定期的にこの機能が必要な場合は、これらのスペースを埋めるために小さなプログラムを書くのが簡単です。既に標準ツールとして存在する場合は聞いたことがありません。


結局、fallocateある程度動作するように見えるツールがあります。

fallocate -l $(stat --format="%s" sparsefile) sparsefile

しかし、最後に、XFSの場合、ファイルに物理領域を割り当てますが、実際にはゼロにはなりません。filefrag割り当てられたが記録されていない範囲を表示します。

   2:        3..      15:    7628851..   7628863:     13:    7629020: unwritten

ブロックデバイスから直接正しいデータを読み取ることが目的であれば、これは十分ではない。今後の書き込みに必要な記憶領域のみを予約します。

おすすめ記事