[PATCH] FUSE - device functions
[deliverable/linux.git] / fs / fuse / fuse_i.h
CommitLineData
d8a5ba45
MS
1/*
2 FUSE: Filesystem in Userspace
3 Copyright (C) 2001-2005 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
334f485d
MS
18/** Max number of pages that can be used in a single read request */
19#define FUSE_MAX_PAGES_PER_REQ 32
20
21/** If more requests are outstanding, then the operation will block */
22#define FUSE_MAX_OUTSTANDING 10
23
d8a5ba45
MS
24/** FUSE inode */
25struct fuse_inode {
26 /** Inode data */
27 struct inode inode;
28
29 /** Unique ID, which identifies the inode between userspace
30 * and kernel */
31 u64 nodeid;
32
33 /** Time in jiffies until the file attributes are valid */
34 unsigned long i_time;
35};
36
334f485d
MS
37/** One input argument of a request */
38struct fuse_in_arg {
39 unsigned size;
40 const void *value;
41};
42
43/** The request input */
44struct fuse_in {
45 /** The request header */
46 struct fuse_in_header h;
47
48 /** True if the data for the last argument is in req->pages */
49 unsigned argpages:1;
50
51 /** Number of arguments */
52 unsigned numargs;
53
54 /** Array of arguments */
55 struct fuse_in_arg args[3];
56};
57
58/** One output argument of a request */
59struct fuse_arg {
60 unsigned size;
61 void *value;
62};
63
64/** The request output */
65struct fuse_out {
66 /** Header returned from userspace */
67 struct fuse_out_header h;
68
69 /** Last argument is variable length (can be shorter than
70 arg->size) */
71 unsigned argvar:1;
72
73 /** Last argument is a list of pages to copy data to */
74 unsigned argpages:1;
75
76 /** Zero partially or not copied pages */
77 unsigned page_zeroing:1;
78
79 /** Number or arguments */
80 unsigned numargs;
81
82 /** Array of arguments */
83 struct fuse_arg args[3];
84};
85
86struct fuse_req;
87struct fuse_conn;
88
89/**
90 * A request to the client
91 */
92struct fuse_req {
93 /** This can be on either unused_list, pending or processing
94 lists in fuse_conn */
95 struct list_head list;
96
97 /** refcount */
98 atomic_t count;
99
100 /** True if the request has reply */
101 unsigned isreply:1;
102
103 /** The request is preallocated */
104 unsigned preallocated:1;
105
106 /** The request was interrupted */
107 unsigned interrupted:1;
108
109 /** Request is sent in the background */
110 unsigned background:1;
111
112 /** Data is being copied to/from the request */
113 unsigned locked:1;
114
115 /** Request has been sent to userspace */
116 unsigned sent:1;
117
118 /** The request is finished */
119 unsigned finished:1;
120
121 /** The request input */
122 struct fuse_in in;
123
124 /** The request output */
125 struct fuse_out out;
126
127 /** Used to wake up the task waiting for completion of request*/
128 wait_queue_head_t waitq;
129
130 /** Data for asynchronous requests */
131 union {
132 struct fuse_init_in_out init_in_out;
133 } misc;
134
135 /** page vector */
136 struct page *pages[FUSE_MAX_PAGES_PER_REQ];
137
138 /** number of pages in vector */
139 unsigned num_pages;
140
141 /** offset of data on first page */
142 unsigned page_offset;
143
144 /** Inode used in the request */
145 struct inode *inode;
146
147 /** Second inode used in the request (or NULL) */
148 struct inode *inode2;
149
150 /** File used in the request (or NULL) */
151 struct file *file;
152};
153
d8a5ba45
MS
154/**
155 * A Fuse connection.
156 *
157 * This structure is created, when the filesystem is mounted, and is
158 * destroyed, when the client device is closed and the filesystem is
159 * unmounted.
160 */
161struct fuse_conn {
162 /** The superblock of the mounted filesystem */
163 struct super_block *sb;
164
334f485d
MS
165 /** The opened client device */
166 struct file *file;
167
d8a5ba45
MS
168 /** The user id for this mount */
169 uid_t user_id;
170
334f485d
MS
171 /** Readers of the connection are waiting on this */
172 wait_queue_head_t waitq;
173
174 /** The list of pending requests */
175 struct list_head pending;
176
177 /** The list of requests being processed */
178 struct list_head processing;
179
180 /** Controls the maximum number of outstanding requests */
181 struct semaphore outstanding_sem;
182
183 /** This counts the number of outstanding requests if
184 outstanding_sem would go negative */
185 unsigned outstanding_debt;
186
187 /** The list of unused requests */
188 struct list_head unused_list;
189
190 /** The next unique request id */
191 u64 reqctr;
192
193 /** Connection failed (version mismatch) */
194 unsigned conn_error : 1;
195
d8a5ba45
MS
196 /** Backing dev info */
197 struct backing_dev_info bdi;
198};
199
200static inline struct fuse_conn **get_fuse_conn_super_p(struct super_block *sb)
201{
202 return (struct fuse_conn **) &sb->s_fs_info;
203}
204
205static inline struct fuse_conn *get_fuse_conn_super(struct super_block *sb)
206{
207 return *get_fuse_conn_super_p(sb);
208}
209
210static inline struct fuse_conn *get_fuse_conn(struct inode *inode)
211{
212 return get_fuse_conn_super(inode->i_sb);
213}
214
215static inline struct fuse_inode *get_fuse_inode(struct inode *inode)
216{
217 return container_of(inode, struct fuse_inode, inode);
218}
219
220static inline u64 get_node_id(struct inode *inode)
221{
222 return get_fuse_inode(inode)->nodeid;
223}
224
334f485d
MS
225/** Device operations */
226extern struct file_operations fuse_dev_operations;
227
d8a5ba45
MS
228/**
229 * This is the single global spinlock which protects FUSE's structures
230 *
231 * The following data is protected by this lock:
232 *
334f485d 233 * - the private_data field of the device file
d8a5ba45 234 * - the s_fs_info field of the super block
334f485d
MS
235 * - unused_list, pending, processing lists in fuse_conn
236 * - the unique request ID counter reqctr in fuse_conn
d8a5ba45 237 * - the sb (super_block) field in fuse_conn
334f485d 238 * - the file (device file) field in fuse_conn
d8a5ba45
MS
239 */
240extern spinlock_t fuse_lock;
241
242/**
243 * Check if the connection can be released, and if yes, then free the
244 * connection structure
245 */
246void fuse_release_conn(struct fuse_conn *fc);
247
334f485d
MS
248/**
249 * Initialize the client device
250 */
251int fuse_dev_init(void);
252
253/**
254 * Cleanup the client device
255 */
256void fuse_dev_cleanup(void);
257
258/**
259 * Allocate a request
260 */
261struct fuse_req *fuse_request_alloc(void);
262
263/**
264 * Free a request
265 */
266void fuse_request_free(struct fuse_req *req);
267
268/**
269 * Reinitialize a request, the preallocated flag is left unmodified
270 */
271void fuse_reset_request(struct fuse_req *req);
272
273/**
274 * Reserve a preallocated request
275 */
276struct fuse_req *fuse_get_request(struct fuse_conn *fc);
277
278/**
279 * Reserve a preallocated request, only interruptible by SIGKILL
280 */
281struct fuse_req *fuse_get_request_nonint(struct fuse_conn *fc);
282
283/**
284 * Decrement reference count of a request. If count goes to zero put
285 * on unused list (preallocated) or free reqest (not preallocated).
286 */
287void fuse_put_request(struct fuse_conn *fc, struct fuse_req *req);
288
289/**
290 * Send a request (synchronous, interruptible)
291 */
292void request_send(struct fuse_conn *fc, struct fuse_req *req);
293
294/**
295 * Send a request (synchronous, non-interruptible except by SIGKILL)
296 */
297void request_send_nonint(struct fuse_conn *fc, struct fuse_req *req);
298
299/**
300 * Send a request with no reply
301 */
302void request_send_noreply(struct fuse_conn *fc, struct fuse_req *req);
303
304/**
305 * Send a request in the background
306 */
307void request_send_background(struct fuse_conn *fc, struct fuse_req *req);
308
309/**
310 * Send the INIT message
311 */
312void fuse_send_init(struct fuse_conn *fc);
This page took 0.035534 seconds and 5 git commands to generate.