summaryrefslogtreecommitdiff
path: root/netfs/fuse/fuseApp.h
blob: f37acb7896b2a5812e447fa5ec71081a4e7dc617 (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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#ifndef NETFS_FUSE_H
#define NETFS_FUSE_H

#include <shared_mutex>
#include <functional>
#include <boost/filesystem/path.hpp>
#include <Ice/Ice.h>
#include <Glacier2/Session.h>
#include <service.h>
#include <entCache.h>
#include <typeConverter.h>
#include "fuseAppBase.h"
#include "fuseConfig.h"
#include "cache.h"
#include <visibility.h>
#include <boost/icl/interval_map.hpp>

namespace NetFS {
	class DLL_PUBLIC FuseApp : public FuseAppBase {
		private:
			class OpenDir {
				public:
					OpenDir(DirectoryPrxPtr remote, const std::string & path);

					DirectoryPrxPtr remote;
					DirectoryV2PrxPtr remoteV2;
					const std::string path;
			};
			typedef std::shared_ptr<OpenDir> OpenDirPtr;
			typedef std::map<int, OpenDirPtr> OpenDirs;

			class OpenFile {
				public:
					OpenFile(FilePrxPtr remote, const std::string & path, int flags);

					void flush();
					void wait() const;

					FilePrxPtr remote;
					const std::string path;
					const int flags;
					class WriteState;
					typedef boost::icl::interval_map<Ice::Long, std::shared_ptr<WriteState>> BGs;
					static BGs::interval_type range(off_t, size_t);
					BGs bg;
					mutable std::shared_mutex _lock;
			};
			typedef std::shared_ptr<OpenFile> OpenFilePtr;
			typedef std::map<int, OpenFilePtr> OpenFiles;

		public:
			FuseApp(const Ice::StringSeq &);
			~FuseApp();

		private:
			void * init (struct fuse_conn_info * info) override;
			int opt_parse(void *, const char * arg, int key, struct fuse_args *) override;

			void connectSession();
			void connectToService();
			void connectToVolume();
			void connectHandles();
			void verifyConnection();

		public:
			// misc
			int access(const char * p, int a) override;
			int getattr(const char * p, struct stat * s) override;
			int fgetattr(const char *, struct stat *, struct fuse_file_info *) override;
			int chmod(const char *, mode_t) override;
			int chown(const char *, uid_t, gid_t) override;
			int link(const char *, const char *) override;
			int readlink(const char *, char *, size_t) override;
			int rename(const char *, const char *) override;
			int symlink(const char *, const char *) override;
			int unlink(const char *) override;
			int utimens(const char *, const struct timespec tv[2]) 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) 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;
			int truncate(const char *, off_t) override;
			int ftruncate(const char *, off_t, struct fuse_file_info *) override;
			// fs
			int statfs(const char *, struct statvfs *) override;
			// stuff
			int onError(const std::exception & err) throw() override;
			void beforeOperation() override;

			virtual struct fuse_context * fuse_get_context() = 0;

		protected:
			typedef std::function<Client::ResourcePtr()> Configurator;
			Configurator configurator;
			virtual NetFS::Client::ConfigurationPtr ReadConfiguration(const boost::filesystem::path &) const;
			virtual NetFS::Client::ResourcePtr configureFromFile(const std::string &, const std::string &) const;
			virtual NetFS::Client::ResourcePtr configureFromUri(const std::string &) const;

		private:
			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;

			EntCache<User> userLookup;
			EntCache<Group> groupLookup;
			EntryTypeConverter converter;

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

#endif