Quantcast

[PATCH v3] fuse: drop dentry on failed revalidate

classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[PATCH v3] fuse: drop dentry on failed revalidate

Anand Avati-6
Consider the following sequence of operations:

  // mount same backend at two places

  # mount -t fuse <some_src> /mnt1
  # mount -t fuse <same_src> /mnt2

  // create a directory chain from 1

  $ mkdir -p /mnt1/a/b

  // load it in 2's cache

  $ stat /mnt2/a/b     # load it in cache

  // recreate same names from 1

  $ rm -rf /mnt1/a
  $ mkdir -p /mnt1/a/b

  // sleep long enough for entry_timeout to expire

  $ sleep 5

  // access /mnt2/a/b from two threads in parallel

  $ stat /mnt2/a/b & stat /mnt2/a/b

Depending on the race, none/either/both of the commands
executed in the last step can fail.

This is because both the stat command threads execute the
resolver in parallel.

- The resolver function lookup_fast() will acquire the dentry
  (of /mnt2/a) reference with __d_lookup()

- Call to d_revalidate() on the just acquired dentry will fail,
  (i.e return 0) as FUSE gets a new nodeid from the server.

- In the mean time another resolver thread enters lookup_fast()
  and acquires the dentry of /mnt2/a with __d_lookup(), effectively
  making dentry->d_count > 1 [+ child refs]

- Now when first thread calls d_invalidate() because of the failed
  d_revalidate(), d_invalidate() will find that even after calling
  shrink_dcache_parent() we are left with d_count > 1, and fails
  d_invalidate() with EBUSY.

- The failed d_invalidate() makes the resolver use this "stale" dentry
  as the result of this walk_component() call -- even though it just
  witnessed d_revalidate() fail on it, only because d_invalidate()
  could not succeed because of an innocent concurrent resolver in
  progress.

- Using the stale dentry (and inode), the call progress and stubles
  with an error as the FUSE server is presented with a dead inode.

- The other thread would fail in d_revalidate() too, and depending
  on the progress relaitvely made between the two, the second
  thread's d_invalidate() might get an EBUSY too, and stuble in the
  same way as the first thread.

If the same stat commands were issued serially, both would succeed.

NFS is faced with a similar situation as FUSE (and in many other ways
in general too) and it checks for a submounts and conditionally calls
d_drop(). The call to d_drop() within ->d_revalidate() guarantees the
success of d_invalidate(), and a fresh lookup would be issued there on.

