storage/nfs: optimize OpenFile()

This commit is contained in:
Max Kellermann 2024-05-15 21:46:38 +02:00
parent 9e8128ecb5
commit b64d01677b
5 changed files with 67 additions and 13 deletions

View File

@ -31,6 +31,15 @@ public:
NFS_MAX_BUFFERED, NFS_MAX_BUFFERED,
NFS_RESUME_AT) {} NFS_RESUME_AT) {}
NfsInputStream(NfsConnection &_connection, std::string_view _path,
Mutex &_mutex) noexcept
:NfsFileReader(_connection, _path),
AsyncInputStream(NfsFileReader::GetEventLoop(),
NfsFileReader::GetAbsoluteUri(),
_mutex,
NFS_MAX_BUFFERED,
NFS_RESUME_AT) {}
~NfsInputStream() override { ~NfsInputStream() override {
DeferClose(); DeferClose();
} }
@ -225,3 +234,10 @@ const InputPlugin input_plugin_nfs = {
input_nfs_open, input_nfs_open,
nullptr nullptr
}; };
InputStreamPtr
OpenNfsInputStream(NfsConnection &connection, std::string_view path,
Mutex &mutex)
{
return std::make_unique<NfsInputStream>(connection, path, mutex);
}

View File

@ -1,9 +1,17 @@
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
// Copyright The Music Player Daemon Project // Copyright The Music Player Daemon Project
#ifndef MPD_INPUT_NFS_H #pragma once
#define MPD_INPUT_NFS_H
#include "input/Ptr.hxx"
#include "thread/Mutex.hxx"
#include <string_view>
class NfsConnection;
extern const struct InputPlugin input_plugin_nfs; extern const struct InputPlugin input_plugin_nfs;
#endif InputStreamPtr
OpenNfsInputStream(NfsConnection &connection, std::string_view path,
Mutex &mutex);

View File

@ -10,6 +10,8 @@
#include <nfsc/libnfs.h> // for struct nfs_stat_64 #include <nfsc/libnfs.h> // for struct nfs_stat_64
#include <fmt/core.h>
#include <cassert> #include <cassert>
#include <cstring> #include <cstring>
#include <stdexcept> #include <stdexcept>
@ -18,16 +20,37 @@
#include <fcntl.h> #include <fcntl.h>
#include <sys/stat.h> // for S_ISREG() #include <sys/stat.h> // for S_ISREG()
using std::string_view_literals::operator""sv;
NfsFileReader::NfsFileReader() noexcept NfsFileReader::NfsFileReader() noexcept
:defer_open(nfs_get_event_loop(), BIND_THIS_METHOD(OnDeferredOpen)) :defer_open(nfs_get_event_loop(), BIND_THIS_METHOD(OnDeferredOpen))
{ {
} }
NfsFileReader::NfsFileReader(NfsConnection &_connection,
std::string_view _path) noexcept
:state(State::DEFER),
path(_path),
connection(&_connection),
defer_open(_connection.GetEventLoop(), BIND_THIS_METHOD(OnDeferredOpen))
{
defer_open.Schedule();
}
NfsFileReader::~NfsFileReader() noexcept NfsFileReader::~NfsFileReader() noexcept
{ {
assert(state == State::INITIAL); assert(state == State::INITIAL);
} }
std::string
NfsFileReader::GetAbsoluteUri() const noexcept
{
return fmt::format("nfs://{}{}/{}"sv,
connection != nullptr ? connection->GetServer() : server,
connection != nullptr ? connection->GetExportName() : export_name,
path);
}
void void
NfsFileReader::Close() noexcept NfsFileReader::Close() noexcept
{ {
@ -293,6 +316,7 @@ NfsFileReader::OnDeferredOpen() noexcept
{ {
assert(state == State::DEFER); assert(state == State::DEFER);
if (connection == nullptr)
try { try {
connection = &nfs_get_connection(server, export_name); connection = &nfs_get_connection(server, export_name);
} catch (...) { } catch (...) {

View File

@ -45,7 +45,7 @@ class NfsFileReader : NfsLease, NfsCallback {
std::string server, export_name, path; std::string server, export_name, path;
NfsConnection *connection; NfsConnection *connection = nullptr;
nfsfh *fh; nfsfh *fh;
@ -60,12 +60,17 @@ class NfsFileReader : NfsLease, NfsCallback {
public: public:
NfsFileReader() noexcept; NfsFileReader() noexcept;
explicit NfsFileReader(NfsConnection &_connection,
std::string_view _path) noexcept;
~NfsFileReader() noexcept; ~NfsFileReader() noexcept;
auto &GetEventLoop() const noexcept { auto &GetEventLoop() const noexcept {
return defer_open.GetEventLoop(); return defer_open.GetEventLoop();
} }
[[nodiscard]] [[gnu::pure]]
std::string GetAbsoluteUri() const noexcept;
void Close() noexcept; void Close() noexcept;
void DeferClose() noexcept; void DeferClose() noexcept;

View File

@ -12,6 +12,7 @@
#include "lib/nfs/Connection.hxx" #include "lib/nfs/Connection.hxx"
#include "lib/nfs/Glue.hxx" #include "lib/nfs/Glue.hxx"
#include "input/InputStream.hxx" #include "input/InputStream.hxx"
#include "input/plugins/NfsInputPlugin.hxx"
#include "fs/AllocatedPath.hxx" #include "fs/AllocatedPath.hxx"
#include "thread/Mutex.hxx" #include "thread/Mutex.hxx"
#include "thread/Cond.hxx" #include "thread/Cond.hxx"
@ -252,9 +253,9 @@ NfsStorage::MapToRelativeUTF8(std::string_view uri_utf8) const noexcept
InputStreamPtr InputStreamPtr
NfsStorage::OpenFile(std::string_view uri_utf8, Mutex &_mutex) NfsStorage::OpenFile(std::string_view uri_utf8, Mutex &_mutex)
{ {
// TODO create NfsInputStream directly WaitConnected();
auto uri = MapUTF8(uri_utf8);
return InputStream::Open(uri.c_str(), _mutex); return OpenNfsInputStream(*connection, uri_utf8, _mutex);
} }
static void static void