[Virtio-fs] [PATCH] virtiofsd: Don't assume header layout

Stefan Hajnoczi stefanha at redhat.com
Thu Mar 11 15:55:45 UTC 2021


On Thu, Mar 11, 2021 at 02:58:09PM +0000, Dr. David Alan Gilbert wrote:
> * Stefan Hajnoczi (stefanha at redhat.com) wrote:
> > On Thu, Mar 04, 2021 at 05:45:36PM +0000, Dr. David Alan Gilbert (git) wrote:
> > > From: "Dr. David Alan Gilbert" <dgilbert at redhat.com>
> > > 
> > > virtiofsd incorrectly assumed a fixed set of header layout in the virt
> > > queue; assuming that the fuse and write headers were conveniently
> > > separated from the data;  the spec doesn't allow us to take that
> > > convenience, so fix it up to deal with it the hard way.
> > > 
> > > Signed-off-by: Dr. David Alan Gilbert <dgilbert at redhat.com>
> > > ---
> > >  tools/virtiofsd/fuse_virtio.c | 84 ++++++++++++++++++++++++++---------
> > >  1 file changed, 63 insertions(+), 21 deletions(-)
> > > 
> > > diff --git a/tools/virtiofsd/fuse_virtio.c b/tools/virtiofsd/fuse_virtio.c
> > > index 523ee64fb7..55e2e057ec 100644
> > > --- a/tools/virtiofsd/fuse_virtio.c
> > > +++ b/tools/virtiofsd/fuse_virtio.c
> > > @@ -129,18 +129,55 @@ static void fv_panic(VuDev *dev, const char *err)
> > >   * Copy from an iovec into a fuse_buf (memory only)
> > >   * Caller must ensure there is space
> > >   */
> > > -static void copy_from_iov(struct fuse_buf *buf, size_t out_num,
> > > -                          const struct iovec *out_sg)
> > > +static size_t copy_from_iov(struct fuse_buf *buf, size_t out_num,
> > > +                            const struct iovec *out_sg,
> > > +                            size_t max)
> > >  {
> > >      void *dest = buf->mem;
> > > +    size_t copied = 0;
> > >  
> > > -    while (out_num) {
> > > +    while (out_num && max) {
> > >          size_t onelen = out_sg->iov_len;
> > > +        onelen = MIN(onelen, max);
> > >          memcpy(dest, out_sg->iov_base, onelen);
> > >          dest += onelen;
> > > +        copied += onelen;
> > >          out_sg++;
> > >          out_num--;
> > > +        max -= onelen;
> > >      }
> > > +
> > > +    return copied;
> > > +}
> > > +
> > > +/*
> > > + * Skip 'skip' bytes in the iov; 'sg_1stindex' is set as
> > > + * the index for the 1st iovec to read data from, and
> > > + * 'sg_1stskip' is the number of bytes to skip in that entry.
> > > + *
> > > + * Returns True if there are at least 'skip' bytes in the iovec
> > > + *
> > > + */
> > > +static bool skip_iov(const struct iovec *sg, size_t sg_size,
> > > +                     size_t skip,
> > > +                     size_t *sg_1stindex, size_t *sg_1stskip)
> > > +{
> > > +    size_t vec;
> > > +
> > > +    for (vec = 0; vec < sg_size; vec++) {
> > > +        if (sg[vec].iov_len > skip) {
> > > +            *sg_1stskip = skip;
> > > +            *sg_1stindex = vec;
> > > +
> > > +            return true;
> > > +        }
> > > +
>  (1)         skip -= sg[vec].iov_len;
> > > +    }
> > > +
>  (2)     *sg_1stindex = vec;
> > > +    *sg_1stskip = 0;
>  (3)     return skip == 0;
> > >  }
> > 
> > This comment does not match the code: "Returns True if there are at
> > least 'skip' bytes in the iovec". When skip == iov_length(sg, sg_size)
> > the function returns false.
> 
> I'm not seeing how; in that case, it'll loop around executing (1) for
> each vector, so skip will reduce, then it falls out of the for loop
> and if it was equal to the size of the vector, (1) would have subtracted
> the whole vector out, so skip would now be 0, hence the 'skip == 0' at 2 and
> so it should return true.

You're right. I misread the code!

Stefan
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://listman.redhat.com/archives/virtio-fs/attachments/20210311/2042e9fc/attachment.sig>


More information about the Virtio-fs mailing list