Signed-off-by: Anand Avati <[hidden email]>
---
Fixed embarrassing typo!

 fs/fuse/dir.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index a1d9047..83c217e 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -226,6 +226,10 @@ static int fuse_dentry_revalidate(struct dentry *entry, unsigned int flags)
  if (!err) {
  struct fuse_inode *fi = get_fuse_inode(inode);
  if (outarg.nodeid != get_node_id(inode)) {
+ if (!have_submounts(entry)) {
+ shrink_dcache_parent(entry);
+ d_drop(entry);
+ }
  fuse_queue_forget(fc, forget, outarg.nodeid, 1);
  return 0;
  }
--
1.7.12.1


------------------------------------------------------------------------------
Everyone hates slow websites. So do we.
Make your web apps faster with AppDynamics
Download AppDynamics Lite for free today:
http://p.sf.net/sfu/appdyn_d2d_mar
_______________________________________________
fuse-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/fuse-devel
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [PATCH v3] fuse: drop dentry on failed revalidate

Matthew Farrellee-2
On 03/23/2013 01:35 PM, Anand Avati wrote:

> Consider the following sequence of operations:
>
>    // mount same backend at two places
>
>    # mount -t fuse <some_src> /mnt1
>    # mount -t fuse <same_src> /mnt2
>
>    // create a directory chain from 1
>
>    $ mkdir -p /mnt1/a/b
>
>    // load it in 2's cache
>
>    $ stat /mnt2/a/b     # load it in cache
>
>    // recreate same names from 1
>
>    $ rm -rf /mnt1/a
>    $ mkdir -p /mnt1/a/b
>
>    // sleep long enough for entry_timeout to expire
>
>    $ sleep 5
>
>    // access /mnt2/a/b from two threads in parallel
>
>    $ stat /mnt2/a/b & stat /mnt2/a/b
>
> Depending on the race, none/either/both of the commands
> executed in the last step can fail.
>
> This is because both the stat command threads execute the
> resolver in parallel.
>
> - The resolver function lookup_fast() will acquire the dentry
>    (of /mnt2/a) reference with __d_lookup()
>
> - Call to d_revalidate() on the just acquired dentry will fail,
>    (i.e return 0) as FUSE gets a new nodeid from the server.
>
> - In the mean time another resolver thread enters lookup_fast()
>    and acquires the dentry of /mnt2/a with __d_lookup(), effectively
>    making dentry->d_count > 1 [+ child refs]
>
> - Now when first thread calls d_invalidate() because of the failed
>    d_revalidate(), d_invalidate() will find that even after calling
>    shrink_dcache_parent() we are left with d_count > 1, and fails
>    d_invalidate() with EBUSY.
>
> - The failed d_invalidate() makes the resolver use this "stale" dentry
>    as the result of this walk_component() call -- even though it just
>    witnessed d_revalidate() fail on it, only because d_invalidate()
>    could not succeed because of an innocent concurrent resolver in
>    progress.
>
> - Using the stale dentry (and inode), the call progress and stubles
>    with an error as the FUSE server is presented with a dead inode.
>
> - The other thread would fail in d_revalidate() too, and depending
>    on the progress relaitvely made between the two, the second
>    thread's d_invalidate() might get an EBUSY too, and stuble in the
>    same way as the first thread.
>
> If the same stat commands were issued serially, both would succeed.
>
> NFS is faced with a similar situation as FUSE (and in many other ways
> in general too) and it checks for a submounts and conditionally calls
> d_drop(). The call to d_drop() within ->d_revalidate() guarantees the
> success of d_invalidate(), and a fresh lookup would be issued there on.
>
> Signed-off-by: Anand Avati <[hidden email]>
> ---
> Fixed embarrassing typo!
>
>   fs/fuse/dir.c | 4 ++++
>   1 file changed, 4 insertions(+)
>
> diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
> index a1d9047..83c217e 100644
> --- a/fs/fuse/dir.c
> +++ b/fs/fuse/dir.c
> @@ -226,6 +226,10 @@ static int fuse_dentry_revalidate(struct dentry *entry, unsigned int flags)
>   if (!err) {
>   struct fuse_inode *fi = get_fuse_inode(inode);
>   if (outarg.nodeid != get_node_id(inode)) {
> + if (!have_submounts(entry)) {
> + shrink_dcache_parent(entry);
> + d_drop(entry);
> + }
>   fuse_queue_forget(fc, forget, outarg.nodeid, 1);
>   return 0;
>   }
>

I've tested this patch against a 3.9.0-rc5 kernel provided by Brian
Foster. The patch successfully allows my more complicated testing to
proceed as well as the example test Avati provided, which I've
reproduced below.

Test script -

ifconfig lo:1 1.1.1.1 netmask 255.255.255.0 up
SELF=1.1.1.1
VOL=gv_test0
MNT=/mnt/glusterfs
EXPORT=/export/glusterfs

mkdir -p $EXPORT
truncate -s 20G $EXPORT.raw
mkfs.xfs -f $EXPORT.raw
mount -o loop $EXPORT.raw $EXPORT

service glusterd start
gluster volume create $VOL $SELF:$EXPORT
gluster volume start $VOL

mkdir -p $MNT.0; mount -t glusterfs $SELF:$VOL $MNT.0
mkdir -p $MNT.1; mount -t glusterfs $SELF:$VOL $MNT.1

mkdir -p $MNT.0/a/b
stat     $MNT.1/a/b
rm -rf   $MNT.0/a
mkdir -p $MNT.0/a/b
sleep 5
stat $MNT.1/a/b & stat $MNT.1/a/b

A 3.9.0-rc5 kernel w/o Avati's patch results in -

stat: cannot stat `/mnt/glusterfs.1/a/b': No such file or directory
stat: cannot stat `/mnt/glusterfs.1/a/b': No such file or directory

A 3.9.0-rc5 kernel w/ Avati's patch -

   File: `/mnt/glusterfs.1/a/b'
   Size: 6             Blocks: 0          IO Block: 131072 directory
Device: 19h/25d    Inode: 13544355986590801786  Links: 2
   File: `/mnt/glusterfs.1/a/b'
   Size: 6             Blocks: 0          IO Block: 131072 directory
Device: 19h/25d    Inode: 13544355986590801786  Links: 2
Access: (0755/drwxr-xr-x)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2013-04-05 09:51:58.160972210 -0400
Modify: 2013-04-05 09:51:58.160972210 -0400
Change: 2013-04-05 09:51:58.160972210 -0400
Access: (0755/drwxr-xr-x)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2013-04-05 09:51:58.160972210 -0400
Modify: 2013-04-05 09:51:58.160972210 -0400
Change: 2013-04-05 09:51:58.160972210 -0400


Switching between test configurations (w/ & w/o patch) was done by -
  . umounting $MNT.0 & $MNT.1
  . rmmod fuse
  . changing a symlink to fuse.ko
  . modprobe fuse
  . mounting $MNT.0 & $MNT.1

# ls -al /lib/modules/3.9.0-rc5+/kernel/fs/fuse/*.ko
-rw-r--r--. 1 root root  267952 Apr  4 14:44
/lib/modules/3.9.0-rc5+/kernel/fs/fuse/cuse.ko
lrwxrwxrwx. 1 root root      15 Apr  5 09:51
/lib/modules/3.9.0-rc5+/kernel/fs/fuse/fuse.ko -> fuse-patched.ko
-rw-r--r--. 1 root root 1673236 Apr  5 09:22
/lib/modules/3.9.0-rc5+/kernel/fs/fuse/fuse-orig.ko
-rw-r--r--. 1 root root 1673667 Apr  4 14:44
/lib/modules/3.9.0-rc5+/kernel/fs/fuse/fuse-patched.ko


Best,


matt


------------------------------------------------------------------------------
Minimize network downtime and maximize team effectiveness.
Reduce network management and security costs.Learn how to hire
the most talented Cisco Certified professionals. Visit the
Employer Resources Portal
http://www.cisco.com/web/learning/employer_resources/index.html
_______________________________________________
fuse-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/fuse-devel
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [PATCH v3] fuse: drop dentry on failed revalidate

Anand Avati-4
Miklos,
 Any comments on this patch and approach?

Thanks!
Avati

On Fri, Apr 5, 2013 at 7:43 AM, Matthew Farrellee <[hidden email]> wrote:

> On 03/23/2013 01:35 PM, Anand Avati wrote:
> > Consider the following sequence of operations:
> >
> >    // mount same backend at two places
> >
> >    # mount -t fuse <some_src> /mnt1
> >    # mount -t fuse <same_src> /mnt2
> >
> >    // create a directory chain from 1
> >
> >    $ mkdir -p /mnt1/a/b
> >
> >    // load it in 2's cache
> >
> >    $ stat /mnt2/a/b     # load it in cache
> >
> >    // recreate same names from 1
> >
> >    $ rm -rf /mnt1/a
> >    $ mkdir -p /mnt1/a/b
> >
> >    // sleep long enough for entry_timeout to expire
> >
> >    $ sleep 5
> >
> >    // access /mnt2/a/b from two threads in parallel
> >
> >    $ stat /mnt2/a/b & stat /mnt2/a/b
> >
> > Depending on the race, none/either/both of the commands
> > executed in the last step can fail.
> >
> > This is because both the stat command threads execute the
> > resolver in parallel.
> >
> > - The resolver function lookup_fast() will acquire the dentry
> >    (of /mnt2/a) reference with __d_lookup()
> >
> > - Call to d_revalidate() on the just acquired dentry will fail,
> >    (i.e return 0) as FUSE gets a new nodeid from the server.
> >
> > - In the mean time another resolver thread enters lookup_fast()
> >    and acquires the dentry of /mnt2/a with __d_lookup(), effectively
> >    making dentry->d_count > 1 [+ child refs]
> >
> > - Now when first thread calls d_invalidate() because of the failed
> >    d_revalidate(), d_invalidate() will find that even after calling
> >    shrink_dcache_parent() we are left with d_count > 1, and fails
> >    d_invalidate() with EBUSY.
> >
> > - The failed d_invalidate() makes the resolver use this "stale" dentry
> >    as the result of this walk_component() call -- even though it just
> >    witnessed d_revalidate() fail on it, only because d_invalidate()
> >    could not succeed because of an innocent concurrent resolver in
> >    progress.
> >
> > - Using the stale dentry (and inode), the call progress and stubles
> >    with an error as the FUSE server is presented with a dead inode.
> >
> > - The other thread would fail in d_revalidate() too, and depending
> >    on the progress relaitvely made between the two, the second
> >    thread's d_invalidate() might get an EBUSY too, and stuble in the
> >    same way as the first thread.
> >
> > If the same stat commands were issued serially, both would succeed.
> >
> > NFS is faced with a similar situation as FUSE (and in many other ways
> > in general too) and it checks for a submounts and conditionally calls
> > d_drop(). The call to d_drop() within ->d_revalidate() guarantees the
> > success of d_invalidate(), and a fresh lookup would be issued there on.
> >
> > Signed-off-by: Anand Avati <[hidden email]>
> > ---
> > Fixed embarrassing typo!
> >
> >   fs/fuse/dir.c | 4 ++++
> >   1 file changed, 4 insertions(+)
> >
> > diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
> > index a1d9047..83c217e 100644
> > --- a/fs/fuse/dir.c
> > +++ b/fs/fuse/dir.c
> > @@ -226,6 +226,10 @@ static int fuse_dentry_revalidate(struct dentry
> *entry, unsigned int flags)
> >               if (!err) {
> >                       struct fuse_inode *fi = get_fuse_inode(inode);
> >                       if (outarg.nodeid != get_node_id(inode)) {
> > +                             if (!have_submounts(entry)) {
> > +                                     shrink_dcache_parent(entry);
> > +                                     d_drop(entry);
> > +                             }
> >                               fuse_queue_forget(fc, forget,
> outarg.nodeid, 1);
> >                               return 0;
> >                       }
> >
>
> I've tested this patch against a 3.9.0-rc5 kernel provided by Brian
> Foster. The patch successfully allows my more complicated testing to
> proceed as well as the example test Avati provided, which I've
> reproduced below.
>
> Test script -
>
> ifconfig lo:1 1.1.1.1 netmask 255.255.255.0 up
> SELF=1.1.1.1
> VOL=gv_test0
> MNT=/mnt/glusterfs
> EXPORT=/export/glusterfs
>
> mkdir -p $EXPORT
> truncate -s 20G $EXPORT.raw
> mkfs.xfs -f $EXPORT.raw
> mount -o loop $EXPORT.raw $EXPORT
>
> service glusterd start
> gluster volume create $VOL $SELF:$EXPORT
> gluster volume start $VOL
>
> mkdir -p $MNT.0; mount -t glusterfs $SELF:$VOL $MNT.0
> mkdir -p $MNT.1; mount -t glusterfs $SELF:$VOL $MNT.1
>
> mkdir -p $MNT.0/a/b
> stat     $MNT.1/a/b
> rm -rf   $MNT.0/a
> mkdir -p $MNT.0/a/b
> sleep 5
> stat $MNT.1/a/b & stat $MNT.1/a/b
>
> A 3.9.0-rc5 kernel w/o Avati's patch results in -
>
> stat: cannot stat `/mnt/glusterfs.1/a/b': No such file or directory
> stat: cannot stat `/mnt/glusterfs.1/a/b': No such file or directory
>
> A 3.9.0-rc5 kernel w/ Avati's patch -
>
>    File: `/mnt/glusterfs.1/a/b'
>    Size: 6             Blocks: 0          IO Block: 131072 directory
> Device: 19h/25d    Inode: 13544355986590801786  Links: 2
>    File: `/mnt/glusterfs.1/a/b'
>    Size: 6             Blocks: 0          IO Block: 131072 directory
> Device: 19h/25d    Inode: 13544355986590801786  Links: 2
> Access: (0755/drwxr-xr-x)  Uid: (    0/    root)   Gid: (    0/    root)
> Access: 2013-04-05 09:51:58.160972210 -0400
> Modify: 2013-04-05 09:51:58.160972210 -0400
> Change: 2013-04-05 09:51:58.160972210 -0400
> Access: (0755/drwxr-xr-x)  Uid: (    0/    root)   Gid: (    0/    root)
> Access: 2013-04-05 09:51:58.160972210 -0400
> Modify: 2013-04-05 09:51:58.160972210 -0400
> Change: 2013-04-05 09:51:58.160972210 -0400
>
>
> Switching between test configurations (w/ & w/o patch) was done by -
>   . umounting $MNT.0 & $MNT.1
>   . rmmod fuse
>   . changing a symlink to fuse.ko
>   . modprobe fuse
>   . mounting $MNT.0 & $MNT.1
>
> # ls -al /lib/modules/3.9.0-rc5+/kernel/fs/fuse/*.ko
> -rw-r--r--. 1 root root  267952 Apr  4 14:44
> /lib/modules/3.9.0-rc5+/kernel/fs/fuse/cuse.ko
> lrwxrwxrwx. 1 root root      15 Apr  5 09:51
> /lib/modules/3.9.0-rc5+/kernel/fs/fuse/fuse.ko -> fuse-patched.ko
> -rw-r--r--. 1 root root 1673236 Apr  5 09:22
> /lib/modules/3.9.0-rc5+/kernel/fs/fuse/fuse-orig.ko
> -rw-r--r--. 1 root root 1673667 Apr  4 14:44
> /lib/modules/3.9.0-rc5+/kernel/fs/fuse/fuse-patched.ko
>
>
> Best,
>
>
> matt
>
>
>
> ------------------------------------------------------------------------------
> Minimize network downtime and maximize team effectiveness.
> Reduce network management and security costs.Learn how to hire
> the most talented Cisco Certified professionals. Visit the
> Employer Resources Portal
> http://www.cisco.com/web/learning/employer_resources/index.html
> _______________________________________________
> fuse-devel mailing list
> [hidden email]
> https://lists.sourceforge.net/lists/listinfo/fuse-devel
>
------------------------------------------------------------------------------
Precog is a next-generation analytics platform capable of advanced
analytics on semi-structured data. The platform includes APIs for building
apps and a phenomenal toolset for data science. Developers can use
our toolset for easy data analysis & visualization. Get a free account!
http://www2.precog.com/precogplatform/slashdotnewsletter
_______________________________________________
fuse-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/fuse-devel
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [PATCH v3] fuse: drop dentry on failed revalidate

Miklos Szeredi
On Thu, Apr 11, 2013 at 4:58 PM, Anand Avati <[hidden email]> wrote:
> Miklos,
>  Any comments on this patch and approach?

I see the bug, and I see the "solution" that NFS uses.  But that
d_drop() on a subtree looks dangerous, and it would be nice to see
this improved for both NFS and FUSE.  As a minimum, we should do
d_drop() an all descendants as well, I think.  And the d_mountpoint()
check should be atomic with d_drop() wrt. a mount creation.

Thanks,
Miklos

------------------------------------------------------------------------------
Precog is a next-generation analytics platform capable of advanced
analytics on semi-structured data. The platform includes APIs for building
apps and a phenomenal toolset for data science. Developers can use
our toolset for easy data analysis & visualization. Get a free account!
http://www2.precog.com/precogplatform/slashdotnewsletter
_______________________________________________
fuse-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/fuse-devel
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [PATCH v3] fuse: drop dentry on failed revalidate

Anand Avati-6

On Apr 11, 2013, at 8:47 AM, Miklos Szeredi <[hidden email]> wrote:

> On Thu, Apr 11, 2013 at 4:58 PM, Anand Avati <[hidden email]> wrote:
>> Miklos,
>> Any comments on this patch and approach?
>
> I see the bug, and I see the "solution" that NFS uses.  But that
> d_drop() on a subtree looks dangerous, and it would be nice to see
> this improved for both NFS and FUSE.  As a minimum, we should do
> d_drop() an all descendants as well, I think.

By descendants, do you mean all the dentries in the subtree? Do you mean not just shrink_dcache_parent, but call d_drop on every dentry in the subtree, and atomically after checking for no submounts?

Thanks,
Avati


------------------------------------------------------------------------------
Precog is a next-generation analytics platform capable of advanced
analytics on semi-structured data. The platform includes APIs for building
apps and a phenomenal toolset for data science. Developers can use
our toolset for easy data analysis & visualization. Get a free account!
http://www2.precog.com/precogplatform/slashdotnewsletter
_______________________________________________
fuse-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/fuse-devel
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [PATCH v3] fuse: drop dentry on failed revalidate

Bob Lemon
I have been stung by this bug, also. What is the status of this patch?

Miklos acknowledges that there is a bug but I don't see that any version of FUSE that has been fixed (at least not by this patch).

Have other people patched their versions of FUSE with this patch? Has it fixed the bug?
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [PATCH v3] fuse: drop dentry on failed revalidate

Anand Avati-4
The fix has been available in upstream kernel since at least v3.12-rc1

Avati


On Fri, Sep 27, 2013 at 2:23 PM, Bob Lemon <[hidden email]> wrote:

> I have been stung by this bug, also. What is the status of this patch?
>
> Miklos acknowledges that there is a bug but I don't see that any version of
> FUSE that has been fixed (at least not by this patch).
>
> Have other people patched their versions of FUSE with this patch? Has it
> fixed the bug?
>
>
>
> --
> View this message in context:
> http://fuse.996288.n3.nabble.com/PATCH-v3-fuse-drop-dentry-on-failed-revalidate-tp11273p11767.html
> Sent from the Fuse mailing list archive at Nabble.com.
>
>
> ------------------------------------------------------------------------------
> October Webinars: Code for Performance
> Free Intel webinars can help you accelerate application performance.
> Explore tips for MPI, OpenMP, advanced profiling, and more. Get the most
> from
> the latest Intel processors and coprocessors. See abstracts and register >
> http://pubads.g.doubleclick.net/gampad/clk?id=60133471&iu=/4140/ostg.clktrk
> _______________________________________________
> fuse-devel mailing list
> [hidden email]
> https://lists.sourceforge.net/lists/listinfo/fuse-devel
>
------------------------------------------------------------------------------
October Webinars: Code for Performance
Free Intel webinars can help you accelerate application performance.
Explore tips for MPI, OpenMP, advanced profiling, and more. Get the most from
the latest Intel processors and coprocessors. See abstracts and register >
http://pubads.g.doubleclick.net/gampad/clk?id=60133471&iu=/4140/ostg.clktrk
_______________________________________________
fuse-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/fuse-devel
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [PATCH v3] fuse: drop dentry on failed revalidate

Bob Lemon
Hi,

Thank you for the quick response. We tried to patch our kernel with the original proposed fix and unfortunately it didn’t work for us. Perhaps we are seeing a different “bug” which simply appears to be the same as the one you have encountered.

We are currently using FUSE 2.8.5 running on a 2.6.32-279 kernel. The application is attempting to delete directories which are not empty. Our FUSE filesystem returns ENOTEMPTY and then subsequent lookups along that path trigger the FUSE kernel to return EBUSY in the fuse_d_add_directory call.

static struct dentry *fuse_d_add_directory(struct dentry *entry,
                                           struct inode *inode)
{
        struct dentry *alias = d_find_alias(inode);
        if (alias && !(alias->d_flags & DCACHE_DISCONNECTED)) {
                /* This tries to shrink the subtree below alias */
                fuse_invalidate_entry(alias);
                dput(alias);
                if (!list_empty(&inode->i_dentry))
                {
                    return ERR_PTR(-EBUSY)




At this point we don’t have enough experience with the VFS or FUSE kernel module to quite grasp what is happening. Our FUSE system is multi-threaded and we have observed that if we change to single threaded mode the error does not occur. Thus, the problem appeared to be the exact same you had described earlier this year. But again, the patch you provided doesn’t seem to fix the problem for us. Do you have any possible suggestions?

Many thanks in advance.
Loading...