lib/nfs: initial support for libnfs API 2
Commit
5e8f7ce273
introduced the libnfs API version 2 which may eventually become libnfs
version 6.
This version detection depends on my pull request
https://github.com/sahlberg/libnfs/pull/468
This commit is contained in:
parent
0ac24e5a24
commit
31e583e9f8
1
NEWS
1
NEWS
|
@ -26,6 +26,7 @@ ver 0.24 (not yet released)
|
|||
* storage
|
||||
- curl: optimize database update
|
||||
- nfs: require libnfs 4.0 or later
|
||||
- nfs: support libnfs 6 (API version 2)
|
||||
- nfs: support libnfs URL arguments
|
||||
* input
|
||||
- alsa: limit ALSA buffer time to 2 seconds
|
||||
|
|
|
@ -81,11 +81,25 @@ NfsConnection::CancellableCallback::Stat(nfs_context *ctx,
|
|||
|
||||
inline void
|
||||
NfsConnection::CancellableCallback::Read(nfs_context *ctx, struct nfsfh *fh,
|
||||
uint64_t offset, size_t size)
|
||||
uint64_t offset,
|
||||
#ifdef LIBNFS_API_2
|
||||
std::span<std::byte> dest
|
||||
#else
|
||||
std::size_t size
|
||||
#endif
|
||||
)
|
||||
{
|
||||
assert(connection.GetEventLoop().IsInside());
|
||||
|
||||
int result = nfs_pread_async(ctx, fh, offset, size, Callback, this);
|
||||
int result = nfs_pread_async(ctx, fh,
|
||||
#ifdef LIBNFS_API_2
|
||||
dest.data(), dest.size(),
|
||||
#endif
|
||||
offset,
|
||||
#ifndef LIBNFS_API_2
|
||||
size,
|
||||
#endif
|
||||
Callback, this);
|
||||
if (result < 0)
|
||||
throw NfsClientError(ctx, "nfs_pread_async() failed");
|
||||
}
|
||||
|
@ -328,7 +342,12 @@ NfsConnection::Stat(struct nfsfh *fh, NfsCallback &callback)
|
|||
}
|
||||
|
||||
void
|
||||
NfsConnection::Read(struct nfsfh *fh, uint64_t offset, size_t size,
|
||||
NfsConnection::Read(struct nfsfh *fh, uint64_t offset,
|
||||
#ifdef LIBNFS_API_2
|
||||
std::span<std::byte> dest,
|
||||
#else
|
||||
std::size_t size,
|
||||
#endif
|
||||
NfsCallback &callback)
|
||||
{
|
||||
assert(GetEventLoop().IsInside());
|
||||
|
@ -336,7 +355,13 @@ NfsConnection::Read(struct nfsfh *fh, uint64_t offset, size_t size,
|
|||
|
||||
auto &c = callbacks.Add(callback, *this, false);
|
||||
try {
|
||||
c.Read(context, fh, offset, size);
|
||||
c.Read(context, fh, offset,
|
||||
#ifdef LIBNFS_API_2
|
||||
dest
|
||||
#else
|
||||
size
|
||||
#endif
|
||||
);
|
||||
} catch (...) {
|
||||
callbacks.Remove(c);
|
||||
throw;
|
||||
|
|
|
@ -62,7 +62,13 @@ class NfsConnection {
|
|||
void Open(nfs_context *context, const char *path, int flags);
|
||||
void Stat(nfs_context *context, struct nfsfh *fh);
|
||||
void Read(nfs_context *context, struct nfsfh *fh,
|
||||
uint64_t offset, size_t size);
|
||||
uint64_t offset,
|
||||
#ifdef LIBNFS_API_2
|
||||
std::span<std::byte> dest
|
||||
#else
|
||||
std::size_t size
|
||||
#endif
|
||||
);
|
||||
|
||||
/**
|
||||
* Cancel the operation and schedule a call to
|
||||
|
@ -210,7 +216,12 @@ public:
|
|||
/**
|
||||
* Throws on error.
|
||||
*/
|
||||
void Read(struct nfsfh *fh, uint64_t offset, size_t size,
|
||||
void Read(struct nfsfh *fh, uint64_t offset,
|
||||
#ifdef LIBNFS_API_2
|
||||
std::span<std::byte> dest,
|
||||
#else
|
||||
std::size_t size,
|
||||
#endif
|
||||
NfsCallback &callback);
|
||||
|
||||
/**
|
||||
|
|
|
@ -59,7 +59,13 @@ NfsFileReader::CancelOrClose() noexcept
|
|||
else if (state > State::OPEN)
|
||||
/* one async operation in progress: cancel it and
|
||||
defer the nfs_close_async() call */
|
||||
connection->CancelAndClose(fh, {}, *this);
|
||||
connection->CancelAndClose(fh,
|
||||
#ifdef LIBNFS_API_2
|
||||
ToDeleteArray(read_buffer.release()),
|
||||
#else
|
||||
{},
|
||||
#endif
|
||||
*this);
|
||||
else if (state > State::MOUNT)
|
||||
/* we don't have a file handle yet - just cancel the
|
||||
async operation */
|
||||
|
@ -116,7 +122,15 @@ NfsFileReader::Read(uint64_t offset, size_t size)
|
|||
{
|
||||
assert(state == State::IDLE);
|
||||
|
||||
#ifdef LIBNFS_API_2
|
||||
assert(!read_buffer);
|
||||
// TOOD read into caller-provided buffer
|
||||
read_buffer = std::make_unique<std::byte[]>(size);
|
||||
connection->Read(fh, offset, {read_buffer.get(), size}, *this);
|
||||
#else
|
||||
connection->Read(fh, offset, size, *this);
|
||||
#endif
|
||||
|
||||
state = State::READ;
|
||||
}
|
||||
|
||||
|
@ -200,7 +214,16 @@ NfsFileReader::StatCallback(const struct nfs_stat_64 *st) noexcept
|
|||
inline void
|
||||
NfsFileReader::ReadCallback(std::size_t nbytes, const void *data) noexcept
|
||||
{
|
||||
#ifdef LIBNFS_API_2
|
||||
(void)data;
|
||||
|
||||
assert(read_buffer);
|
||||
const auto buffer = std::move(read_buffer);
|
||||
|
||||
OnNfsFileRead({buffer.get(), nbytes});
|
||||
#else
|
||||
OnNfsFileRead({static_cast<const std::byte *>(data), nbytes});
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -14,6 +14,10 @@
|
|||
#include <span>
|
||||
#include <string>
|
||||
|
||||
#ifdef LIBNFS_API_2
|
||||
#include <memory>
|
||||
#endif
|
||||
|
||||
struct nfsfh;
|
||||
struct nfs_stat_64;
|
||||
class NfsConnection;
|
||||
|
@ -51,6 +55,10 @@ class NfsFileReader : NfsLease, NfsCallback {
|
|||
*/
|
||||
InjectEvent defer_open;
|
||||
|
||||
#ifdef LIBNFS_API_2
|
||||
std::unique_ptr<std::byte[]> read_buffer;
|
||||
#endif
|
||||
|
||||
public:
|
||||
NfsFileReader() noexcept;
|
||||
~NfsFileReader() noexcept;
|
||||
|
|
|
@ -4,6 +4,13 @@ if not nfs_dep.found()
|
|||
subdir_done()
|
||||
endif
|
||||
|
||||
if nfs_dep.version().version_compare('>=6')
|
||||
# libnfs has no version macro therefore we must detect the API
|
||||
# version 2 at configure time
|
||||
nfs_dep = declare_dependency(compile_args: '-DLIBNFS_API_2',
|
||||
dependencies: nfs_dep)
|
||||
endif
|
||||
|
||||
nfs = static_library(
|
||||
'nfs',
|
||||
'Connection.cxx',
|
||||
|
|
Loading…
Reference in New Issue