1. Introduction

The structure and organization of filesystems and partitions are key elements when it comes to system usage and administration. In other words, knowing file and directory locations can be critical.

In this tutorial, we look at quick ways to check the physical partition of a given file or directory. First, we briefly refresh on partitions, filesystems, mounts, and storage abstractions. Next, we delve into different cases for identifying the physical medium of a given file or directory. Finally, we reference and demonstrate a script that combines most of the methods discussed.

We tested the code in this tutorial on Debian 11 (Bullseye) with GNU Bash 5.1.4. It should work in most POSIX-compliant environments.

2. Partitions and Filesystems

When it comes to storage, partitions are the top-level subdivisions in terms of logical separation in software. However, there are further abstractions based on them. In addition, when setting up a new Linux machine, we also need to format the partitions with a supported filesystem.

2.1. Storage Division

Usually, installing Linux leaves us with a fairly common software view of the storage medium:

$ fdisk --list

Disk /dev/sda: 10 GiB, 10737418240 bytes, 20971520 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes
Disklabel type: dos
Disk identifier: 0x10666010

Device     Boot   Start      End  Sectors  Size Id Type
/dev/sda1  *       2048  4786175  4784128  2.3G 83 Linux
/dev/sda2       4788222 20969471 16181250  7.7G  5 Extended
/dev/sda5       4788224  7032831  2244608  1.1G 83 Linux
/dev/sda6       7034880  9033727  1998848  976M 82 Linux swap / Solaris
/dev/sda7       9035776  9582591   546816  267M 83 Linux
/dev/sda8       9584640 20969471 11384832  5.4G 83 Linux

Here, fdisk lists six partitions:

  • /dev/sda1, primary, the main Linux partition of type 83
  • /dev/sda2, primary, an extended partition, container for logical partitions
  • /dev/sda5, logical
  • /dev/sda6, logical, swap
  • /dev/sda7, logical
  • /dev/sda8, logical

In a way, /dev/sda2 contains /dev/sda5, /dev/sda6, /dev/sda7, and /dev/sda8. Further, we don’t have a filesystem on this Extended (type 5) partition and the swap, as they’re just system constructs.

2.2. Mounts and Filesystems

Alternatively, we can use df to see a map of mounts and filesystems to the actual storage partitioning:

$ df
Filesystem     1K-blocks   Used Available Use% Mounted on
udev              450172      0    450172   0% /dev
tmpfs              93396    532     92864   1% /run
/dev/sda1        2281952 892784   1253184  42% /
tmpfs             466976      0    466976   0% /dev/shm
tmpfs               5120      0      5120   0% /run/lock
/dev/sda7         254499     11    236722   1% /tmp
/dev/sda5        1069136 255104    741536  26% /var
/dev/sda8        5515200     44   5214152   1% /home
tmpfs              93392      0     93392   0% /run/user/0
tmpfs              93392      0     93392   0% /run/user/1000

Here, we won’t see the special swap and Extended partitions, but we can check the mount points of the rest in the last column.

2.3. Logical Volume Manager (LVM)

The Logical Volume Manager (LVM) is a way for Linux to handle further abstractions when dividing storage. Indeed, it supports three division types:

  • physical volumes
  • logical volumes
  • volume groups

In a way, these are related to the usual primary, logical, and extended partitions but are much more flexible. In fact, LVM allows us to break the storage medium boundaries and subdivide physical partitions.

Handling LVM partitioning is usually done via the lvm2 package, which includes pv*, vg*, and lv* commands for each division type.

For example, with our setup above, we don’t have any LVM volumes, as confirmed by lvmdiskscan:

$ lvmdiskscan
  /dev/sda1 [       2.28 GiB]
  /dev/sda5 [       1.07 GiB]
  /dev/sda6 [     976.00 MiB]
  /dev/sda7 [     267.00 MiB]
  /dev/sda8 [      <5.43 GiB]
  0 disks
  5 partitions
  0 LVM physical volume whole disks
  0 LVM physical volumes

However, LVM introduces further complexity when it comes to identifying the physical location of a file or directory.

Because of these details, knowing where our data is and what actually stores it is a challenge but may become critical.

3. Where Is My Data?

Using the setup in the previous section, let’s take an example directory at /tmp/dir and attempt to identify the partition that holds it.

3.1. Base Case

In the simplest case, we can get what we need via df alone by passing the path to our directory:

$ df /tmp/dir
Filesystem     1K-blocks  Used Available Use% Mounted on
/dev/sda7         254499    12    236721   1% /tmp

Here, we see that /dev/sda7 is the partition mounted on /tmp and holding our data. This is the simplest scenario. Let’s move on to more complex situations.

Indeed, we can check what happens when a file or directory link is on a different partition from its data.

First, let’s create a symbolic link to our directory:

$ ln --symbolic /tmp/dir /var/dir

Now, let’s apply our earlier strategy to the link:

$ df /var/dir
Filesystem     1K-blocks  Used Available Use% Mounted on
/dev/sda7         254499    12    236721   1% /tmp

Evidently, df is able to resolve the link and get the proper location of our data. Yet, the location itself might be misleading.

3.3. LVM

When we have a directory on an LVM volume, working with df alone might not be enough. To demonstrate, we created the volume group baeldung with a single logical volume vol1, mounted on /vol1.

Creating and locating /vol1/dir shows us the logical volume data:

$ df /vol1/dir
Filesystem                1K-blocks  Used Available Use% Mounted on
/dev/mapper/baeldung-vol1   3021608    24   2847916   1% /vol1

However, since /dev/mapper contains pseudo-devices for the LVM, we should resolve one more level:

$ lvs -o +devices /dev/mapper/baeldung-vol1
LV   VG       Attr       LSize Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert Devices
vol1 baeldung -wi-ao---- 3.00g                                                     /dev/sda(0)

Here, lvs shows us that /dev/sda is the actual location of /dev/mapper/baeldung-vol1 and, thus, our data.

Alternatively, the location can be a partition (sda1) instead of a whole disk (sda):

$ lvs -o +devices /dev/mapper/baeldung-vol1
LV   VG       Attr       LSize Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert Devices
vol1 baeldung -wi-ao---- 3.00g                                                     /dev/sda1(0)

Let’s explore one final storage subdivision.

3.4. RAID and Multiple Devices

Linux also supports multi-device storage, usually as /dev/md* devices that form a RAID.

With this abstraction, we have to take a two-step approach similar to the LVM scenario:

$ df /md1/dir
Filesystem           1K-blocks  Used Available Use% Mounted on
/dev/md1               6660106   666   6659440   1% /md1
$ mdadm --detail /dev/md1
[...]
    Number   Major   Minor   RaidDevice State
       0       8        3        0      active sync   /dev/sda1
       1       8       10        1      active sync   /dev/sdb2

With the help of the madm command, we resolve the logical device returned by df to its proper physical constituents.

3.5. Script

Combining all scenarios and approaches above, we get a path to the physical medium resolving script:

$ wget 'https://github.com/BMDan/rawdev/blob/master/rawdev.sh'
$ chmod +x rawdev.sh
$ ./rawdev.sh /vol1/dir
/dev/sda1

Here, the rawdev.sh script employs names to identify possible configurations and uses the appropriate tools to get the relevant storage location.

4. Summary

In this article, we looked at ways to get the physical partition a file or directory is located on.

In conclusion, there are many types of storage subdivisions, but each one provides ways to resolve the original partition or storage medium that holds our file or directory data.