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.
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.
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.
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.