Saturday, 20 June 2009

FIBMAP ioctl example - get the file system block number of a file

The FIBMAP ioctl() is an obscure and rarely used ioctl() that returns the file system block number of a file.

To find the Nth block of a file, one uses the FIBMAP ioctl() as follows:

int block = N;
int ret = ioctl(fd, FIBMAP, &block);

where:

fd is the opened file descriptor of the file being examined,
N is the Nth block,
block is the returned file system block number of the Nth block.

fibmap.c
is example of a program that interrogates all the blocks of a file and dumps them out to stdout. From this one can see if a large file is contiguously allocated on your filesystem. One needs to have super user priviliges to be able to perform the FIBMAP ioctl, so run it using sudo. Any ideas for a good use of this ioctl() are most welcome!

UPDATE:

An alternative way to observe the output from fibmap is to use hdparm:

sudo hdparm --fibmap /initrd.img

/initrd.img: underlying filesystem: blocksize 4096, begins at LBA 63; assuming 512 byte sectors
byte_offset begin_LBA end_LBA sectors
0 860223 868414 8192
4194304 14114879 14122334 7456
 
Also check out the fiemap ioctl() for getting extent information from a file's inode.

7 comments:

  1. Just a note that FIBMAP does not take into account ext2/ext3 indirect blocks. These can be seem with the "stat" command in debugfs. What may seem like holes in the fibmap.c output may just be the indirect blocks.

    Not sure what the implications are for other filesystem types.

    ReplyDelete
  2. @Anonymous, OK - that's a good to know about the ext2/ext3 indirect blocks. Now where is the documentation for that...

    ReplyDelete
  3. Hmmm, fibmap.c no is no longer accessible, it seems.

    ReplyDelete
  4. @Richard, Apologies, I've moved it into my source code repo:

    http://kernel.ubuntu.com/git?p=cking/debug-code/.git;a=commit;h=2be8b87e85c3195c9ab365da3348c1e222f65dd1

    ReplyDelete
  5. Can a FIBMAP ioctl call block?

    ReplyDelete
  6. FIBMAP is indeed how LILO determines where the raw blocks of the kernel image exist on disk:
    https://alioth.debian.org/plugins/scmgit/cgi-bin/gitweb.cgi?p=lilo/lilo.git;a=blob;f=src/geometry.c;h=196a8924d995a4e691c12caa6e7e5322a9863e1f;hb=HEAD#l1497

    ReplyDelete