A comprehensive answer is: there are three things to understand, and then this all makes sense.
First, the source of a bind-mount is a dentry, not an inode. That is, you don't bind-mount an inode on a name; you bind-mount one dentry over another dentry. To see the difference, look at what happens if you mount different links to the same inode; the mounts are different, because the source dentries are different, even when the inode is the same:
root@penguin:/tmp# echo hello > a1
root@penguin:/tmp# ln a1 a2
root@penguin:/tmp# touch b1 b2
root@penguin:/tmp# mount -B a1 b1
root@penguin:/tmp# mount -B a2 b2
root@penguin:/tmp# ls -li a1 a2 b1 b2
9552271 -rw-r--r-- 2 root root 6 Aug 25 05:16 a1
9552271 -rw-r--r-- 2 root root 6 Aug 25 05:16 a2
9552271 -rw-r--r-- 2 root root 6 Aug 25 05:16 b1
9552271 -rw-r--r-- 2 root root 6 Aug 25 05:16 b2
root@penguin:/tmp# grep /tmp/ /proc/self/mountinfo
421 364 0:38 /lxd/.../rootfs/tmp/a1 /tmp/b1 rw,...
422 364 0:38 /lxd/.../rootfs/tmp/a2 /tmp/b2 rw,...
The second thing to understand is that when you mount something that is itself the target of an earlier bind-mount, that's the same dentry object as the source of the bind-mount (that's what bind-mounting is; one dentry over another.) So, if a1 is mounted on b1, then mounting b1 on c1 is exactly the same thing as mounting a1 on c1 because the names a1 and b1 refer to the same dentry.
The third thing to understand is that the kernel prohibits bind-mounting a deleted dentry because... of no good reason that I can see. It appears that an error check intended for the target of a mount (preventing mounting over a deleted dentry, which would make no sense to do, because you could never reference your new mount) is applying for no good reason to the source of the mount as well. That's this code here:
static struct mountpoint *get_mountpoint(struct dentry *dentry)
{
struct mountpoint *mp, *new = NULL;
int ret;
if (d_mountpoint(dentry)) {
/* might be worth a WARN_ON() */
if (d_unlinked(dentry))
return ERR_PTR(-ENOENT);
The consequence of these three facts is (continuing the shell session above) is ENOENT mounting b2 on c2 if a2 is deleted:
root@penguin:/tmp# touch c1 c2
root@penguin:/tmp# rm a2
root@penguin:/tmp# mount -B b1 c1
root@penguin:/tmp# mount -B b2 c2
mount: mount(2) failed: /tmp/c2: No such file or directory
root@penguin:/tmp#
This strikes me as a bug because your b2-on-c2 mount is valid if you delete a2 after the mount, and the order should not matter: either having a deleted dentry mounted on something is legal or it isn't, it should not matter when it became deleted. However, reasonable people disagree.
Thanks everyone.