I initially noticed this on a modified kernel that returns EBADF when
the fusefs_readdir() code you modified is encountered. I then
downloaded the latest snapshot to see if I could replicate it and
noticed that it "hangs" the kernel (due to an endless loop). This bug
is not present in 6.1.

I used ktrace to see what system calls are being made and narrowed it
down to getcwd(3). I've noticed that there is no call to VOP_OPEN in
vfs_getcwd.c. Is that the correct behaviour?

I've tried your patch and had to modify it a bit so it compiles but it
doesn't solve the problem. The fusefs_file_open() call succeeds.
However, any call to getcwd(3) now fails with "No such file or
directory". I tested by creating a small test program that just makes
this function call.

On Mon, 9 Oct 2017 14:49:55 +0200
Martin Pieuchot <[email protected]> wrote:

> On 06/10/17(Fri) 12:26, Helg Bredow wrote:
> > To replicate this bug. 
> > 
> > 1. Mount a fuse files system (e.g. ntfs-3g)
> > 2. cd to a subdirectory (this is important)
> > 3. run make (you don't need a makefile)
> > 
> > I've traced the cause to fuse_vnops.c line 704, which is in turn called by 
> > getcwd().
> 
> How did you trace it?  Are you suggesting that the implied open/close
> which is not implemented is the problem?
> 
> If that's the case, you might want to play with the (untested) diff
> below:
> 
> Index: fuse/fuse_vnops.c
> ===================================================================
> RCS file: /cvs/src/sys/miscfs/fuse/fuse_vnops.c,v
> retrieving revision 1.33
> diff -u -p -r1.33 fuse_vnops.c
> --- fuse/fuse_vnops.c 7 Sep 2016 17:53:35 -0000       1.33
> +++ fuse/fuse_vnops.c 9 Oct 2017 12:42:13 -0000
> @@ -680,7 +680,7 @@ fusefs_readdir(void *v)
>       struct vnode *vp;
>       struct proc *p;
>       struct uio *uio;
> -     int error = 0, eofflag = 0;
> +     int error = 0, eofflag = 0, diropen = 0;
>  
>       vp = ap->a_vp;
>       uio = ap->a_uio;
> @@ -699,9 +699,13 @@ fusefs_readdir(void *v)
>               fbuf = fb_setup(0, ip->ufs_ino.i_number, FBT_READDIR, p);
>  
>               if (ip->fufh[FUFH_RDONLY].fh_type == FUFH_INVALID) {
> -                     /* TODO open the file */
> -                     fb_delete(fbuf);
> -                     return (error);
> +                     error = fusefs_file_open(fmp, ip, FUFH_RDONLY, O_RDONLY,
> +                         1, p);
> +                     if (error) {
> +                             fb_delete(fbuf);
> +                             break;
> +                     }
> +                     diropen = 1;
>               }
>               fbuf->fb_io_fd = ip->fufh[FUFH_RDONLY].fh_id;
>               fbuf->fb_io_off = uio->uio_offset;
> @@ -731,6 +735,9 @@ fusefs_readdir(void *v)
>  
>       if (!error && ap->a_eofflag != NULL)
>               *ap->a_eofflag = eofflag;
> +
> +     if (diropen)
> +             fusefs_file_close(fmp, ip, FUFH_RDONLY, O_RDONLY, 1, p);
>  
>       return (error);
>  }
> 


-- 
Helg <[email protected]>

Reply via email to