1 #ifndef FS_API_PRIVATE_H
2 #define FS_API_PRIVATE_H
3 
4 #include "fs-api.h"
5 #include "fs-wrapper.h"
6 #include "module-context.h"
7 
8 #include <sys/time.h>
9 
10 #define FS_EVENT_FIELD_FS "lib-fs#fs"
11 #define FS_EVENT_FIELD_FILE "lib-fs#file"
12 #define FS_EVENT_FIELD_ITER "lib-fs#iter"
13 
14 enum fs_get_metadata_flags {
15 	FS_GET_METADATA_FLAG_LOADED_ONLY = BIT(0),
16 };
17 
18 struct fs_api_module_register {
19 	unsigned int id;
20 };
21 
22 union fs_api_module_context {
23 	struct fs_api_module_register *reg;
24 };
25 
26 extern struct fs_api_module_register fs_api_module_register;
27 
28 struct fs_vfuncs {
29 	struct fs *(*alloc)(void);
30 	int (*init)(struct fs *fs, const char *args,
31 		    const struct fs_settings *set, const char **error_r);
32 	void (*deinit)(struct fs *fs);
33 	void (*free)(struct fs *fs);
34 
35 	enum fs_properties (*get_properties)(struct fs *fs);
36 
37 	struct fs_file *(*file_alloc)(void);
38 	void (*file_init)(struct fs_file *file, const char *path,
39 			  enum fs_open_mode mode, enum fs_open_flags flags);
40 	void (*file_deinit)(struct fs_file *file);
41 	void (*file_close)(struct fs_file *file);
42 	const char *(*get_path)(struct fs_file *file);
43 
44 	void (*set_async_callback)(struct fs_file *file,
45 				   fs_file_async_callback_t *callback,
46 				   void *context);
47 	void (*wait_async)(struct fs *fs);
48 
49 	void (*set_metadata)(struct fs_file *file, const char *key,
50 			     const char *value);
51 	int (*get_metadata)(struct fs_file *file,
52 			    enum fs_get_metadata_flags flags,
53 			    const ARRAY_TYPE(fs_metadata) **metadata_r);
54 
55 	bool (*prefetch)(struct fs_file *file, uoff_t length);
56 	ssize_t (*read)(struct fs_file *file, void *buf, size_t size);
57 	struct istream *(*read_stream)(struct fs_file *file,
58 				       size_t max_buffer_size);
59 
60 	int (*write)(struct fs_file *file, const void *data, size_t size);
61 	void (*write_stream)(struct fs_file *file);
62 	/* After write_stream_finish() is called once, all the following
63 	   (async) calls will have success==TRUE. */
64 	int (*write_stream_finish)(struct fs_file *file, bool success);
65 
66 	int (*lock)(struct fs_file *file, unsigned int secs,
67 		    struct fs_lock **lock_r);
68 	void (*unlock)(struct fs_lock *lock);
69 
70 	int (*exists)(struct fs_file *file);
71 	int (*stat)(struct fs_file *file, struct stat *st_r);
72 	int (*copy)(struct fs_file *src, struct fs_file *dest);
73 	int (*rename)(struct fs_file *src, struct fs_file *dest);
74 	int (*delete_file)(struct fs_file *file);
75 
76 	struct fs_iter *(*iter_alloc)(void);
77 	void (*iter_init)(struct fs_iter *iter, const char *path,
78 			  enum fs_iter_flags flags);
79 	const char *(*iter_next)(struct fs_iter *iter);
80 	int (*iter_deinit)(struct fs_iter *iter);
81 
82 	bool (*switch_ioloop)(struct fs *fs);
83 	int (*get_nlinks)(struct fs_file *file, nlink_t *nlinks_r);
84 };
85 
86 struct fs {
87 	struct fs *parent; /* for wrapper filesystems */
88 	const char *name;
89 	struct fs_vfuncs v;
90 	char *temp_path_prefix;
91 	int refcount;
92 
93 	char *username, *session_id;
94 
95 	struct fs_settings set;
96 
97 	/* may be used by fs_wait_async() to do the waiting */
98 	struct ioloop *wait_ioloop, *prev_ioloop;
99 
100 	unsigned int files_open_count;
101 	struct fs_file *files;
102 	struct fs_iter *iters;
103 	struct event *event;
104 
105 	struct fs_stats stats;
106 
107 	ARRAY(union fs_api_module_context *) module_contexts;
108 };
109 
110 struct fs_file {
111 	/* linked list of all files */
112 	struct fs_file *prev, *next;
113 
114 	struct fs_file *parent; /* for wrapper filesystems */
115 	struct fs *fs;
116 	struct ostream *output;
117 	struct event *event;
118 	char *path;
119 	char *last_error;
120 	enum fs_open_flags flags;
121 
122 	struct istream *seekable_input;
123 	struct istream *pending_read_input;
124 
125 	const struct hash_method *write_digest_method;
126 	void *write_digest;
127 
128 	pool_t metadata_pool;
129 	ARRAY_TYPE(fs_metadata) metadata;
130 
131 	struct fs_file *copy_src;
132 	struct istream *copy_input;
133 	struct ostream *copy_output;
134 
135 	struct timeval timing_start[FS_OP_COUNT];
136 
137 	bool write_pending:1;
138 	bool writing_stream:1;
139 	bool metadata_changed:1;
140 
141 	bool read_or_prefetch_counted:1;
142 	bool lookup_metadata_counted:1;
143 	bool stat_counted:1;
144 	bool copy_counted:1;
145 	bool istream_open:1;
146 	bool last_error_changed:1;
147 };
148 
149 struct fs_lock {
150 	struct fs_file *file;
151 };
152 
153 struct fs_iter {
154 	/* linked list of all iters */
155 	struct fs_iter *prev, *next;
156 
157 	struct fs *fs;
158 	struct event *event;
159 	char *path;
160 	enum fs_iter_flags flags;
161 	struct timeval start_time;
162 	char *last_error;
163 
164 	bool async_have_more;
165 	fs_file_async_callback_t *async_callback;
166 	void *async_context;
167 };
168 
169 extern const struct fs fs_class_dict;
170 extern const struct fs fs_class_posix;
171 extern const struct fs fs_class_randomfail;
172 extern const struct fs fs_class_metawrap;
173 extern const struct fs fs_class_sis;
174 extern const struct fs fs_class_sis_queue;
175 extern const struct fs fs_class_test;
176 
177 void fs_class_register(const struct fs *fs_class);
178 
179 /* Event must be fs_file or fs_iter events. Set errno from err. */
180 void fs_set_error(struct event *event, int err,
181 		  const char *fmt, ...) ATTR_FORMAT(3, 4);
182 /* Like fs_set_error(), but use the existing errno. */
183 void fs_set_error_errno(struct event *event, const char *fmt, ...) ATTR_FORMAT(2, 3);
184 void fs_file_set_error_async(struct fs_file *file);
185 
186 ssize_t fs_read_via_stream(struct fs_file *file, void *buf, size_t size);
187 int fs_write_via_stream(struct fs_file *file, const void *data, size_t size);
188 void fs_metadata_init(struct fs_file *file);
189 void fs_metadata_init_or_clear(struct fs_file *file);
190 void fs_default_set_metadata(struct fs_file *file,
191 			     const char *key, const char *value);
192 int fs_get_metadata_full(struct fs_file *file,
193 			 enum fs_get_metadata_flags flags,
194 			 const ARRAY_TYPE(fs_metadata) **metadata_r);
195 const char *fs_metadata_find(const ARRAY_TYPE(fs_metadata) *metadata,
196 			     const char *key);
197 int fs_default_copy(struct fs_file *src, struct fs_file *dest);
198 
199 void fs_file_timing_end(struct fs_file *file, enum fs_op op);
200 
201 struct fs_file *
202 fs_file_init_parent(struct fs_file *parent, const char *path,
203 		    enum fs_open_mode mode, enum fs_open_flags flags);
204 struct fs_iter *
205 fs_iter_init_parent(struct fs_iter *parent,
206 		    const char *path, enum fs_iter_flags flags);
207 void fs_file_free(struct fs_file *file);
208 
209 /* Same as fs_write_stream_abort_error(), except it closes the *parent* file
210    and error is left untouched */
211 void fs_write_stream_abort_parent(struct fs_file *file, struct ostream **output);
212 
213 #endif
214