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:
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 /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.
P.S. Do keep in mind that some filesystems are network based - like NFS or CIFS - or are virtual - like procfs or sysfs and dont have a source block device. I don't know what will be returned as the device in the stat output, just fwiw.