summaryrefslogtreecommitdiff
path: root/netfs/fuse/fuseApp.h
blob: b905b2319730550b32576096f8b614e5a551d03d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#ifndef NETFS_FUSE_H
#define NETFS_FUSE_H

#include "cache.h"
#include "fuseAppBase.h"
#include "fuseConfig.h"
#include <Glacier2/Session.h>
#include <Ice/Ice.h>
#include <c++11Helpers.h>
#include <entCache.h>
#include <filesystem>
#include <functional>
#include <service.h>
#include <shared_mutex>
#include <typeConverter.h>
#include <visibility.h>

namespace NetFS {
	class DLL_PUBLIC FuseApp : public FuseAppBaseT<FuseApp> {
	private:
		class OpenDir;
		using OpenDirPtr = std::shared_ptr<OpenDir>;
		using OpenDirs = std::map<int, OpenDirPtr>;

		class OpenFile;
		using OpenFilePtr = std::shared_ptr<OpenFile>;
		using OpenFiles = std::map<int, OpenFilePtr>;

	public:
		explicit FuseApp(Ice::StringSeq &&);
		SPECIAL_MEMBERS_DELETE(FuseApp);
		~FuseApp() override;

		// lifecycle
		void * init(struct fuse_conn_info * info, struct fuse_config * cfg) override;
		static int opt_parse(void * data, const char * arg, int, struct fuse_args *);

	protected:
		void connectSession();
		virtual void connectToService();
		void connectToVolume();
		void connectHandles();
		void verifyConnection();

	public:
		// misc
		int access(const char * p, int a) override;
		int getattr(const char *, struct stat *, struct fuse_file_info *) override;
		int chmod(const char *, mode_t, struct fuse_file_info *) override;
		int chown(const char *, uid_t, gid_t, struct fuse_file_info *) override;
		int link(const char *, const char *) override;
		int readlink(const char *, char *, size_t) override;
		int rename(const char *, const char *, unsigned int) override;
		int symlink(const char *, const char *) override;
		int unlink(const char *) override;
		// NOLINTNEXTLINE(hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
		int utimens(const char *, const struct timespec tv[2], struct fuse_file_info *) override;
		int mknod(const char *, mode_t, dev_t) override;
		// dirs
		int opendir(const char * p, struct fuse_file_info * fi) override;
		int releasedir(const char *, struct fuse_file_info * fi) override;
		int readdir(const char *, void * buf, fuse_fill_dir_t filler, off_t, struct fuse_file_info * fi,
				enum fuse_readdir_flags) override;
		int mkdir(const char *, mode_t) override;
		int rmdir(const char *) override;
		// files
		int open(const char * p, struct fuse_file_info * fi) override;
		int create(const char *, mode_t, struct fuse_file_info *) override;
		int flush(const char *, struct fuse_file_info * fi) override;
		int release(const char *, struct fuse_file_info * fi) override;
		int read(const char *, char * buf, size_t s, off_t o, struct fuse_file_info * fi) override;
		int write(const char *, const char * buf, size_t s, off_t o, struct fuse_file_info * fi) override;
		ssize_t copy_file_range(const char *, struct fuse_file_info *, off_t, const char *, struct fuse_file_info *,
				off_t, size_t, int) override;
		int truncate(const char *, off_t, struct fuse_file_info *) override;
		// fs
		int statfs(const char *, struct statvfs *) override;
		// stuff
		int onError(const std::exception & err) noexcept override;
		void beforeOperation() override;

		virtual struct fuse_context * fuse_get_context() = 0;

		static NetFS::Client::ResourcePtr configureFromFile(const std::filesystem::path &, const std::string &);
		static NetFS::Client::ResourcePtr configureFromUri(const std::string &);

	protected:
		template<typename Handle, typename... Params> void setProxy(uint64_t & fh, const Params &...);
		template<typename Handle> Handle getProxy(uint64_t localID);
		template<typename Handle> void clearProxy(uint64_t localID);
		template<typename Handle> std::map<int, Handle> & getMap();

		template<typename Rtn, typename F>
		static inline Rtn waitOnWriteRangeAndThen(size_t s, off_t o, const OpenFilePtr & of, const F & f);

		ReqEnv reqEnv();

		Ice::StringSeq iceArgs;
		Ice::CommunicatorPtr ic;
		Client::ResourcePtr fcr;
		mutable std::shared_mutex _proxymaplock;

		NetFS::VolumePrxPtr volume;
		NetFS::ServicePrxPtr service;
		Glacier2::SessionPrxPtr session;
		bool sessionOpened;

		std::string mountPoint;

		OpenDirs openDirs;
		OpenFiles openFiles;
		int openHandleId;

		EntryTypeConverter converter;

		using StatCache = AdHoc::Cache<struct stat, std::string>;
		StatCache statCache;
	};
}

#endif