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_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 {
DeferClose();
}
@ -225,3 +234,10 @@ const InputPlugin input_plugin_nfs = {
input_nfs_open,
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
// Copyright The Music Player Daemon Project
#ifndef MPD_INPUT_NFS_H
#define MPD_INPUT_NFS_H
#pragma once
#include "input/Ptr.hxx"
#include "thread/Mutex.hxx"
#include <string_view>
class NfsConnection;
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 <fmt/core.h>
#include <cassert>
#include <cstring>
#include <stdexcept>
@ -18,16 +20,37 @@
#include <fcntl.h>
#include <sys/stat.h> // for S_ISREG()
using std::string_view_literals::operator""sv;
NfsFileReader::NfsFileReader() noexcept
: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
{
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
NfsFileReader::Close() noexcept
{
@ -293,12 +316,13 @@ NfsFileReader::OnDeferredOpen() noexcept
{
assert(state == State::DEFER);
try {
connection = &nfs_get_connection(server, export_name);
} catch (...) {
OnNfsFileError(std::current_exception());
return;
}
if (connection == nullptr)
try {
connection = &nfs_get_connection(server, export_name);
} catch (...) {
OnNfsFileError(std::current_exception());
return;
}
connection->AddLease(*this);
state = State::MOUNT;

View File

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

View File

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