2
FUSE: Filesystem in Userspace
3
Copyright (C) 2001-2005 Miklos Szeredi <miklos@szeredi.hu>
5
This program can be distributed under the terms of the GNU GPL.
10
#include <linux/fuse.h>
12
#include "fuse_kernel.h"
13
#include <linux/version.h>
15
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) && LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
16
#error Kernel version 2.5.* not supported
19
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
21
# if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,6)
22
# define KERNEL_2_6_6_PLUS
24
# if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,8)
25
# define KERNEL_2_6_8_PLUS
27
# if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10)
28
# define KERNEL_2_6_10_PLUS
34
# include <linux/config.h>
35
# ifdef CONFIG_MODVERSIONS
37
# include <linux/modversions.h>
39
# ifndef HAVE_I_SIZE_FUNC
40
# define i_size_read(inode) ((inode)->i_size)
41
# define i_size_write(inode, size) do { (inode)->i_size = size; } while(0)
43
# define new_decode_dev(x) (x)
44
# define new_encode_dev(x) (x)
45
#endif /* KERNEL_2_6 */
46
#endif /* FUSE_MAINLINE */
48
#include <linux/wait.h>
49
#include <linux/list.h>
50
#include <linux/spinlock.h>
53
#include <linux/backing-dev.h>
55
#include <asm/semaphore.h>
61
#define container_of(ptr, type, member) ({ \
62
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
63
(type *)( (char *)__mptr - offsetof(type,member) );})
69
#include <linux/pagemap.h>
70
static inline void set_page_dirty_lock(struct page *page)
77
/** Max number of pages that can be used in a single read request */
78
#define FUSE_MAX_PAGES_PER_REQ 32
80
/** If more requests are outstanding, then the operation will block */
81
#define FUSE_MAX_OUTSTANDING 10
83
/** If the FUSE_DEFAULT_PERMISSIONS flag is given, the filesystem
84
module will check permissions based on the file mode. Otherwise no
85
permission checking is done in the kernel */
86
#define FUSE_DEFAULT_PERMISSIONS (1 << 0)
88
/** If the FUSE_ALLOW_OTHER flag is given, then not only the user
89
doing the mount will be allowed to access the filesystem */
90
#define FUSE_ALLOW_OTHER (1 << 1)
92
/** If the FUSE_KERNEL_CACHE flag is given, then cached data will not
94
#define FUSE_KERNEL_CACHE (1 << 2)
97
/** Allow FUSE to combine reads into 64k chunks. This is useful if
98
the filesystem is better at handling large chunks */
99
#define FUSE_LARGE_READ (1 << 31)
101
/** Bypass the page cache for read and write operations */
102
#define FUSE_DIRECT_IO (1 << 3)
104
/** Allow root and setuid-root programs to access fuse-mounted
106
#define FUSE_ALLOW_ROOT (1 << 4)
113
/** Unique ID, which identifies the inode between userspace
117
/** The request used for sending the FORGET message */
118
struct fuse_req *forget_req;
120
/** Time in jiffies until the file attributes are valid */
121
unsigned long i_time;
124
/** FUSE specific file data */
126
/** Request reserved for flush and release */
127
struct fuse_req *release_req;
129
/** File handle used by userspace */
133
/** One input argument of a request */
139
/** The request input */
141
/** The request header */
142
struct fuse_in_header h;
144
/** True if the data for the last argument is in req->pages */
147
/** Number of arguments */
150
/** Array of arguments */
151
struct fuse_in_arg args[3];
154
/** One output argument of a request */
160
/** The request output */
162
/** Header returned from userspace */
163
struct fuse_out_header h;
165
/** Last argument is variable length (can be shorter than
169
/** Last argument is a list of pages to copy data to */
172
/** Zero partially or not copied pages */
173
unsigned page_zeroing:1;
175
/** Number or arguments */
178
/** Array of arguments */
179
struct fuse_arg args[3];
186
* A request to the client
189
/** This can be on either unused_list, pending or processing
190
lists in fuse_conn */
191
struct list_head list;
196
/** True if the request has reply */
199
/** The request is preallocated */
200
unsigned preallocated:1;
202
/** The request was interrupted */
203
unsigned interrupted:1;
205
/** Request is sent in the background */
206
unsigned background:1;
208
/** Data is being copied to/from the request */
211
/** Request has been sent to userspace */
214
/** The request is finished */
217
/** The request input */
220
/** The request output */
223
/** Used to wake up the task waiting for completion of request*/
224
wait_queue_head_t waitq;
226
/** Data for asynchronous requests */
228
struct fuse_forget_in forget_in;
229
struct fuse_release_in release_in;
230
struct fuse_init_in_out init_in_out;
234
struct page *pages[FUSE_MAX_PAGES_PER_REQ];
236
/** number of pages in vector */
239
/** offset of data on first page */
240
unsigned page_offset;
242
/** Inode used in the request */
245
/** Second inode used in the request (or NULL) */
246
struct inode *inode2;
248
/** File used in the request (or NULL) */
255
* This structure is created, when the filesystem is mounted, and is
256
* destroyed, when the client device is closed and the filesystem is
260
/** The superblock of the mounted filesystem */
261
struct super_block *sb;
263
/** The opened client device */
266
/** The user id for this mount */
269
/** The fuse mount flags for this mount */
272
/** Maximum read size */
275
/** Maximum write size */
278
/** Readers of the connection are waiting on this */
279
wait_queue_head_t waitq;
281
/** The list of pending requests */
282
struct list_head pending;
284
/** The list of requests being processed */
285
struct list_head processing;
287
/** Controls the maximum number of outstanding requests */
288
struct semaphore outstanding_sem;
290
/** This counts the number of outstanding requests if
291
outstanding_sem would go negative */
292
unsigned outstanding_debt;
294
/** The list of unused requests */
295
struct list_head unused_list;
297
/** The next unique request id */
300
/** Is fsync not implemented by fs? */
301
unsigned no_fsync : 1;
303
/** Is flush not implemented by fs? */
304
unsigned no_flush : 1;
306
/** Is setxattr not implemented by fs? */
307
unsigned no_setxattr : 1;
309
/** Is getxattr not implemented by fs? */
310
unsigned no_getxattr : 1;
312
/** Is listxattr not implemented by fs? */
313
unsigned no_listxattr : 1;
315
/** Is removexattr not implemented by fs? */
316
unsigned no_removexattr : 1;
319
/** Backing dev info */
320
struct backing_dev_info bdi;
324
static inline struct fuse_conn **get_fuse_conn_super_p(struct super_block *sb)
327
return (struct fuse_conn **) &sb->s_fs_info;
329
return (struct fuse_conn **) &sb->u.generic_sbp;
333
static inline struct fuse_conn *get_fuse_conn_super(struct super_block *sb)
335
return *get_fuse_conn_super_p(sb);
338
static inline struct fuse_conn *get_fuse_conn(struct inode *inode)
340
return get_fuse_conn_super(inode->i_sb);
343
static inline struct fuse_inode *get_fuse_inode(struct inode *inode)
345
return container_of(inode, struct fuse_inode, inode);
348
static inline u64 get_node_id(struct inode *inode)
350
return get_fuse_inode(inode)->nodeid;
353
/** Device operations */
354
extern struct file_operations fuse_dev_operations;
357
* This is the single global spinlock which protects FUSE's structures
359
* The following data is protected by this lock:
361
* - the private_data field of the device file
362
* - the s_fs_info field of the super block
363
* - unused_list, pending, processing lists in fuse_conn
364
* - the unique request ID counter reqctr in fuse_conn
365
* - the sb (super_block) field in fuse_conn
366
* - the file (device file) field in fuse_conn
368
extern spinlock_t fuse_lock;
371
* Get a filled in inode
373
struct inode *fuse_iget(struct super_block *sb, unsigned long nodeid,
374
int generation, struct fuse_attr *attr, int version);
377
* Send FORGET command
379
void fuse_send_forget(struct fuse_conn *fc, struct fuse_req *req,
380
unsigned long nodeid, int version);
383
* Send READ or READDIR request
385
size_t fuse_send_read_common(struct fuse_req *req, struct file *file,
386
struct inode *inode, loff_t pos, size_t count,
390
* Send OPEN or OPENDIR request
392
int fuse_open_common(struct inode *inode, struct file *file, int isdir);
395
* Send RELEASE or RELEASEDIR request
397
int fuse_release_common(struct inode *inode, struct file *file, int isdir);
400
* Initialise file operations on a regular file
402
void fuse_init_file_inode(struct inode *inode);
405
* Initialise inode operations on regular files and special files
407
void fuse_init_common(struct inode *inode);
410
* Initialise inode and file operations on a directory
412
void fuse_init_dir(struct inode *inode);
415
* Initialise inode operations on a symlink
417
void fuse_init_symlink(struct inode *inode);
420
* Change attributes of an inode
422
void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr);
425
* Check if the connection can be released, and if yes, then free the
426
* connection structure
428
void fuse_release_conn(struct fuse_conn *fc);
431
* Initialize the client device
433
int fuse_dev_init(void);
436
* Cleanup the client device
438
void fuse_dev_cleanup(void);
443
struct fuse_req *fuse_request_alloc(void);
448
void fuse_request_free(struct fuse_req *req);
451
* Reinitialize a request, the preallocated flag is left unmodified
453
void fuse_reset_request(struct fuse_req *req);
456
* Reserve a preallocated request
458
struct fuse_req *fuse_get_request(struct fuse_conn *fc);
461
* Reserve a preallocated request, only interruptible by SIGKILL
463
struct fuse_req *fuse_get_request_nonint(struct fuse_conn *fc);
466
* Decrement reference count of a request. If count goes to zero put
467
* on unused list (preallocated) or free reqest (not preallocated).
469
void fuse_put_request(struct fuse_conn *fc, struct fuse_req *req);
472
* Send a request (synchronous, interruptible)
474
void request_send(struct fuse_conn *fc, struct fuse_req *req);
477
* Send a request (synchronous, non-interruptible except by SIGKILL)
479
void request_send_nonint(struct fuse_conn *fc, struct fuse_req *req);
482
* Send a request with no reply
484
void request_send_noreply(struct fuse_conn *fc, struct fuse_req *req);
487
* Send a request in the background
489
void request_send_background(struct fuse_conn *fc, struct fuse_req *req);
492
* Get the attributes of a file
494
int fuse_do_getattr(struct inode *inode);
497
* Invalidate inode attributes
499
void fuse_invalidate_attr(struct inode *inode);
502
* Send the INIT message
504
void fuse_send_init(struct fuse_conn *fc);