On 2/28/24 17:02, Miklos Szeredi wrote: > The root inode is assumed to be always hashed. Do not unhash the root > inode even if it is marked BAD. > > Fixes: 5d069dbe8aaf ("fuse: fix bad inode") > Cc: <stable@xxxxxxxxxxxxxxx> # v5.11 > Signed-off-by: Miklos Szeredi <mszeredi@xxxxxxxxxx> > --- > fs/fuse/fuse_i.h | 1 - > fs/fuse/inode.c | 7 +++++-- > 2 files changed, 5 insertions(+), 3 deletions(-) > > diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h > index 7bd3552b1e80..4ef6087f0e5c 100644 > --- a/fs/fuse/fuse_i.h > +++ b/fs/fuse/fuse_i.h > @@ -994,7 +994,6 @@ static inline bool fuse_stale_inode(const struct inode *inode, int generation, > > static inline void fuse_make_bad(struct inode *inode) > { > - remove_inode_hash(inode); > set_bit(FUSE_I_BAD, &get_fuse_inode(inode)->state); > } Hmm, what about callers like fuse_direntplus_link? It now never removes the inode hash for these? Depend on lookup/revalidate? Thanks, Bernd > > diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c > index c26a84439934..aa0614e8791c 100644 > --- a/fs/fuse/inode.c > +++ b/fs/fuse/inode.c > @@ -475,8 +475,11 @@ struct inode *fuse_iget(struct super_block *sb, u64 nodeid, > } else if (fuse_stale_inode(inode, generation, attr)) { > /* nodeid was reused, any I/O on the old inode should fail */ > fuse_make_bad(inode); > - iput(inode); > - goto retry; > + if (inode != d_inode(sb->s_root)) { > + remove_inode_hash(inode); > + iput(inode); > + goto retry; > + } > } > fi = get_fuse_inode(inode); > spin_lock(&fi->lock);