diff options
Diffstat (limited to '')
-rw-r--r-- | src/lib/nfs/Connection.hxx | 33 |
1 files changed, 32 insertions, 1 deletions
diff --git a/src/lib/nfs/Connection.hxx b/src/lib/nfs/Connection.hxx index 880b7d467..b3db37c5d 100644 --- a/src/lib/nfs/Connection.hxx +++ b/src/lib/nfs/Connection.hxx @@ -26,8 +26,11 @@ #include "event/DeferredMonitor.hxx" #include "util/Error.hxx" +#include <boost/intrusive/list.hpp> + #include <string> #include <list> +#include <forward_list> struct nfs_context; class NfsCallback; @@ -47,13 +50,19 @@ class NfsConnection : SocketMonitor, DeferredMonitor { */ const bool open; + /** + * The file handle scheduled to be closed as soon as + * the operation finishes. + */ + struct nfsfh *close_fh; + public: explicit CancellableCallback(NfsCallback &_callback, NfsConnection &_connection, bool _open) :CancellablePointer<NfsCallback>(_callback), connection(_connection), - open(_open) {} + open(_open), close_fh(nullptr) {} bool Open(nfs_context *context, const char *path, int flags, Error &error); @@ -63,6 +72,12 @@ class NfsConnection : SocketMonitor, DeferredMonitor { uint64_t offset, size_t size, Error &error); + /** + * Cancel the operation and schedule a call to + * nfs_close_async() with the given file handle. + */ + void CancelAndScheduleClose(struct nfsfh *fh); + private: static void Callback(int err, struct nfs_context *nfs, void *data, void *private_data); @@ -79,6 +94,15 @@ class NfsConnection : SocketMonitor, DeferredMonitor { typedef CancellableList<NfsCallback, CancellableCallback> CallbackList; CallbackList callbacks; + /** + * A list of NFS file handles (struct nfsfh *) which shall be + * closed as soon as nfs_service() returns. If we close the + * file handle while in nfs_service(), libnfs may crash, and + * deferring this call to after nfs_service() avoids this + * problem. + */ + std::forward_list<struct nfsfh *> deferred_close; + Error postponed_mount_error; /** @@ -135,6 +159,7 @@ public: void Cancel(NfsCallback &callback); void Close(struct nfsfh *fh); + void CancelAndClose(struct nfsfh *fh, NfsCallback &callback); protected: virtual void OnNfsConnectionError(Error &&error) = 0; @@ -145,6 +170,12 @@ private: } void DestroyContext(); + + /** + * Invoke nfs_close_async() after nfs_service() returns. + */ + void DeferClose(struct nfsfh *fh); + bool MountInternal(Error &error); void BroadcastMountSuccess(); void BroadcastMountError(Error &&error); |