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
|
* storage
|
||||||
- curl: optimize database update
|
- curl: optimize database update
|
||||||
- nfs: require libnfs 4.0 or later
|
- nfs: require libnfs 4.0 or later
|
||||||
|
- nfs: support libnfs 6 (API version 2)
|
||||||
- nfs: support libnfs URL arguments
|
- nfs: support libnfs URL arguments
|
||||||
* input
|
* input
|
||||||
- alsa: limit ALSA buffer time to 2 seconds
|
- alsa: limit ALSA buffer time to 2 seconds
|
||||||
|
|
|
@ -81,11 +81,25 @@ NfsConnection::CancellableCallback::Stat(nfs_context *ctx,
|
||||||
|
|
||||||
inline void
|
inline void
|
||||||
NfsConnection::CancellableCallback::Read(nfs_context *ctx, struct nfsfh *fh,
|
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());
|
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)
|
if (result < 0)
|
||||||
throw NfsClientError(ctx, "nfs_pread_async() failed");
|
throw NfsClientError(ctx, "nfs_pread_async() failed");
|
||||||
}
|
}
|
||||||
|
@ -328,7 +342,12 @@ NfsConnection::Stat(struct nfsfh *fh, NfsCallback &callback)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
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)
|
NfsCallback &callback)
|
||||||
{
|
{
|
||||||
assert(GetEventLoop().IsInside());
|
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);
|
auto &c = callbacks.Add(callback, *this, false);
|
||||||
try {
|
try {
|
||||||
c.Read(context, fh, offset, size);
|
c.Read(context, fh, offset,
|
||||||
|
#ifdef LIBNFS_API_2
|
||||||
|
dest
|
||||||
|
#else
|
||||||
|
size
|
||||||
|
#endif
|
||||||
|
);
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
callbacks.Remove(c);
|
callbacks.Remove(c);
|
||||||
throw;
|
throw;
|
||||||
|
|
|
@ -62,7 +62,13 @@ class NfsConnection {
|
||||||
void Open(nfs_context *context, const char *path, int flags);
|
void Open(nfs_context *context, const char *path, int flags);
|
||||||
void Stat(nfs_context *context, struct nfsfh *fh);
|
void Stat(nfs_context *context, struct nfsfh *fh);
|
||||||
void Read(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
|
* Cancel the operation and schedule a call to
|
||||||
|
@ -210,7 +216,12 @@ public:
|
||||||
/**
|
/**
|
||||||
* Throws on error.
|
* 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);
|
NfsCallback &callback);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -59,7 +59,13 @@ NfsFileReader::CancelOrClose() noexcept
|
||||||
else if (state > State::OPEN)
|
else if (state > State::OPEN)
|
||||||
/* one async operation in progress: cancel it and
|
/* one async operation in progress: cancel it and
|
||||||
defer the nfs_close_async() call */
|
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)
|
else if (state > State::MOUNT)
|
||||||
/* we don't have a file handle yet - just cancel the
|
/* we don't have a file handle yet - just cancel the
|
||||||
async operation */
|
async operation */
|
||||||
|
@ -116,7 +122,15 @@ NfsFileReader::Read(uint64_t offset, size_t size)
|
||||||
{
|
{
|
||||||
assert(state == State::IDLE);
|
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);
|
connection->Read(fh, offset, size, *this);
|
||||||
|
#endif
|
||||||
|
|
||||||
state = State::READ;
|
state = State::READ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -200,7 +214,16 @@ NfsFileReader::StatCallback(const struct nfs_stat_64 *st) noexcept
|
||||||
inline void
|
inline void
|
||||||
NfsFileReader::ReadCallback(std::size_t nbytes, const void *data) noexcept
|
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});
|
OnNfsFileRead({static_cast<const std::byte *>(data), nbytes});
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -14,6 +14,10 @@
|
||||||
#include <span>
|
#include <span>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#ifdef LIBNFS_API_2
|
||||||
|
#include <memory>
|
||||||
|
#endif
|
||||||
|
|
||||||
struct nfsfh;
|
struct nfsfh;
|
||||||
struct nfs_stat_64;
|
struct nfs_stat_64;
|
||||||
class NfsConnection;
|
class NfsConnection;
|
||||||
|
@ -51,6 +55,10 @@ class NfsFileReader : NfsLease, NfsCallback {
|
||||||
*/
|
*/
|
||||||
InjectEvent defer_open;
|
InjectEvent defer_open;
|
||||||
|
|
||||||
|
#ifdef LIBNFS_API_2
|
||||||
|
std::unique_ptr<std::byte[]> read_buffer;
|
||||||
|
#endif
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NfsFileReader() noexcept;
|
NfsFileReader() noexcept;
|
||||||
~NfsFileReader() noexcept;
|
~NfsFileReader() noexcept;
|
||||||
|
|
|
@ -4,6 +4,13 @@ if not nfs_dep.found()
|
||||||
subdir_done()
|
subdir_done()
|
||||||
endif
|
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 = static_library(
|
||||||
'nfs',
|
'nfs',
|
||||||
'Connection.cxx',
|
'Connection.cxx',
|
||||||
|
|
Loading…
Reference in New Issue