lib/nfs/Connection: replace flag "mount_finished" with enum

This commit is contained in:
Max Kellermann 2024-05-06 17:47:52 +02:00
parent e013c19223
commit 90a44a0c07
2 changed files with 25 additions and 12 deletions

View File

@ -379,9 +379,11 @@ NfsConnection::DestroyContext() noexcept
in_destroy = true; in_destroy = true;
#endif #endif
if (!mount_finished) { if (mount_state == MountState::WAITING) {
assert(mount_timeout_event.IsPending()); assert(mount_timeout_event.IsPending());
mount_timeout_event.Cancel(); mount_timeout_event.Cancel();
} else {
assert(!mount_timeout_event.IsPending());
} }
/* cancel pending DeferEvent that was scheduled to notify /* cancel pending DeferEvent that was scheduled to notify
@ -469,9 +471,10 @@ NfsConnection::OnSocketReady(unsigned flags) noexcept
{ {
assert(GetEventLoop().IsInside()); assert(GetEventLoop().IsInside());
assert(deferred_close.empty()); assert(deferred_close.empty());
assert(mount_state >= MountState::WAITING);
const bool was_mounted = mount_finished; const bool was_mounted = mount_state >= MountState::FINISHED;
if (!mount_finished || (flags & SocketEvent::HANGUP) != 0) if (!was_mounted || (flags & SocketEvent::HANGUP) != 0)
/* until the mount is finished, the NFS client may use /* until the mount is finished, the NFS client may use
various sockets, therefore we unregister and various sockets, therefore we unregister and
re-register it each time */ re-register it each time */
@ -488,7 +491,7 @@ NfsConnection::OnSocketReady(unsigned flags) noexcept
deferred_close.pop_front(); deferred_close.pop_front();
} }
if (!was_mounted && mount_finished) { if (!was_mounted && mount_state >= MountState::FINISHED) {
if (postponed_mount_error) { if (postponed_mount_error) {
DestroyContext(); DestroyContext();
BroadcastMountError(std::move(postponed_mount_error)); BroadcastMountError(std::move(postponed_mount_error));
@ -530,8 +533,9 @@ NfsConnection::MountCallback(int status, [[maybe_unused]] nfs_context *nfs,
{ {
assert(GetEventLoop().IsInside()); assert(GetEventLoop().IsInside());
assert(context == nfs); assert(context == nfs);
assert(mount_state == MountState::WAITING);
mount_finished = true; mount_state = MountState::FINISHED;
assert(mount_timeout_event.IsPending() || in_destroy); assert(mount_timeout_event.IsPending() || in_destroy);
mount_timeout_event.Cancel(); mount_timeout_event.Cancel();
@ -557,13 +561,14 @@ NfsConnection::MountInternal()
{ {
assert(GetEventLoop().IsInside()); assert(GetEventLoop().IsInside());
assert(context == nullptr); assert(context == nullptr);
assert(mount_state == MountState::INITIAL);
context = nfs_init_context(); context = nfs_init_context();
if (context == nullptr) if (context == nullptr)
throw std::runtime_error("nfs_init_context() failed"); throw std::runtime_error("nfs_init_context() failed");
postponed_mount_error = std::exception_ptr(); postponed_mount_error = std::exception_ptr();
mount_finished = false; mount_state = MountState::WAITING;
mount_timeout_event.Schedule(NFS_MOUNT_TIMEOUT); mount_timeout_event.Schedule(NFS_MOUNT_TIMEOUT);
@ -575,6 +580,7 @@ NfsConnection::MountInternal()
if (nfs_mount_async(context, server.c_str(), export_name.c_str(), if (nfs_mount_async(context, server.c_str(), export_name.c_str(),
MountCallback, this) != 0) { MountCallback, this) != 0) {
mount_state = MountState::FINISHED;
auto e = NfsClientError(context, "nfs_mount_async() failed"); auto e = NfsClientError(context, "nfs_mount_async() failed");
nfs_destroy_context(context); nfs_destroy_context(context);
context = nullptr; context = nullptr;
@ -588,6 +594,7 @@ void
NfsConnection::BroadcastMountSuccess() noexcept NfsConnection::BroadcastMountSuccess() noexcept
{ {
assert(GetEventLoop().IsInside()); assert(GetEventLoop().IsInside());
assert(mount_state == MountState::FINISHED);
new_leases.clear_and_dispose([this](auto *lease){ new_leases.clear_and_dispose([this](auto *lease){
active_leases.push_back(*lease); active_leases.push_back(*lease);
@ -599,6 +606,7 @@ void
NfsConnection::BroadcastMountError(std::exception_ptr e) noexcept NfsConnection::BroadcastMountError(std::exception_ptr e) noexcept
{ {
assert(GetEventLoop().IsInside()); assert(GetEventLoop().IsInside());
assert(mount_state == MountState::FINISHED);
new_leases.clear_and_dispose([this, &e](auto *l){ new_leases.clear_and_dispose([this, &e](auto *l){
l->OnNfsConnectionFailed(e); l->OnNfsConnectionFailed(e);
@ -623,9 +631,9 @@ void
NfsConnection::OnMountTimeout() noexcept NfsConnection::OnMountTimeout() noexcept
{ {
assert(GetEventLoop().IsInside()); assert(GetEventLoop().IsInside());
assert(!mount_finished); assert(mount_state == MountState::WAITING);
mount_finished = true; mount_state = MountState::FINISHED;
DestroyContext(); DestroyContext();
BroadcastMountError(std::make_exception_ptr(std::runtime_error("Mount timeout"))); BroadcastMountError(std::make_exception_ptr(std::runtime_error("Mount timeout")));
@ -636,7 +644,7 @@ NfsConnection::RunDeferred() noexcept
{ {
assert(GetEventLoop().IsInside()); assert(GetEventLoop().IsInside());
if (context == nullptr) { if (mount_state == MountState::INITIAL) {
try { try {
MountInternal(); MountInternal();
} catch (...) { } catch (...) {
@ -645,6 +653,6 @@ NfsConnection::RunDeferred() noexcept
} }
} }
if (mount_finished) if (mount_state >= MountState::FINISHED)
BroadcastMountSuccess(); BroadcastMountSuccess();
} }

View File

@ -9,6 +9,7 @@
#include "event/DeferEvent.hxx" #include "event/DeferEvent.hxx"
#include "util/IntrusiveList.hxx" #include "util/IntrusiveList.hxx"
#include <cstdint>
#include <string> #include <string>
#include <forward_list> #include <forward_list>
#include <exception> #include <exception>
@ -100,6 +101,12 @@ class NfsConnection {
std::exception_ptr postponed_mount_error; std::exception_ptr postponed_mount_error;
enum class MountState : uint_least8_t {
INITIAL,
WAITING,
FINISHED,
} mount_state = MountState::INITIAL;
#ifndef NDEBUG #ifndef NDEBUG
/** /**
* True when nfs_service() is being called. * True when nfs_service() is being called.
@ -118,8 +125,6 @@ class NfsConnection {
bool in_destroy; bool in_destroy;
#endif #endif
bool mount_finished;
public: public:
[[gnu::nonnull]] [[gnu::nonnull]]
NfsConnection(EventLoop &_loop, NfsConnection(EventLoop &_loop,