Il dom 15 dic 2024, 03:53 ronnie sahlberg <ronniesahlb...@gmail.com> ha scritto:
> Maybe something like this: > --- > diff --git a/block/nfs.c b/block/nfs.c > index 0500f60c08..f768ee0c4b 100644 > --- a/block/nfs.c > +++ b/block/nfs.c > @@ -268,11 +268,18 @@ static int coroutine_fn > nfs_co_preadv(BlockDriverState *bs, int64_t offset, > NFSRPC task; > > nfs_co_init_task(bs, &task); > - task.iov = iov; > > WITH_QEMU_LOCK_GUARD(&client->mutex) { > +#ifdef LIBNFS_API_V2 > + if (nfs_pread_async(client->context, client->fh, > + iov->iov[0].iov_base, > + bytes > iov->iov[0].iov_len ? > iov->iov[0].iov_len : bytes, > Ah, this was not clear—can the buffer be shorter than the command's transfer length? Paolo > + offset, nfs_co_generic_cb, &task) != 0) { > +#else > + task.iov = iov; > if (nfs_pread_async(client->context, client->fh, > offset, bytes, nfs_co_generic_cb, &task) != > 0) { > +#endif > return -ENOMEM; > } > > @@ -317,9 +324,15 @@ static int coroutine_fn > nfs_co_pwritev(BlockDriverState *bs, int64_t offset, > } > > WITH_QEMU_LOCK_GUARD(&client->mutex) { > +#ifdef LIBNFS_API_V2 > + if (nfs_pwrite_async(client->context, client->fh, > + buf, bytes, offset, > + nfs_co_generic_cb, &task) != 0) { > +#else > if (nfs_pwrite_async(client->context, client->fh, > offset, bytes, buf, > nfs_co_generic_cb, &task) != 0) { > +#endif > if (my_buffer) { > g_free(buf); > } > --- > > On Sun, 15 Dec 2024 at 12:04, ronnie sahlberg <ronniesahlb...@gmail.com> > wrote: > > > > On Sun, 15 Dec 2024 at 11:58, ronnie sahlberg <ronniesahlb...@gmail.com> > wrote: > > > > > > On Sun, 15 Dec 2024 at 11:33, Stefan Hajnoczi <stefa...@gmail.com> > wrote: > > > > > > > > On Fri, 13 Dec 2024 at 11:04, Paolo Bonzini <pbonz...@redhat.com> > wrote: > > > > > > > > > > On 12/13/24 16:51, Richard W.M. Jones wrote: > > > > > > The libnfs asynch API has changed type signature in this new > version. > > > > > > This change breaks qemu and it wasn't immediately obvious to me > how to > > > > > > fix it. In particular the new API requires a buffer to be > passed, but > > > > > > it's unclear what that would be. > > > > > > > > > > > > Old signature: > > > > > > > > > > > > EXTERN int nfs_pread_async(struct nfs_context *nfs, struct nfsfh > *nfsfh, > > > > > > uint64_t offset, uint64_t count, > nfs_cb cb, > > > > > > void *private_data); > > > > > > > > > > > > New signature: > > > > > > > > > > > > EXTERN int nfs_pread_async(struct nfs_context *nfs, struct nfsfh > *nfsfh, > > > > > > void *buf, size_t count, uint64_t > offset, > > > > > > nfs_cb cb, void *private_data); > > > > > > > > > > > > (Similar changes are made to pwrite_async) > > > > > > > > > > Looks like the buffer used to be allocated by libnfs and passed to > > > > > nfs_co_generic_cb: > > > > > > > > > > static void > > > > > nfs_co_generic_cb(int ret, struct nfs_context *nfs, void *data, > > > > > void *private_data) > > > > > > > > > > Now it has to be allocated by the application. > > > > > > > > > > (upstream commit > https://github.com/sahlberg/libnfs/commit/5e8f7ce273308) > > > > > > > > > > > I guess this needs upstream qemu attention. > > > > > > > > > > And should it also block the libnfs update in Fedora, since QEMU > is a > > > > > critical package? > > > > > > > > Hi Ronnie, > > > > This libnfs nfs_pread_async() API change breaks the QEMU build. This > > > > email thread discusses holding off on updating libnfs 5 -> 6 in > > > > Fedora, but the update has already happened in Homebrew so the QEMU > > > > macOS CI is now failing: > > > > https://gitlab.com/qemu-project/qemu/-/jobs/8646124898 > > > > > > > > Do you plan to release a new libnfs version that restores API > > > > compatibility or has the ship sailed and applications need to detect > > > > this at compile time? > > > > > > I would prefer not to restore the old API. I had to break the API for > > > at least nfs_[p]read[_async] > > > in order to make (almost) zero-copy within the library work for the > read path. > > > I already do zero-copy (within the library) for the write path bit did > > > not do it for the read path until now > > > due to how hairy it is to do with the several variable length fields > > > in the headers :-( > > > > > > Since I broke the API for read, which will affect every applicatin I > > > went ahead and fixed a lot of other warts in the > > > API as well, so that we can not actually cancel pdus that are in > flight. > > > > > > There is a compile-time check that can be made to determine which API > is use, > > > this is from fio : > > > > > > @@ -157,16 +157,28 @@ static int queue_write(struct fio_libnfs_options > > > *o, struct io_u *io_u) > > > { > > > struct nfs_data *nfs_data = io_u->engine_data; > > > > > > +#ifdef LIBNFS_API_V2 > > > + return nfs_pwrite_async(o->context, nfs_data->nfsfh, > > > + io_u->buf, io_u->buflen, io_u->offset, > > > + nfs_callback, io_u); > > > +#else > > > return nfs_pwrite_async(o->context, nfs_data->nfsfh, > io_u->offset, > > > io_u->buflen, io_u->buf, nfs_callback, > io_u); > > > +#endif > > > } > > > ... > > > struct nfs_data *nfs_data = io_u->engine_data; > > > > > > +#ifdef LIBNFS_API_V2 > > > + return nfs_pread_async(o->context, nfs_data->nfsfh, > > > + io_u->buf, io_u->buflen, io_u->offset, > > > + nfs_callback, io_u); > > > +#else > > > return nfs_pread_async(o->context, nfs_data->nfsfh, > io_u->offset, > > > io_u->buflen, nfs_callback, io_u); > > > +#endif > > > > > > > > > > > > Do you want me to send a patch to qemu to add this type of > > > compile-time conditionals? > > > Or will you do it? the change as seen in the snippet above is fairly > trivial. > > > > QEMU is very important application. > > Let me know if doing the compile-time check as above is feasible. > > If it is not really feasible due to where/when buffers are allocated in > qemu, > > please let me know and then I will restore the old API and introduce > > the zero-copy versions under a new different function. > > > > > > > > > > > > > regards > > > Ronnie Sahlberg > > > > > > > > > > > > > > Thanks, > > > > Stefan > >