8

Is there any Linux program which offers the same (or some of the) functionality of Sysinternals DiskView, especially being able to view to physical location of a file on a hard disk?

DiskView URL: http://technet.microsoft.com/en-gb/sysinternals/bb896650

1
  • DiskView isn't as much about OS (Windows v. Linux) as it is about filesystem type. Even in Windows, it doesn't handle any filesystem but NTFS. The number of possible filesystems is a lot larger in Linux than in Windows - you should probably target your software search by filesystem as opposed to OS.
    – mikeserv
    Commented Oct 14, 2014 at 0:31

2 Answers 2

16

For some file systems like ext4 or btrfs on Linux, you can use filefrag to get the offsets of the data segments for the file on the block device the file system is on.

$ seq 1000 > a
$ filefrag -v a
Filesystem type is: ef53
File size of a is 3893 (1 block of 4096 bytes)
 ext:     logical_offset:        physical_offset: length:   expected: flags:
   0:        0..       0:   82784147..  82784147:      1:             eof
a: 1 extent found
$ sudo dd bs=4k skip=82784147 count=1 if=/dev/storage/home 2>&- | head
1
2
3
4
5
6
7
8
9
10

Here the block device is a LVM volume. That volume may have physical volumes on disks, on partitions, on RAID arrays, on files, on RAM, on network block devices... Going back to an actual disk or set of disk may prove difficult.

In my case, it's relatively easy, as it's just a logical volume on top of one GPT partition as one linear stretch.

$ sudo dmsetup table /dev/storage/home
0 1953120256 linear 8:98 384

So /dev/storage/home is 384 sectors within device 8:98, which happens to be /dev/sdg2 for me.

$ cat /sys/block/sdg/sdg2/start
489060352

So sdg2 is 489060352 sectors within /dev/sdg (the 7th disk on this system).

So I can obtain the offset within the single disk that file is on with:

$ sudo dd if=/dev/sdg skip="$((489060352+384+82784147*8))" count=1 2> /dev/null | head
1
2
3
4
5
6
7
8
9
10
4
  • Thanks for your suggestion. I did know about filefrag, and I wondered whether there were any other programs that could do this. The reason is because I once tried using filefrag -ev filename on a 512MB FAT volume and it told me the file started on something like block 15625000, which at 512 bytes per sector = 8GB! Any idea why?
    – EmmaV
    Commented Oct 13, 2014 at 23:04
  • @EmmaV: maybe that 512mb FAT volume was at 8gb on the underlying physical disk? Commented Oct 16, 2014 at 20:29
  • @OlivierDulac: The capacity of the whole physical disk was only 512MB!
    – EmmaV
    Commented Oct 25, 2014 at 17:16
  • I have a file of size 0 that is overwritten on top of a previous file, does that mean I cannot find its location any more (need for recovery)?
    – dashesy
    Commented Dec 17, 2015 at 15:00
0

I know this is an old post but I needed the same functionality for a btrfs filesystem, which doesn't have a simple logical -> physical address mapping. The elegant way to do this on btrfs is to compile btrfs_map_physical.c located source here.

A more general mechanism I created that'll work on any filesystem is accessing the file with dd while running blktrace.

While running this in one terminal:

sudo blktrace -d /dev/sda -o - | blkparse -i - -F Q,"%d Queue(Q) %T.%t %S %n %C\n" | grep --line-buffered "Queue(Q)" | awk -W interactive ' {printf "%s %13s %s 0x%08x 0x%04x %s\n", $2, $3, $1, $4, $5, $6; fflush() }

Run this in another:

dd if=/mnt/myfs/test.txt bs=4096 iflag=direct count=1 | head -4

Sample output:

Queue(Q)   0.000000000 R 0x00044800 0x0008 dd
  • Queue(Q) is the blktrace event I'm parsing
  • 0.000000000 is the relative timestamp
  • R is the operation (read)
  • 0x00044800 is the block address in hex. Change the printf if you want decimal.
  • 0x0008 is the number of blocks read
  • dd is the name of the app that issued the request

This sample is on a filesystem with a blocksize of 4K.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .