If I do

# cd /
# ln -s /home test
# cd test
# mount --bind $PWD /mnt

the entry in /proc/mounts is

/dev/sda2 /mnt ext4 rw,noatime,data=ordered 0 0

which is the device that is mounted to /home and is not easily deducible from $PWD which is /test. How can I determine which device (i.e., /dev/sda2) is going to show up in /proc/mounts in general given that the bind mount may be to a directory/file that is potentially "obscured" by symlinks, other bind mounts, etc?

5 Answers 5


If I understand your question you want to know which device was used for a given mount. For this you can use the df command:

$ df -h 
Filesystem                         Size  Used Avail Use% Mounted on
/dev/mapper/fedora_greeneggs-root   50G   21G   27G  44% /
devtmpfs                           3.8G     0  3.8G   0% /dev
tmpfs                              3.8G   14M  3.8G   1% /dev/shm
tmpfs                              3.8G  984K  3.8G   1% /run
tmpfs                              3.8G     0  3.8G   0% /sys/fs/cgroup
tmpfs                              3.8G  3.4M  3.8G   1% /tmp
/dev/sda1                          477M   99M  349M  23% /boot
/dev/mapper/fedora_greeneggs-home  402G  184G  198G  49% /home

To find which device a particular file/directory is found on, give the file as an argument to df. Using your example:

$ df -h /mnt
Filesystem                         Size  Used Avail Use% Mounted on
/dev/sda1                          477M   99M  349M  23% /

You can also use the mount command:

$ mount | grep '^/dev'
/dev/mapper/fedora_greeneggs-root on / type ext4 (rw,relatime,seclabel,data=ordered)
/dev/sda1 on /boot type ext4 (rw,relatime,seclabel,data=ordered)
/dev/mapper/fedora_greeneggs-home on /home type ext4 (rw,relatime,seclabel,data=ordered)

The directory mounted for each device is the 3rd argument in the output above. So for device /dev/sda1 would be /boot. The other devices are making use of LVM (Logical Volume Management) and would need to be further queried to know which actual device is being used by LVM.

  • 1
    If $PWD (which is what I am mounting) is buried in a series of symlinks, bind mounts, etc then I would need to recursively examine the path for mount points.
    – StrongBad
    May 8, 2014 at 12:27
  • 1
    With bind mounts despite what shows up in /proc/mounts the "thing" that is mounted, at least in my mind, is not the device it is the directory/file.
    – StrongBad
    May 8, 2014 at 12:29
  • @StrongBad - what does readlink -f /mnt show?
    – slm
    May 8, 2014 at 12:37
  • 2
    @StrongBad if you have to deal with determining the mount point/device when obscured by symlinks, you should put that in your question. It'll make it much easier to get the right answer.
    – phemmer
    May 8, 2014 at 12:48
  • readlink -f /mnt gives /mnt
    – StrongBad
    May 8, 2014 at 13:18

On Linux we have findmnt from util-linux exactly made for this

findmnt -n -o SOURCE --target /path/to/FILE

The advantage about other solutions is that it still works if paths are obscured by symlinks or duplicate bind mounts.

  • This doesn't work for me. It shows the source of every mount on the system. findmnt from util-linux 2.23.2
    – bwduncan
    Apr 18, 2017 at 11:46
  • @bwduncan for me it works with 2.23.2. Maybe a bug? Could you try the latest version 2.29.2?
    – rudimeier
    Apr 18, 2017 at 20:42
  • 2.29 on Ubuntu does the trick. Not a bug as such, more a feature :)
    – bwduncan
    Apr 25, 2017 at 11:00
  • 1
    Thanks! That's exactly what I needed for a system script.
    – vog
    May 16, 2017 at 13:30
  • findmnt -n -o SOURCE -M /path/to/DIR is what is best for me, it checks for the exact mountpoint: /path/to/DIR , if it is not used nothing is returned. With findmnt -n -o SOURCE --target /path/to/DIR you get the partition where the mountpoint is located, which is the answer on the original question!
    – Martin T.
    Mar 16, 2023 at 12:28

The most accurate method I am aware of is to use the output of the lstat() system call. Specifically, the st_dev field. There is a command line utility, stat(1) that can be used to see this information. For example, the output of "stat /etc/issue" on my laptop:

File: ‘/etc/issue’
  Size: 65          Blocks: 8          IO Block: 4096   regular file
Device: 801h/2049d  Inode: 1610916043  Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)

Notice the third line, first field, "Device". Here it lists 801h. That value can be separated into two bytes, 8 and 1. The first byte is known as the major number, the second byte is the minor number. So, the next step is to figure out what device major 8, minor 1 is.

I find consulting /proc/partitions to be the fastest. In my case, /proc/partitions has the contents:

major minor  #blocks  name

   8       16  234431064 sdb
   8       17   33554432 sdb1
   8       18  200875608 sdb2
   8        0  500107608 sda
   8        1  500106584 sda1

It's rather clear from that output that major 8, minor 1 is sda1. We can confirm this with an ls -l /dev/sda1

brw-rw---- 1 root disk 8, 1 May  8 05:33 /dev/sda1

Notice the 8, 1 before the datestamp.

It's important to understand/remember that the name of a device file like /dev/sda1 is only a label. The major and minor numbers are the significant, important values of the device file. If you get curious, check out the mknod(1) utility used to create device files. I could create a new /dev entry called aardvark with major 8, minor 18 with the following syntax:

mknod /dev/aardvark b 8 18

Then, I could easily mount it:

mount /dev/aardvark /mnt

and, if we look at the output of the mount command or the contents of /proc/mounts and we see:

/dev/aardvark on /mnt type xfs (rw,relatime,attr2,inode64,noquota)

df -h shows:

/dev/aardvark   192G  154G   38G  81% /mnt

... Anyways, the point of all of this is to illustrate that the important details for identifying a block device are the major and minor numbers - not the device file label - and that using the lstat() system call is the best way to query those values.

As a last comment, I just reread your question to make sure I was answering it and I realized you were asking what source device label would show up in /proc/mounts for a bind mount. That would be the same source device label as was used in the original mount(2) call for the filesystem mountpoint source for the bind mount. Perhaps an example would help:

I have /dev/sdb2 and /dev/aardvark (the same as above). They are both major 8, minor 18. Note, I will be mounting the same filesystem twice. I do the following:

mkdir /mnt1 /mnt2 /foo

mount /dev/aardvark /mnt1
mount /dev/sdb2 /mnt2

Notice that I make the directory somedir in /mnt1. But since /mnt1 and /mnt2 have the same filesystem mounted, somedir will also be reachable through /mnt2.

mkdir /mnt1/somedir

mkdir /foo/left /foo/right

mount -o bind /mnt1/somedir /foo/left
mount -o bind /mnt2/somedir /foo/right

Now, if we check /proc/mounts, we see:

/dev/aardvark /mnt1 xfs rw,relatime,attr2,inode64,noquota 0 0
/dev/sdb2 /mnt2 xfs rw,relatime,attr2,inode64,noquota 0 0
/dev/aardvark /foo/left xfs rw,relatime,attr2,inode64,noquota 0 0
/dev/sdb2 /foo/right xfs rw,relatime,attr2,inode64,noquota 0 0

The source device label on the /foo/... bind mounts is the same as the value originally supplied in the filesystem mount(2) call. Remember, /dev/aardvark and /dev/sdb2 in my example are the same device.

I realize I just typed up a novel and the first half doesn't really answer your question at all, but it seemed like such a waste to delete it. Perhaps it'll help someone else.

Good Luck.

P.S. Do keep in mind that some filesystems are network based - like NFS or CIFS - or are virtual - like procfs or sysfs and don't have a source block device. I don't know what will be returned as the device in the stat output, just for what it's worth.

  • 2
    The first part definitely helps me understand the last part.
    – StrongBad
    May 8, 2014 at 13:44
  • This answer does not work for tmpfs paths. You will not find the st_dev minor,major on /proc/partitions.
    – mbello
    Feb 10, 2019 at 3:30
  • @mbello As I mention at the end of my answer, this method won't and can't work for filesystems that have no backing device - like tmpfs mounts.
    – etherfish
    Feb 20, 2019 at 5:18

Given the following typical mountpoints:

$ df --output=target
Mounted on

stat --format %m <path> will print only mountpoint in a round-trappable fashion (although you need to check the exit code to unambiguously detect a permission error; mount-table approaches win here):

$ stat --format %m /
$ stat --format %m /tmp
$ stat --format %m /proc
$ stat --format %m /run
$ stat --format %m /run/mount
$ stat --format %m /run/user
$ stat --format %m /run/user/1000/dconf
$ stat --format %m /run/user/1000/gvfs

Symlinks take a bit of care as usual:

$ ls -lh ~/.gvfs
/home/cwillu/.gvfs -> /run/user/1000/gvfs
$ stat --format %m ~/.gvfs
$ stat --format %m ~/.gvfs

And of course remember to use quotes when scripting. Consider a mountpoint path with spaces and such:

$ mkdir /tmp/Something\ Like\ This\!
$ sudo mount none /tmp/Something\ Like\ This\! -t tmpfs
$ stat --format %m /tmp/Something\ Like\ This\!
/tmp/Something Like This!
$ touch /tmp/Something\ Like\ This\!/pretend-I\'m-big
$ ls /tmp/Something\ Like\ This\!

How big are you?

$ du $(stat --format %m /tmp/Something\ Like\ This\!/)
du: cannot access /tmp/Something: No such file or directory
du: cannot access Like: No such file or directory
du: cannot access This!: No such file or directory

$ du "$(stat --format %m /tmp/Something\ Like\ This\!/)"
0   /tmp/Something Like This!

My distro's tab completion don't even get this right, so we'll just wildcard this example mountpoint with carriage returns and linefeeds and runs of spaces:

$ stat --format %m /tmp/Something*
Like   This!

$ a="$(stat --format %m /tmp/Something*)"
    # the above assignment is actually the one place you don't need quotes, 
    # but `export a=...` or similar _would_ need them, so we'll just put them in;
    # they don't change the behaviour in this form of assignment.

$ stat "$a"
  File: ‘/tmp/Something   \r\n\rLike   This!’
  Size: 40          Blocks: 0          IO Block: 4096   directory
Device: 7bh/123d    Inode: 1279171     Links: 2
Access: (1777/drwxrwxrwt)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2016-09-30 11:43:17.933467344 -0600
Modify: 2016-09-30 11:43:17.933467344 -0600
Change: 2016-09-30 11:43:17.933467344 -0600
 Birth: -
  • 1
    The <kbd> markup is used for a single key, rather than a whole command. It doesn't look any better this way, in my humble opinion.
    – user147505
    Sep 30, 2016 at 18:03

The du command can be called with an -x switch to ignore content from other mounted file systems.

The -k switch displays directory sizes in KB.

To display directories >~ 1MB in size.

du -xk / | awk ' $1 > 1000000 { print } '

You must log in to answer this question.

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