While answering this U&L question titled: What command do I use to see the start and end block of a file in the file system?, I tried to figure out if it was possible to determine a file's LBA using it's inode.
My answer determined that I could use hdparm
as one method for finding LBAs:
$ 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
But I was curious if there was some method using a file's inode to also get the LBA's; without using hdparm
.
I think there might be alternative methods hiding in the tools filefrag
, stat
, debugfs
, and tune2fs
but teasing it out is eluding me.
Can anyone think of alternatives?
Here's some of my research thus far that might be useful to those brave enough to attempt to answer this.
filefrag
I suspect you could use the tool filefrag
to do it, specifically using the results from its -e
switch, perhaps by performing several calculations to get there that I'm not that familiar with.
sample output
$ 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
inodes
Another potential method I suspect might have potential is to use a file's inode information, either directly or through some complex math that is poorly documented on the interwebs.
Example
First we find out the file's inode. We can do this using either the stat
command or 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
With the inode information in hand, we can now open up the filesystem this file resides on using the tool, debugfs
.
NOTE: To determine the filesystem a file resides on you can use the command df <filename>
.
Now if we run debugfs
and run the command stat <inode #>
we can get a list of extents that contain this file's data.
$ 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
Now we have the extents information above, and this is where I get lost and do not know how to proceed.