Bagaimana saya bisa mengetahui kisaran file LBA menggunakan inode-nya?

9

Saat menjawab pertanyaan U&L ini berjudul: Perintah apa yang saya gunakan untuk melihat blok awal dan akhir file dalam sistem file? , Saya mencoba mencari tahu apakah mungkin untuk menentukan LBA file menggunakan inode itu.

Jawaban saya menentukan bahwa saya dapat menggunakan hdparmsebagai satu metode untuk menemukan BBA:

$ sudo hdparm --fibmap afile 

afile:
 filesystem blocksize 4096, begins at LBA 0; assuming 512 byte sectors.
 byte_offset  begin_LBA    end_LBA    sectors
           0  282439184  282439191          8

Tapi saya ingin tahu apakah ada beberapa metode menggunakan inode file untuk mendapatkan LBA; tanpa menggunakan hdparm.

Saya pikir mungkin ada metode alternatif bersembunyi di alat filefrag, stat, debugfs, dan tune2fstapi menggoda itu adalah sehingga dapat menghindari saya.

Adakah yang bisa memikirkan alternatif?


Inilah beberapa penelitian saya sejauh ini yang mungkin berguna bagi mereka yang cukup berani untuk mencoba menjawab ini.

filefrag

Saya curiga Anda dapat menggunakan alat filefraguntuk melakukannya, khususnya menggunakan hasil dari -eperalihannya, mungkin dengan melakukan beberapa perhitungan untuk sampai ke sana yang saya tidak terlalu kenal.

output sampel

$ filefrag -e afile
Filesystem type is: ef53
File size of afile is 20 (1 block of 4096 bytes)
 ext:     logical_offset:        physical_offset: length:   expected: flags:
   0:        0..       0:   35304898..  35304898:      1:             eof
afile: 1 extent found

inode

Metode potensial lain yang saya duga mungkin memiliki potensi adalah dengan menggunakan informasi inode file, baik secara langsung atau melalui beberapa matematika kompleks yang kurang terdokumentasi pada interweb.

Contoh

Pertama kita cari inode file. Kita dapat melakukan ini dengan menggunakan statperintah atau ls -i.

stat

$ stat afile 
  File: ‘afile’
  Size: 20          Blocks: 8          IO Block: 4096   regular file
Device: fd02h/64770d    Inode: 6560281     Links: 1
Access: (0664/-rw-rw-r--)  Uid: ( 1000/    saml)   Gid: ( 1000/    saml)
Context: unconfined_u:object_r:user_home_t:s0
Access: 2013-12-27 18:40:12.788333778 -0500
Modify: 2013-12-27 18:40:23.103333073 -0500
Change: 2013-12-27 18:44:03.697317989 -0500
 Birth: -

ls -i

$ ls -i 
6560281 afile

Dengan informasi inode di tangan, kita sekarang dapat membuka sistem file yang berada di file ini menggunakan alat debugfs,.

CATATAN: Untuk menentukan sistem file tempat file berada, Anda dapat menggunakan perintah df <filename>.

Sekarang jika kita menjalankan debugfsdan menjalankan perintah stat <inode #>kita bisa mendapatkan daftar luasan yang berisi data file ini.

$ sudo debugfs -R "stat <6560281>" /dev/mapper/fedora_greeneggs-home
debugfs 1.42.7 (21-Jan-2013)
Inode: 6560281   Type: regular    Mode:  0664   Flags: 0x80000
Generation: 1999478298    Version: 0x00000000:00000001
User:  1000   Group:  1000   Size: 20
File ACL: 0    Directory ACL: 0
Links: 1   Blockcount: 8
Fragment:  Address: 0    Number: 0    Size: 0
 ctime: 0x52be10c3:a640e994 -- Fri Dec 27 18:44:03 2013
 atime: 0x52be0fdc:bbf41348 -- Fri Dec 27 18:40:12 2013
 mtime: 0x52be0fe7:18a2f344 -- Fri Dec 27 18:40:23 2013
