]> pilppa.org Git - linux-2.6-omap-h63xx.git/blob - fs/fuse/fuse_i.h
[PATCH] fuse: clean up request accounting
[linux-2.6-omap-h63xx.git] / fs / fuse / fuse_i.h
1 /*
2   FUSE: Filesystem in Userspace
3   Copyright (C) 2001-2006  Miklos Szeredi <miklos@szeredi.hu>
4
5   This program can be distributed under the terms of the GNU GPL.
6   See the file COPYING.
7 */
8
9 #include <linux/fuse.h>
10 #include <linux/fs.h>
11 #include <linux/wait.h>
12 #include <linux/list.h>
13 #include <linux/spinlock.h>
14 #include <linux/mm.h>
15 #include <linux/backing-dev.h>
16 #include <asm/semaphore.h>
17
18 /** Max number of pages that can be used in a single read request */
19 #define FUSE_MAX_PAGES_PER_REQ 32
20
21 /** It could be as large as PATH_MAX, but would that have any uses? */
22 #define FUSE_NAME_MAX 1024
23
24 /** If the FUSE_DEFAULT_PERMISSIONS flag is given, the filesystem
25     module will check permissions based on the file mode.  Otherwise no
26     permission checking is done in the kernel */
27 #define FUSE_DEFAULT_PERMISSIONS (1 << 0)
28
29 /** If the FUSE_ALLOW_OTHER flag is given, then not only the user
30     doing the mount will be allowed to access the filesystem */
31 #define FUSE_ALLOW_OTHER         (1 << 1)
32
33
34 /** FUSE inode */
35 struct fuse_inode {
36         /** Inode data */
37         struct inode inode;
38
39         /** Unique ID, which identifies the inode between userspace
40          * and kernel */
41         u64 nodeid;
42
43         /** Number of lookups on this inode */
44         u64 nlookup;
45
46         /** The request used for sending the FORGET message */
47         struct fuse_req *forget_req;
48
49         /** Time in jiffies until the file attributes are valid */
50         unsigned long i_time;
51 };
52
53 /** FUSE specific file data */
54 struct fuse_file {
55         /** Request reserved for flush and release */
56         struct fuse_req *release_req;
57
58         /** File handle used by userspace */
59         u64 fh;
60 };
61
62 /** One input argument of a request */
63 struct fuse_in_arg {
64         unsigned size;
65         const void *value;
66 };
67
68 /** The request input */
69 struct fuse_in {
70         /** The request header */
71         struct fuse_in_header h;
72
73         /** True if the data for the last argument is in req->pages */
74         unsigned argpages:1;
75
76         /** Number of arguments */
77         unsigned numargs;
78
79         /** Array of arguments */
80         struct fuse_in_arg args[3];
81 };
82
83 /** One output argument of a request */
84 struct fuse_arg {
85         unsigned size;
86         void *value;
87 };
88
89 /** The request output */
90 struct fuse_out {
91         /** Header returned from userspace */
92         struct fuse_out_header h;
93
94         /*
95          * The following bitfields are not changed during the request
96          * processing
97          */
98
99         /** Last argument is variable length (can be shorter than
100             arg->size) */
101         unsigned argvar:1;
102
103         /** Last argument is a list of pages to copy data to */
104         unsigned argpages:1;
105
106         /** Zero partially or not copied pages */
107         unsigned page_zeroing:1;
108
109         /** Number or arguments */
110         unsigned numargs;
111
112         /** Array of arguments */
113         struct fuse_arg args[3];
114 };
115
116 /** The request state */
117 enum fuse_req_state {
118         FUSE_REQ_INIT = 0,
119         FUSE_REQ_PENDING,
120         FUSE_REQ_READING,
121         FUSE_REQ_SENT,
122         FUSE_REQ_FINISHED
123 };
124
125 struct fuse_conn;
126
127 /**
128  * A request to the client
129  */
130 struct fuse_req {
131         /** This can be on either pending processing or io lists in
132             fuse_conn */
133         struct list_head list;
134
135         /** Entry on the background list */
136         struct list_head bg_entry;
137
138         /** refcount */
139         atomic_t count;
140
141         /*
142          * The following bitfields are either set once before the
143          * request is queued or setting/clearing them is protected by
144          * fuse_conn->lock
145          */
146
147         /** True if the request has reply */
148         unsigned isreply:1;
149
150         /** The request was interrupted */
151         unsigned interrupted:1;
152
153         /** Request is sent in the background */
154         unsigned background:1;
155
156         /** Data is being copied to/from the request */
157         unsigned locked:1;
158
159         /** State of the request */
160         enum fuse_req_state state;
161
162         /** The request input */
163         struct fuse_in in;
164
165         /** The request output */
166         struct fuse_out out;
167
168         /** Used to wake up the task waiting for completion of request*/
169         wait_queue_head_t waitq;
170
171         /** Data for asynchronous requests */
172         union {
173                 struct fuse_forget_in forget_in;
174                 struct fuse_release_in release_in;
175                 struct fuse_init_in init_in;
176                 struct fuse_init_out init_out;
177                 struct fuse_read_in read_in;
178         } misc;
179
180         /** page vector */
181         struct page *pages[FUSE_MAX_PAGES_PER_REQ];
182
183         /** number of pages in vector */
184         unsigned num_pages;
185
186         /** offset of data on first page */
187         unsigned page_offset;
188
189         /** Inode used in the request */
190         struct inode *inode;
191
192         /** Second inode used in the request (or NULL) */
193         struct inode *inode2;
194
195         /** File used in the request (or NULL) */
196         struct file *file;
197
198         /** Request completion callback */
199         void (*end)(struct fuse_conn *, struct fuse_req *);
200 };
201
202 /**
203  * A Fuse connection.
204  *
205  * This structure is created, when the filesystem is mounted, and is
206  * destroyed, when the client device is closed and the filesystem is
207  * unmounted.
208  */
209 struct fuse_conn {
210         /** Lock protecting accessess to  members of this structure */
211         spinlock_t lock;
212
213         /** The user id for this mount */
214         uid_t user_id;
215
216         /** The group id for this mount */
217         gid_t group_id;
218
219         /** The fuse mount flags for this mount */
220         unsigned flags;
221
222         /** Maximum read size */
223         unsigned max_read;
224
225         /** Maximum write size */
226         unsigned max_write;
227
228         /** Readers of the connection are waiting on this */
229         wait_queue_head_t waitq;
230
231         /** The list of pending requests */
232         struct list_head pending;
233
234         /** The list of requests being processed */
235         struct list_head processing;
236
237         /** The list of requests under I/O */
238         struct list_head io;
239
240         /** Requests put in the background (RELEASE or any other
241             interrupted request) */
242         struct list_head background;
243
244         /** RW semaphore for exclusion with fuse_put_super() */
245         struct rw_semaphore sbput_sem;
246
247         /** The next unique request id */
248         u64 reqctr;
249
250         /** Mount is active */
251         unsigned mounted;
252
253         /** Connection established, cleared on umount, connection
254             abort and device release */
255         unsigned connected;
256
257         /** Connection failed (version mismatch).  Cannot race with
258             setting other bitfields since it is only set once in INIT
259             reply, before any other request, and never cleared */
260         unsigned conn_error : 1;
261
262         /** Do readpages asynchronously?  Only set in INIT */
263         unsigned async_read : 1;
264
265         /*
266          * The following bitfields are only for optimization purposes
267          * and hence races in setting them will not cause malfunction
268          */
269
270         /** Is fsync not implemented by fs? */
271         unsigned no_fsync : 1;
272
273         /** Is fsyncdir not implemented by fs? */
274         unsigned no_fsyncdir : 1;
275
276         /** Is flush not implemented by fs? */
277         unsigned no_flush : 1;
278
279         /** Is setxattr not implemented by fs? */
280         unsigned no_setxattr : 1;
281
282         /** Is getxattr not implemented by fs? */
283         unsigned no_getxattr : 1;
284
285         /** Is listxattr not implemented by fs? */
286         unsigned no_listxattr : 1;
287
288         /** Is removexattr not implemented by fs? */
289         unsigned no_removexattr : 1;
290
291         /** Is access not implemented by fs? */
292         unsigned no_access : 1;
293
294         /** Is create not implemented by fs? */
295         unsigned no_create : 1;
296
297         /** The number of requests waiting for completion */
298         atomic_t num_waiting;
299
300         /** Negotiated minor version */
301         unsigned minor;
302
303         /** Backing dev info */
304         struct backing_dev_info bdi;
305
306         /** kobject */
307         struct kobject kobj;
308
309         /** O_ASYNC requests */
310         struct fasync_struct *fasync;
311 };
312
313 static inline struct fuse_conn *get_fuse_conn_super(struct super_block *sb)
314 {
315         return sb->s_fs_info;
316 }
317
318 static inline struct fuse_conn *get_fuse_conn(struct inode *inode)
319 {
320         return get_fuse_conn_super(inode->i_sb);
321 }
322
323 static inline struct fuse_conn *get_fuse_conn_kobj(struct kobject *obj)
324 {
325         return container_of(obj, struct fuse_conn, kobj);
326 }
327
328 static inline struct fuse_inode *get_fuse_inode(struct inode *inode)
329 {
330         return container_of(inode, struct fuse_inode, inode);
331 }
332
333 static inline u64 get_node_id(struct inode *inode)
334 {
335         return get_fuse_inode(inode)->nodeid;
336 }
337
338 /** Device operations */
339 extern const struct file_operations fuse_dev_operations;
340
341 /**
342  * Get a filled in inode
343  */
344 struct inode *fuse_iget(struct super_block *sb, unsigned long nodeid,
345                         int generation, struct fuse_attr *attr);
346
347 /**
348  * Send FORGET command
349  */
350 void fuse_send_forget(struct fuse_conn *fc, struct fuse_req *req,
351                       unsigned long nodeid, u64 nlookup);
352
353 /**
354  * Initialize READ or READDIR request
355  */
356 void fuse_read_fill(struct fuse_req *req, struct file *file,
357                     struct inode *inode, loff_t pos, size_t count, int opcode);
358
359 /**
360  * Send OPEN or OPENDIR request
361  */
362 int fuse_open_common(struct inode *inode, struct file *file, int isdir);
363
364 struct fuse_file *fuse_file_alloc(void);
365 void fuse_file_free(struct fuse_file *ff);
366 void fuse_finish_open(struct inode *inode, struct file *file,
367                       struct fuse_file *ff, struct fuse_open_out *outarg);
368
369 /**
370  * Send a RELEASE request
371  */
372 void fuse_send_release(struct fuse_conn *fc, struct fuse_file *ff,
373                        u64 nodeid, struct inode *inode, int flags, int isdir);
374
375 /**
376  * Send RELEASE or RELEASEDIR request
377  */
378 int fuse_release_common(struct inode *inode, struct file *file, int isdir);
379
380 /**
381  * Send FSYNC or FSYNCDIR request
382  */
383 int fuse_fsync_common(struct file *file, struct dentry *de, int datasync,
384                       int isdir);
385
386 /**
387  * Initialize file operations on a regular file
388  */
389 void fuse_init_file_inode(struct inode *inode);
390
391 /**
392  * Initialize inode operations on regular files and special files
393  */
394 void fuse_init_common(struct inode *inode);
395
396 /**
397  * Initialize inode and file operations on a directory
398  */
399 void fuse_init_dir(struct inode *inode);
400
401 /**
402  * Initialize inode operations on a symlink
403  */
404 void fuse_init_symlink(struct inode *inode);
405
406 /**
407  * Change attributes of an inode
408  */
409 void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr);
410
411 /**
412  * Initialize the client device
413  */
414 int fuse_dev_init(void);
415
416 /**
417  * Cleanup the client device
418  */
419 void fuse_dev_cleanup(void);
420
421 /**
422  * Allocate a request
423  */
424 struct fuse_req *fuse_request_alloc(void);
425
426 /**
427  * Free a request
428  */
429 void fuse_request_free(struct fuse_req *req);
430
431 /**
432  * Reinitialize a request, the preallocated flag is left unmodified
433  */
434 void fuse_reset_request(struct fuse_req *req);
435
436 /**
437  * Reserve a preallocated request
438  */
439 struct fuse_req *fuse_get_req(struct fuse_conn *fc);
440
441 /**
442  * Decrement reference count of a request.  If count goes to zero free
443  * the request.
444  */
445 void fuse_put_request(struct fuse_conn *fc, struct fuse_req *req);
446
447 /**
448  * Send a request (synchronous)
449  */
450 void request_send(struct fuse_conn *fc, struct fuse_req *req);
451
452 /**
453  * Send a request with no reply
454  */
455 void request_send_noreply(struct fuse_conn *fc, struct fuse_req *req);
456
457 /**
458  * Send a request in the background
459  */
460 void request_send_background(struct fuse_conn *fc, struct fuse_req *req);
461
462 /**
463  * Release inodes and file associated with background request
464  */
465 void fuse_release_background(struct fuse_conn *fc, struct fuse_req *req);
466
467 /* Abort all requests */
468 void fuse_abort_conn(struct fuse_conn *fc);
469
470 /**
471  * Get the attributes of a file
472  */
473 int fuse_do_getattr(struct inode *inode);
474
475 /**
476  * Invalidate inode attributes
477  */
478 void fuse_invalidate_attr(struct inode *inode);