On Thu, 27 Jul 2023 at 13:37, Nikolaus Rath <Nikolaus@xxxxxxxx> wrote: > > On Jul 27 2023, Miklos Szeredi via fuse-devel <fuse-devel@xxxxxxxxxxxxxxxxxxxxx> wrote: > > On Wed, 26 Jul 2023 at 20:09, Nikolaus Rath <Nikolaus@xxxxxxxx> wrote: > >> > >> Hello, > >> > >> It seems to me that fuse_notify_delete > >> (https://elixir.bootlin.com/linux/v6.1/source/fs/fuse/dev.c#L1512) fails > >> with ENOTEMPTY if there is a pending FORGET request for a directory > >> entry within. Is that correct? > > > > It's bug if it does that. > > > > The code related to NOTIFY_DELETE in fuse_reverse_inval_entry() seems > > historic. It's supposed to be careful about mountpoints and > > referenced dentries, but d_invalidate() should have already gotten all > > that out of the way and left an unhashed dentry without any submounts > > or children. The checks just seem redundant, but not harmful. > > > > If you are managing to trigger the ENOTEMPTY case, then something > > strange is going on, and we need to investigate. > > I can trigger this reliable on kernel 6.1.0-10-amd64 (Debian stable) > with this sequence of operations: > > $ mkdir test > $ echo foo > test/bar > $ Trigger removal of test/bar and then test within the filesystem (not > through unlink()/rmdir() but out-of-band) Issue is that "test/.__s3ql__ctrl__" is still positive. I.e. the directory is *really* not empty. I thought that that's okay, and d_invalidate will recursively unhash dentries, but that's not the case. d_invalidate removes submounts but only unhashes the root of the subtree, leaving the rest intact. So the solution here is to invoke NOTIFY_DELETE on "test/.__s3ql__ctrl__" before doing it on "test" itself. I don't think NOTIFY_DELETE was ever meant to be a recursive delete. This is indicated by the simple_empty() check, which will fail if any positive child dentries remain. Thanks, Miklos