crtime: 0x52be0dd8:64394b00 -- Fri Dec 27 18:31:36 2013
Size of extra inode fields: 28
Extended attributes stored in inode body: 
  selinux = "unconfined_u:object_r:user_home_t:s0\000" (37)
EXTENTS:
(0):35304898

Sekarang kami memiliki informasi luas di atas, dan di sinilah saya tersesat dan tidak tahu bagaimana melanjutkan.

Referensi

slm
sumber

Jawaban:

5

filefragdan debugfslaporkan offset dinyatakan dalam sejumlah blok sistem file.

Untuk mendapatkan offset dalam jumlah unit 512 byte, Anda perlu mengalikan dengan ukuran blok dalam unit 512 byte. Pada ext4 FS, ukuran blok seringkali 4k, jadi Anda perlu mengalikannya dengan 8.

Dengan filefrag, Anda juga dapat menggunakan -b 512opsi untuk mendapatkan offset dalam satuan 512 byte.

Anda bisa mendapatkan ukuran blok dengan statsperintah debugfs, atau dengan stat GNU:

stat -fc%s /mount/point

(atau file apa pun di sistem file itu).

Perhatikan bahwa hdparmini adalah utilitas hard disk, ia akan mencoba memberikan offset di dalam disk sebagai lawan perangkat blok tempat sistem file dipasang (dengan asumsi perangkat blok tidak berada pada disk entah bagaimana). Ini hanya berfungsi seperti itu untuk partisi (dengan menambahkan konten /sys/class/block/the-block-device/startke offset aktual), dan perangkat RAID 1, tetapi tidak pada jenis perangkat blok yang didukung disk lainnya seperti perangkat mapper perangkat, level RAID lain, perangkat dmraid, loop, nbd. .. Juga catat bahwa versi yang lebih lama hdparmmengandalkan FIBMAP ioctl yang terbatas pada perangkat blok apa yang dapat digunakan, sementara versi yang lebih baru menggunakan FIEMAP seperti filefrag.

Jadi, misalnya, jika Anda memiliki sistem ext2file aktif /dev/sda1.

# hdparm --fibmap /file/in/there
/file/in/there:
 filesystem blocksize 1024, begins at LBA 2048; assuming 512 byte sectors.
 byte_offset  begin_LBA    end_LBA    sectors
           0     109766     109767          2

Anda bisa mendapatkan kedua sektor tersebut (tetapi perhatikan bahwa file tersebut kemungkinan hanya menggunakan sebagian saja):

dd skip=109766 count=2 if=/dev/sda # not /dev/sda1

Saat dengan filefragatau debugfs.

# filefrag -v /file/in/there
Filesystem type is: ef53
Filesystem cylinder groups is approximately 12
File size of /file/in/there is 87 (1 block, blocksize 1024)
 ext logical physical expected length flags
   0       0    53859               1 merged,eof

Anda mendapatkannya dari perangkat blok aktual:

dd bs=1024 skip=53859 count=1 if=/dev/sda1
Stéphane Chazelas
sumber
Jadi jika saya mengerti Anda dengan benar, jika filefrag -b512 -v ..mengatakan "physical_offset: 211787168 .. 211795719" ini akan sama dengan LBA? Ini sepertinya hidup dengan file yang sama dengan hdparm --fibmap, 211787168..211795719. Jika saya menjatuhkan -b512 -vdan menggunakan def. 1024, dan mencoba mult. oleh 8, 26473396⋅8..26474464⋅8, saya mendapatkan 211787168..211795712, yang dekat tapi sedikit mati. Saya pikir nilai 2 seharusnya (26474465⋅8) -1 = 211795719, tidak yakin mengapa.
slm
Adakah pemikiran tentang cara mendapatkan blok dalam 512 unit dari debugfs?
slm
Saya akhirnya melakukan perhitungan untuk mengkonversi dari luasan ke LBA menggunakan matematika yang sama di atas.
slm
2

Ternyata untuk mengkonversi dari luasan ke LBA sebenarnya cukup mudah setelah Anda memahami dari mana angka-angka itu berasal. Jawaban @StephaneChazelas sangat penting untuk mendapatkan pemahaman ini.

Output debugf asli

Menggunakan contoh berikut yang disebutkan dalam pertanyaan.

$ sudo debugfs -R "stat <6560281>" /dev/mapper/fedora_greeneggs-home
debugfs 1.42.7 (21-Jan-2013)
Inode: 6560281   Type: regular    Mode:  0664   Flags: 0x80000
Generation: 1999478298    Version: 0x00000000:00000001
User:  1000   Group:  1000   Size: 20
File ACL: 0    Directory ACL: 0
Links: 1   Blockcount: 8
Fragment:  Address: 0    Number: 0    Size: 0
 ctime: 0x52be10c3:a640e994 -- Fri Dec 27 18:44:03 2013
 atime: 0x52be0fdc:bbf41348 -- Fri Dec 27 18:40:12 2013
 mtime: 0x52be0fe7:18a2f344 -- Fri Dec 27 18:40:23 2013
crtime: 0x52be0dd8:64394b00 -- Fri Dec 27 18:31:36 2013
Size of extra inode fields: 28
Extended attributes stored in inode body: 
  selinux = "unconfined_u:object_r:user_home_t:s0\000" (37)
EXTENTS:
(0):35304898

Dengan informasi luasan kita dapat melakukan perhitungan berikut. Tetapi kami membutuhkan satu informasi tambahan. Ukuran blok sistem file yang mendasarinya. Anda dapat menggunakan perintah ini untuk mendapatkannya.

Ukuran blok

$ sudo tune2fs -l /dev/mapper/fedora_greeneggs-home | grep "Block size"
Block size:               4096

Konversi dari Extents ke LBA

Jadi transformasi utama yang harus dikenali di sini adalah bahwa LBA berada dalam unit 512 byte dan debugfsperintah di atas yang melaporkan jumlah luasan, melaporkannya dalam blok 4096 byte.

Jadi, 4096/512 = 8. Jadi kita perlu mengalikan luasan dengan 8 untuk mengubahnya menjadi nilai LBA.

Jadi matematika berikut akan memberi kita LBA awal kita:

$ calc -d
; 35304898 * 8
    282439184
; 

Jadi apa LBA akhir kita? Untuk mendapatkan itu kita perlu mengenali bahwa inode kita pas di dalam satu blok sehingga tingkat akhirnya sama dengan tingkat awalnya. Untuk menghitung LBA akhir kita bisa menggunakan persamaan ini.

ending LBA = ( (extent + 1) * 8 ) - 1

Jadi melakukan perhitungan ini:

$ calc -d
; ( (35304898 + 1) * 8 ) - 1
    282439191

Mengonfirmasi hasil

Melihat hasil asli hdparm:

 byte_offset  begin_LBA    end_LBA    sectors
           0  282439184  282439191          8

Kami melihat bahwa semuanya cocok.

Contoh lain

Hanya untuk memastikan kami ada di sini, file yang lebih besar sebagai contoh ke-2.

$ ls -i util-linux-2.19.tar.bz2 
6559005 util-linux-2.19.tar.bz2

Inilah luasan inode.

$ sudo debugfs -R "stat <6559005>" /dev/mapper/fedora_greeneggs-home
...
EXTENTS:
(0-1068):26473396-26474464

Sekarang kami melakukan konversi dari luasan ke LBA.

$ calc -d
; 26473396*8
    211787168
; (26474464+1)*8 - 1
    211795719

Dan kami mengkonfirmasi.

$ sudo hdparm --fibmap util-linux-2.19.tar.bz2 
...
 byte_offset  begin_LBA    end_LBA    sectors
           0  211787168  211795719       8552

Dan kami cocok lagi.

slm
sumber