15

As I understand it, each file on a Unix-like operating system has an inode number (which can be viewed with "ls -i"), and each inode is a list of disk blocks that contain the actual data of a file.

Is there a Linux command which takes a filename as its argument and prints out the list of disk blocks that that file's inode points to?

P.S. The filesystem in question is ext3.

mike
  • 3,853
  • 11
  • 29
  • 27

5 Answers5

20

You could use the "debugfs" tool to view file info on the command line or interactivley. either use:

# debugfs /dev/<spartition>
# stat /path/to/file

or

# debugfs -R "stat /path/to/file" /dev/<partition>

for example:

# debugfs -R "stat /etc/passwd"  /dev/sda5
Inode: 435914   Type: regular    Mode:  0644   Flags: 0x0
Generation: 979004472    Version: 0x00000000
User:     0   Group:     0   Size: 1577
File ACL: 0    Directory ACL: 0
Links: 1   Blockcount: 8
Fragment:  Address: 0    Number: 0    Size: 0
ctime: 0x4a2d6f78 -- Mon Jun  8 23:07:20 2009
atime: 0x4a2d6f79 -- Mon Jun  8 23:07:21 2009
mtime: 0x4a2d6f78 -- Mon Jun  8 23:07:20 2009
Size of extra inode fields: 4
BLOCKS:
(0):1767438
TOTAL: 1
katriel
  • 4,407
  • 22
  • 20
  • 1
    Note that the argument for 'stat' is not always /path/to/file. Using /path/to/file works for files on the root file systems (mounted at /) but not for paths mounted in other file system. In those cases one may get the error message `File not found by ext2_lookup`. So it is better to use the inode notation for the argument of stat. Use `ls -i` to get the inode number of a file, then invoke debugfs with that number in '<>' instead of /path/to/file. For example: `# debugfs -R "stat <1234567>" /dev/sda2` – ElazarR Feb 14 '17 at 15:14
  • @ElazarR Can you explain that comment? Why should `path/to/file` not work in all cases? What is confusing to me is that via `debugfs ..... /dev/fs_blockdev` there is in my comprehension only ever one filesystem in consideration ever, and all those files inside this system can be accessed either via their path or via thair inode, what did you want to express? – humanityANDpeace Mar 10 '17 at 10:56
  • @humanityANDpeace , in the case where a file is in a partition (filesystem) that is outside of the root filesystem, i.e., mounted at some mount point under the root partition, the ext2_lookup operation seems to fail finding the given path under the given device (partition). This results in the error I mentioned. For example, if your /home folders are mounted from /dev/sda5 over the root filesystem (which is on another paritition, e.g., /dev/sda3), then `debugfs -R "stat /home/myuser/foo.txt" /dev/sda5` results in an error. But invoking `debugfs -R "stat /path/on/rootfs" /dev/sda3` works. – ElazarR Mar 11 '17 at 13:05
  • I think you need `sudo`, otherwise some unhelpful message will be displayed. – Kedar Mhaswade Jun 25 '17 at 03:54
  • And the converse question: how we can find out which file uses a given block? – Luis A. Florit Jul 05 '17 at 17:28
  • @ElazarR : In my situation your comment works the other way arround. `ls -i /home/gatio/ave_Permisao_Wikiaves` gives me `783781 /home/gatio/ave_Permisao_Wikiaves`, and then `debugfs -R "stat 783781" /dev/sda6` gives me `783781: File not found by ext2_lookup`. – Luis A. Florit Jul 05 '17 at 17:54
  • @Luis, you forgot the "<>" around the inode number. In your case, it should be `sudo debugfs -R "stat <783781>" /dev/sda6` (assuming your /home/ partition is on /dev/sda6). – ElazarR Jul 09 '17 at 08:03
  • 1
    @Kedar - regarding the `sudo` - Note that all the examples that start with the `#` sign imply root prompt. So `sudo` is redundant in those cases. – ElazarR Jul 09 '17 at 08:07
  • Is there a way to do this through a C api? – Azmisov Mar 12 '19 at 19:28
  • It should be noted that (according to the manual page) `debugfs` works for `ext2`, `ext3`, and `ext4` only. – U. Windl May 11 '21 at 08:49
5

A simple way to get the list of blocks (without having to read from the partition like in the debugfs answers) is to use the FIBMAP ioctl. I do not know of any command to do so, but it is very simple to write one; a quick Google search gave me an example of FIBMAP use, which does exactly what you want. One advantage is that it will work on any filesystem which supports the bmap operation, not just ext3.

A newer (and more efficient) alternative is the FIEMAP ioctl, which can also return detailed information about extents (useful for ext4).

CesarB
  • 2,368
  • 15
  • 9
  • There are some interesting details, however: I have a case where `FIGETBSZ` returns 4096 while `fstat()` returns `st_blksize=16384`. So could I expect that there are always clusters of four consecutive 4kB blocks at least? – U. Windl May 11 '21 at 08:26
  • The other thing is that some filesystems (like OCFS2) seem not to implement the `ioctl(FIBMAP)`: I got block zero (and no error indicator) for every logical file block. First I thought that might be sparse blocks, but that does not seem to be the case. – U. Windl May 11 '21 at 08:42
5
hdparm --fibmap /path/to/filename

I will not work on zfs, but will on ext4, btrfs, (v)fat, etc

man 8 hdparm :

--fibmap When used, this must be the only flag given. It requires a file path as a parameter, and will print out a list of the device extents (sector ranges) occupied by that file on disk. Sector numbers are given as absolute LBA numbers, referenced from sector 0 of the physical device (not the partition or filesystem). This information can then be used for a variety of purposes, such as examining the degree of fragmenation of larger files, or determining appropriate sectors to deliberately corrupt during fault-injection testing procedures.

HBruijn
  • 72,524
  • 21
  • 127
  • 192
ChewbaccaKL
  • 228
  • 3
  • 10
4

Look at the syntax for "debugfs", and specifically the "stat" command. That will show you a list of the data blocks used by a file. You can pass parameters to "debugfs" with the "-f" argument to call it from a script.

Evan Anderson
  • 141,071
  • 19
  • 191
  • 328
2

At least on some linux machines... "ls -s" might provide what you're looking for.

Edit: my bad, I see that you're looking for a list of the blocks themselves, not a count of them.

user10357
  • 131
  • 2
  • -s shows the size of the file in blocks -- i want an actual list of the block numbers. – mike Jun 22 '09 at 18:10