13

Is there a way in zfs to find out where blocks for a particular file are stored? I'd like to be able to ask for the locations of all the blocks for a file, including ditto blocks.

(Yes, I understand that this is low-level stuff not normally exposed to users.)

(v0.6.0.56-rc8, ZFS pool version 28, ZFS filesystem version 5, Ubuntu 11.10)

4 Answers4

14

This is non trivial and possibly beyond the scope of an SF question/answer as the tools required don't appear well documented. You can probably use zdb(1m) in conjunction with the on disk format doc to find the information you want. There is a blog on how to do this here

Essentially

use ls -i to get the initial inode.

use zdb -ddddd <inodenum> to get the block information and decode it using the ODF

Romeo Ninov
  • 5,932
  • 4
  • 20
  • 26
user9517
  • 116,228
7

ZFS physically stores data using DVA (Device Virtual Addresses) offset + length. You can get the relevant data using something as zdb -bbb -vvv <dataset> -O <filename>. You should keep in mind that:

  • while ZFS stores DVA offset in 512-byte sectors on disk, zdb translate them in bytes
  • zdb output such numbers in hex format
  • offset 0 start after a 4 MB header on each disk.

For example, on a just created (and otherwise empty) test pool:

root@localhost:~# zpool status
  pool: tank
 state: ONLINE
config:
    NAME                     STATE     READ WRITE CKSUM
    tank                     ONLINE       0     0     0
      /root/disks/disk1.img  ONLINE       0     0     0

root@localhost:~# cp /etc/services /tank/ root@localhost:~# zdb -bbb -vvv tank -O services ... Indirect blocks: 0 L0 DVA[0]=<0:10007000:4000> [L0 ZFS plain file]

some math:

0x10007000 == 268464128 == 65543 4K blocks

65543 + 1024 4K blocks (header) == 66567 4K blocks

our file starts at 4k offset 66567

check with dd over the raw device (a backing file, in this test)

root@localhost:~# dd if=/root/disks/disk1.img bs=4k count=1 skip=66567 | head -3 1+0 records in 1+0 records out 4096 bytes (4.1 kB, 4.0 KiB) copied, 2.3434e-05 s, 175 MB/s

Network services, Internet style

Updated from https://www.iana.org/assignments/service-names-port-numbers...

Some references:

https://utcc.utoronto.ca/~cks/space/blog/solaris/ZFSDVAOffsetVdevDetails https://utcc.utoronto.ca/~cks/space/blog/solaris/ZFSDVAOffsetsInBytesII

shodanshok
  • 50,565
3

You can use ls -i to see the initial inode, after that I'd suggest reading the source code published to understand the on-disk data structures. After you've completed that I'd suggest writing your own tools to read the raw device and assemble all the block layout information you're interested in. There is a small-ish ZFS API (libzfs) project that only offers basic ZFS configuration like listing, creating etc. zpools.

pfo
  • 5,718
-1

On FreeBSD, you can obtain the file's object ID with stat(1):

stat -f %i /your/file

Of course, ls -i works as well, but then the number has to be parsed from ls's output with a command like grep.