xref: /haiku/src/add-ons/kernel/file_systems/userlandfs/server/fuse/fuse_fs.cpp (revision da8162be21b36442f34a731873d2358a0d63c25a)
1 /*
2  * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
3  * Distributed under the terms of the MIT License.
4  */
5 
6 #include "fuse_fs.h"
7 
8 #include <string.h>
9 
10 #include <new>
11 
12 #include "Debug.h"
13 
14 
15 int
fuse_fs_getattr(struct fuse_fs * fs,const char * path,struct stat * buf)16 fuse_fs_getattr(struct fuse_fs* fs, const char* path, struct stat* buf)
17 {
18 	if (fs->ops.getattr == NULL)
19 		return ENOSYS;
20 	return fs->ops.getattr(path, buf);
21 }
22 
23 
24 int
fuse_fs_fgetattr(struct fuse_fs * fs,const char * path,struct stat * buf,struct fuse_file_info * fi)25 fuse_fs_fgetattr(struct fuse_fs* fs, const char* path, struct stat* buf,
26 	struct fuse_file_info* fi)
27 {
28 	if (fs->ops.fgetattr == NULL)
29 		return ENOSYS;
30 	return fs->ops.fgetattr(path, buf, fi);
31 }
32 
33 
34 int
fuse_fs_rename(struct fuse_fs * fs,const char * oldpath,const char * newpath)35 fuse_fs_rename(struct fuse_fs* fs, const char* oldpath, const char* newpath)
36 {
37 	if (fs->ops.rename == NULL)
38 		return ENOSYS;
39 	return fs->ops.rename(oldpath, newpath);
40 }
41 
42 
43 int
fuse_fs_unlink(struct fuse_fs * fs,const char * path)44 fuse_fs_unlink(struct fuse_fs* fs, const char* path)
45 {
46 	if (fs->ops.unlink == NULL)
47 		return ENOSYS;
48 	return fs->ops.unlink(path);
49 }
50 
51 
52 int
fuse_fs_rmdir(struct fuse_fs * fs,const char * path)53 fuse_fs_rmdir(struct fuse_fs* fs, const char* path)
54 {
55 	if (fs->ops.rmdir == NULL)
56 		return ENOSYS;
57 	return fs->ops.rmdir(path);
58 }
59 
60 
61 int
fuse_fs_symlink(struct fuse_fs * fs,const char * linkname,const char * path)62 fuse_fs_symlink(struct fuse_fs* fs, const char* linkname, const char* path)
63 {
64 	if (fs->ops.symlink == NULL)
65 		return ENOSYS;
66 	return fs->ops.symlink(linkname, path);
67 }
68 
69 
70 int
fuse_fs_link(struct fuse_fs * fs,const char * oldpath,const char * newpath)71 fuse_fs_link(struct fuse_fs* fs, const char* oldpath, const char* newpath)
72 {
73 	if (fs->ops.link == NULL)
74 		return ENOSYS;
75 	return fs->ops.link(oldpath, newpath);
76 }
77 
78 
79 int
fuse_fs_release(struct fuse_fs * fs,const char * path,struct fuse_file_info * fi)80 fuse_fs_release(struct fuse_fs* fs,	 const char* path,
81 	struct fuse_file_info* fi)
82 {
83 	if (fs->ops.release == NULL)
84 		return 0;
85 	return fs->ops.release(path, fi);
86 }
87 
88 
89 int
fuse_fs_open(struct fuse_fs * fs,const char * path,struct fuse_file_info * fi)90 fuse_fs_open(struct fuse_fs* fs, const char* path, struct fuse_file_info* fi)
91 {
92 	if (fs->ops.open == NULL)
93 		return 0;
94 	return fs->ops.open(path, fi);
95 }
96 
97 
98 int
fuse_fs_read(struct fuse_fs * fs,const char * path,char * buf,size_t size,off_t off,struct fuse_file_info * fi)99 fuse_fs_read(struct fuse_fs* fs, const char* path, char *buf, size_t size,
100 	off_t off, struct fuse_file_info* fi)
101 {
102 	if (fs->ops.read == NULL)
103 		return ENOSYS;
104 	return fs->ops.read(path, buf, size, off, fi);
105 }
106 
107 
108 int
fuse_fs_write(struct fuse_fs * fs,const char * path,const char * buf,size_t size,off_t off,struct fuse_file_info * fi)109 fuse_fs_write(struct fuse_fs* fs, const char* path, const char* buf,
110 	size_t size, off_t off, struct fuse_file_info* fi)
111 {
112 	if (fs->ops.write == NULL)
113 		return ENOSYS;
114 	return fs->ops.write(path, buf, size, off, fi);
115 }
116 
117 
118 int
fuse_fs_fsync(struct fuse_fs * fs,const char * path,int datasync,struct fuse_file_info * fi)119 fuse_fs_fsync(struct fuse_fs* fs, const char* path, int datasync,
120 	struct fuse_file_info* fi)
121 {
122 	if (fs->ops.fsync == NULL)
123 		return ENOSYS;
124 	return fs->ops.fsync(path, datasync, fi);
125 }
126 
127 
128 int
fuse_fs_flush(struct fuse_fs * fs,const char * path,struct fuse_file_info * fi)129 fuse_fs_flush(struct fuse_fs* fs, const char* path, struct fuse_file_info* fi)
130 {
131 	if (fs->ops.flush == NULL)
132 		return ENOSYS;
133 	return fs->ops.flush(path, fi);
134 }
135 
136 
137 int
fuse_fs_statfs(struct fuse_fs * fs,const char * path,struct statvfs * buf)138 fuse_fs_statfs(struct fuse_fs* fs, const char* path, struct statvfs* buf)
139 {
140 	if (fs->ops.statfs == NULL)
141 		return 0;
142 	return fs->ops.statfs(path, buf);
143 }
144 
145 
146 int
fuse_fs_opendir(struct fuse_fs * fs,const char * path,struct fuse_file_info * fi)147 fuse_fs_opendir(struct fuse_fs* fs, const char* path, struct fuse_file_info* fi)
148 {
149 	if (fs->ops.opendir == NULL)
150 		return 0;
151 	return fs->ops.opendir(path, fi);
152 }
153 
154 
155 int
fuse_fs_readdir(struct fuse_fs * fs,const char * path,void * buf,fuse_fill_dir_t filler,off_t off,struct fuse_file_info * fi)156 fuse_fs_readdir(struct fuse_fs* fs, const char* path, void* buf,
157 	fuse_fill_dir_t filler, off_t off, struct fuse_file_info* fi)
158 {
159 	if (fs->ops.readdir == NULL)
160 		return ENOSYS;
161 	return fs->ops.readdir(path, buf, filler, off, fi);
162 }
163 
164 
165 int
fuse_fs_fsyncdir(struct fuse_fs * fs,const char * path,int datasync,struct fuse_file_info * fi)166 fuse_fs_fsyncdir(struct fuse_fs* fs, const char* path, int datasync,
167 	struct fuse_file_info* fi)
168 {
169 	if (fs->ops.fsyncdir == NULL)
170 		return ENOSYS;
171 	return fs->ops.fsyncdir(path, datasync, fi);
172 }
173 
174 
175 int
fuse_fs_releasedir(struct fuse_fs * fs,const char * path,struct fuse_file_info * fi)176 fuse_fs_releasedir(struct fuse_fs* fs, const char* path,
177 	struct fuse_file_info* fi)
178 {
179 	if (fs->ops.releasedir == NULL)
180 		return 0;
181 	return fs->ops.releasedir(path, fi);
182 }
183 
184 
185 int
fuse_fs_create(struct fuse_fs * fs,const char * path,mode_t mode,struct fuse_file_info * fi)186 fuse_fs_create(struct fuse_fs* fs, const char* path, mode_t mode,
187 	struct fuse_file_info* fi)
188 {
189 	if (fs->ops.create == NULL)
190 		return ENOSYS;
191 	return fs->ops.create(path, mode, fi);
192 }
193 
194 
195 int
fuse_fs_lock(struct fuse_fs * fs,const char * path,struct fuse_file_info * fi,int cmd,struct flock * lock)196 fuse_fs_lock(struct fuse_fs* fs, const char* path, struct fuse_file_info* fi,
197 	int cmd, struct flock* lock)
198 {
199 	if (fs->ops.lock == NULL)
200 		return ENOSYS;
201 	return fs->ops.lock(path, fi, cmd, lock);
202 }
203 
204 
205 int
fuse_fs_chmod(struct fuse_fs * fs,const char * path,mode_t mode)206 fuse_fs_chmod(struct fuse_fs* fs, const char* path, mode_t mode)
207 {
208 	if (fs->ops.chmod == NULL)
209 		return ENOSYS;
210 	return fs->ops.chmod(path, mode);
211 }
212 
213 
214 int
fuse_fs_chown(struct fuse_fs * fs,const char * path,uid_t uid,gid_t gid)215 fuse_fs_chown(struct fuse_fs* fs, const char* path, uid_t uid, gid_t gid)
216 {
217 	if (fs->ops.chown == NULL)
218 		return ENOSYS;
219 	return fs->ops.chown(path, uid, gid);
220 }
221 
222 
223 int
fuse_fs_truncate(struct fuse_fs * fs,const char * path,off_t size)224 fuse_fs_truncate(struct fuse_fs* fs, const char* path, off_t size)
225 {
226 	if (fs->ops.truncate == NULL)
227 		return ENOSYS;
228 	return fs->ops.truncate(path, size);
229 }
230 
231 
232 int
fuse_fs_ftruncate(struct fuse_fs * fs,const char * path,off_t size,struct fuse_file_info * fi)233 fuse_fs_ftruncate(struct fuse_fs* fs, const char* path, off_t size,
234 	struct fuse_file_info* fi)
235 {
236 	if (fs->ops.ftruncate == NULL)
237 		return ENOSYS;
238 	return fs->ops.ftruncate(path, size, fi);
239 }
240 
241 
242 int
fuse_fs_utimens(struct fuse_fs * fs,const char * path,const struct timespec tv[2])243 fuse_fs_utimens(struct fuse_fs* fs, const char* path,
244 	const struct timespec tv[2])
245 {
246 	if (fs->ops.utimens != NULL)
247 		return fs->ops.utimens(path, tv);
248 
249 	if (fs->ops.utime != NULL) {
250 		utimbuf timeBuffer = {
251 			tv[0].tv_sec,	// access time
252 			tv[1].tv_sec	// modification time
253 		};
254 		return fs->ops.utime(path, &timeBuffer);
255 	}
256 
257 	return ENOSYS;
258 }
259 
260 
261 int
fuse_fs_access(struct fuse_fs * fs,const char * path,int mask)262 fuse_fs_access(struct fuse_fs* fs, const char* path, int mask)
263 {
264 	if (fs->ops.access == NULL)
265 		return ENOSYS;
266 	return fs->ops.access(path, mask);
267 }
268 
269 
270 int
fuse_fs_readlink(struct fuse_fs * fs,const char * path,char * buf,size_t len)271 fuse_fs_readlink(struct fuse_fs* fs, const char* path, char* buf, size_t len)
272 {
273 	if (fs->ops.readlink == NULL)
274 		return ENOSYS;
275 	return fs->ops.readlink(path, buf, len);
276 }
277 
278 
279 int
fuse_fs_mknod(struct fuse_fs * fs,const char * path,mode_t mode,dev_t rdev)280 fuse_fs_mknod(struct fuse_fs* fs, const char* path, mode_t mode, dev_t rdev)
281 {
282 	if (fs->ops.mknod == NULL)
283 		return ENOSYS;
284 	return fs->ops.mknod(path, mode, rdev);
285 }
286 
287 
288 int
fuse_fs_mkdir(struct fuse_fs * fs,const char * path,mode_t mode)289 fuse_fs_mkdir(struct fuse_fs* fs, const char* path, mode_t mode)
290 {
291 	if (fs->ops.mkdir == NULL)
292 		return ENOSYS;
293 	return fs->ops.mkdir(path, mode);
294 }
295 
296 
297 int
fuse_fs_setxattr(struct fuse_fs * fs,const char * path,const char * name,const char * value,size_t size,int flags)298 fuse_fs_setxattr(struct fuse_fs* fs, const char* path, const char* name,
299 	const char* value, size_t size, int flags)
300 {
301 	if (fs->ops.setxattr == NULL)
302 		return ENOSYS;
303 	return fs->ops.setxattr(path, name, value, size, flags);
304 }
305 
306 
307 int
fuse_fs_getxattr(struct fuse_fs * fs,const char * path,const char * name,char * value,size_t size)308 fuse_fs_getxattr(struct fuse_fs* fs, const char* path, const char* name,
309 	char* value, size_t size)
310 {
311 	if (fs->ops.getxattr == NULL)
312 		return ENOSYS;
313 	return fs->ops.getxattr(path, name, value, size);
314 }
315 
316 
317 int
fuse_fs_listxattr(struct fuse_fs * fs,const char * path,char * list,size_t size)318 fuse_fs_listxattr(struct fuse_fs* fs, const char* path, char* list, size_t size)
319 {
320 	if (fs->ops.listxattr == NULL)
321 		return ENOSYS;
322 	return fs->ops.listxattr(path, list, size);
323 }
324 
325 
326 int
fuse_fs_removexattr(struct fuse_fs * fs,const char * path,const char * name)327 fuse_fs_removexattr(struct fuse_fs* fs, const char* path, const char* name)
328 {
329 	if (fs->ops.removexattr == NULL)
330 		return ENOSYS;
331 	return fs->ops.removexattr(path, name);
332 }
333 
334 
335 int
fuse_fs_bmap(struct fuse_fs * fs,const char * path,size_t blocksize,uint64_t * idx)336 fuse_fs_bmap(struct fuse_fs* fs, const char* path, size_t blocksize,
337 	uint64_t* idx)
338 {
339 	if (fs->ops.bmap == NULL)
340 		return ENOSYS;
341 	return fs->ops.bmap(path, blocksize, idx);
342 }
343 
344 
fuse_fs_ioctl(struct fuse_fs * fs,const char * path,int cmd,void * arg,struct fuse_file_info * fi,unsigned int flags,void * data)345 int fuse_fs_ioctl(struct fuse_fs *fs, const char *path, int cmd, void *arg,
346 	struct fuse_file_info *fi, unsigned int flags, void *data)
347 {
348 	if (fs->ops.ioctl == NULL)
349 		return ENOSYS;
350 
351 	return fs->ops.ioctl(path, cmd, arg, fi, flags, data);
352 }
353 
354 
355 void
fuse_fs_init(struct fuse_fs * fs,struct fuse_conn_info * conn)356 fuse_fs_init(struct fuse_fs* fs, struct fuse_conn_info* conn)
357 {
358 	if (fs->ops.init == NULL)
359 		return;
360 	fs->ops.init(conn);
361 }
362 
363 
364 void
fuse_fs_destroy(struct fuse_fs * fs)365 fuse_fs_destroy(struct fuse_fs* fs)
366 {
367 	if (fs->ops.destroy != NULL)
368 		fs->ops.destroy(fs->userData);
369 
370 	delete fs;
371 }
372 
373 
374 struct fuse_fs*
fuse_fs_new(const struct fuse_operations * ops,size_t opSize,void * userData)375 fuse_fs_new(const struct fuse_operations* ops, size_t opSize, void* userData)
376 {
377 	if (sizeof(fuse_operations) < opSize) {
378 		ERROR(("fuse_fs_new(): Client FS built with newer library version!\n"));
379 		return NULL;
380 	}
381 
382 	fuse_fs* fs = new(std::nothrow) fuse_fs;
383 	if (fs == NULL)
384 		return NULL;
385 
386 	memset(&fs->ops, 0, sizeof(fuse_operations));
387 	memcpy(&fs->ops, ops, opSize);
388 
389 	fs->userData = userData;
390 
391 	return fs;
392 }
393 
394