On 16/10/17(Mon) 14:37, Helg Bredow wrote:
> [...] 
> Patch is below.

Do you mind explaining the problem and the solution you implemented?

Some comments below:

> Index: lib/libfuse/fuse.h
> ===================================================================
> RCS file: /cvs/src/lib/libfuse/fuse.h,v
> retrieving revision 1.12
> diff -u -p -r1.12 fuse.h
> --- lib/libfuse/fuse.h        20 Jan 2014 15:01:59 -0000      1.12
> +++ lib/libfuse/fuse.h        16 Oct 2017 14:21:06 -0000
> @@ -89,6 +89,7 @@ typedef int (*fuse_fill_dir_t)(void *, c
>      off_t);
>  
>  typedef struct fuse_dirhandle {
> +     struct fuse *fuse;

Are you sure you can save this across calls?

>       fuse_fill_dir_t filler;
>       void *buf;
>       int filled;
> Index: lib/libfuse/fuse_ops.c
> ===================================================================
> RCS file: /cvs/src/lib/libfuse/fuse_ops.c,v
> retrieving revision 1.26
> diff -u -p -r1.26 fuse_ops.c
> --- lib/libfuse/fuse_ops.c    7 Sep 2016 17:53:35 -0000       1.26
> +++ lib/libfuse/fuse_ops.c    16 Oct 2017 14:21:06 -0000
> @@ -217,17 +217,23 @@ static int
>  ifuse_fill_readdir(void *dh, const char *name, const struct stat *stbuf,
>      off_t off)
>  {
> +     struct fuse *f;
>       struct fuse_dirhandle *fd = dh;
> +     struct fuse_vnode *v;
>       struct fusebuf *fbuf;
>       struct dirent *dir;
>       uint32_t namelen;
>       uint32_t len;
>  
> +     f = fd->fuse;
>       fbuf = fd->buf;
>       namelen = strnlen(name, MAXNAMLEN);
>       len = GENERIC_DIRSIZ(namelen);
>  
> -     if (fd->full || (fbuf->fb_len + len > fd->size)) {
> +     if (fd->full)
> +             return (0);
> +
> +     if (fbuf->fb_len + len > fd->size) {
>               fd->full = 1;
>               return (0);

Why is this chunk necessary?  Is it part of the fix?

>       }
> @@ -242,13 +248,21 @@ ifuse_fill_readdir(void *dh, const char 
>       if (off)
>               fd->filled = 0;
>  
> -     if (stbuf) {
> -             dir->d_fileno = stbuf->st_ino;
> +     /* TODO Add support for use_ino and readdir_ino */
> +     v = get_vn_by_name_and_parent(f, (uint8_t *)name, fbuf->fb_ino);
> +     if (v == NULL) {
> +             if (strcmp(name, ".") == 0)
> +                     dir->d_fileno = fbuf->fb_ino;
> +             else
> +                     dir->d_fileno = 0xffffffff;
> +     } else
> +             dir->d_fileno = v->ino;
> +
> +     if (stbuf)
>               dir->d_type = IFTODT(stbuf->st_mode);
> -     } else {
> -             dir->d_fileno = 0xffffffff;
> +     else
>               dir->d_type = DT_UNKNOWN;
> -     }
> +
>       dir->d_reclen = len;
>       dir->d_off = off + len;         /* XXX */
>       strlcpy(dir->d_name, name, sizeof(dir->d_name));
> @@ -295,7 +309,7 @@ ifuse_ops_readdir(struct fuse *f, struct
>       ffi.fh = fbuf->fb_io_fd;
>       offset = fbuf->fb_io_off;
>       size = fbuf->fb_io_len;
> -     startsave = 0;
> +     startsave = offset;
>  
>       fbuf->fb_dat = calloc(1, size);
>  
> @@ -319,6 +333,8 @@ ifuse_ops_readdir(struct fuse *f, struct
>               vn->fd->size = size;
>               vn->fd->off = offset;
>               vn->fd->idx = 0;
> +             vn->fd->fuse = f;
> +             vn->fd->start = offset;
>               startsave = vn->fd->start;
>  
>               realname = build_realname(f, vn->ino);
> @@ -345,7 +361,8 @@ ifuse_ops_readdir(struct fuse *f, struct
>       if (fbuf->fb_err) {
>               fbuf->fb_len = 0;
>               vn->fd->filled = 1;
> -     }
> +     } else if (vn->fd->full && fbuf->fb_len == 0)
> +             fbuf->fb_err = -ENOBUFS;
>  
>       if (fbuf->fb_len == 0)
>               free(fbuf->fb_dat);
> Index: sys/miscfs/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
> --- sys/miscfs/fuse/fuse_vnops.c      7 Sep 2016 17:53:35 -0000       1.33
> +++ sys/miscfs/fuse/fuse_vnops.c      16 Oct 2017 14:21:17 -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;
> @@ -695,14 +695,18 @@ fusefs_readdir(void *v)
>       if (uio->uio_resid < sizeof(struct dirent))
>               return (EINVAL);
>  
> +     if (ip->fufh[FUFH_RDONLY].fh_type == FUFH_INVALID) {
> +             error = fusefs_file_open(fmp, ip, FUFH_RDONLY, O_RDONLY, 1, p);
> +             if (error) {
> +                     fb_delete(fbuf);
> +                     goto out;

You can use return (error) here and remove the goto.

> +             }
> +             diropen = 1;
> +     }
> +
>       while (uio->uio_resid > 0) {
>               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);
> -             }
>               fbuf->fb_io_fd = ip->fufh[FUFH_RDONLY].fh_id;
>               fbuf->fb_io_off = uio->uio_offset;
>               fbuf->fb_io_len = MIN(uio->uio_resid, fmp->max_read);
> @@ -710,6 +714,11 @@ fusefs_readdir(void *v)
>               error = fb_queue(fmp->dev, fbuf);
>  
>               if (error) {
> +                     /* Not a real error, dirent was larger than residual
> +                        space left in buffer. Return as normal. */

s/Not a real error,//

s/return as normal.//

And look a style(9) for the comment formatting.

> +                     if (error == ENOBUFS && fbuf->fb_len == 0)
> +                             error = 0;
> +
>                       fb_delete(fbuf);
>                       break;
>               }
> @@ -732,6 +741,10 @@ 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);
> +
> +out:
>       return (error);
>  }
>  
> 
> 

Reply via email to