fuse: share lookup state between submount and its parent
authorKrister Johansen <kjlx@templeofstupid.com>
Fri, 3 Nov 2023 17:39:47 +0000 (10:39 -0700)
committerMiklos Szeredi <mszeredi@redhat.com>
Mon, 4 Dec 2023 09:16:53 +0000 (10:16 +0100)
commitc4d361f66ac91db8fc65061a9671682f61f4ca9d
treec54776bd9b97f6f64fca8d7172d2cce78b0786ac
parent11ca77cdcca17cec909d2b97404ddacfec0acafd
fuse: share lookup state between submount and its parent

Fuse submounts do not perform a lookup for the nodeid that they inherit
from their parent.  Instead, the code decrements the nlookup on the
submount's fuse_inode when it is instantiated, and no forget is
performed when a submount root is evicted.

Trouble arises when the submount's parent is evicted despite the
submount itself being in use.  In this author's case, the submount was
in a container and deatched from the initial mount namespace via a
MNT_DEATCH operation.  When memory pressure triggered the shrinker, the
inode from the parent was evicted, which triggered enough forgets to
render the submount's nodeid invalid.

Since submounts should still function, even if their parent goes away,
solve this problem by sharing refcounted state between the parent and
its submount.  When all of the references on this shared state reach
zero, it's safe to forget the final lookup of the fuse nodeid.

Signed-off-by: Krister Johansen <kjlx@templeofstupid.com>
Cc: stable@vger.kernel.org
Fixes: 1866d779d5d2 ("fuse: Allow fuse_fill_super_common() for submounts")
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
fs/fuse/fuse_i.h
fs/fuse/inode.c