aboutsummaryrefslogtreecommitdiffstats
path: root/fs/fuse/fuse_i.h
diff options
context:
space:
mode:
Diffstat (limited to 'fs/fuse/fuse_i.h')
-rw-r--r--fs/fuse/fuse_i.h106
1 files changed, 69 insertions, 37 deletions
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
index 0ea5301f86be..46cf933aa3bf 100644
--- a/fs/fuse/fuse_i.h
+++ b/fs/fuse/fuse_i.h
@@ -21,6 +21,9 @@
21/** If more requests are outstanding, then the operation will block */ 21/** If more requests are outstanding, then the operation will block */
22#define FUSE_MAX_OUTSTANDING 10 22#define FUSE_MAX_OUTSTANDING 10
23 23
24/** It could be as large as PATH_MAX, but would that have any uses? */
25#define FUSE_NAME_MAX 1024
26
24/** If the FUSE_DEFAULT_PERMISSIONS flag is given, the filesystem 27/** If the FUSE_DEFAULT_PERMISSIONS flag is given, the filesystem
25 module will check permissions based on the file mode. Otherwise no 28 module will check permissions based on the file mode. Otherwise no
26 permission checking is done in the kernel */ 29 permission checking is done in the kernel */
@@ -91,6 +94,11 @@ struct fuse_out {
91 /** Header returned from userspace */ 94 /** Header returned from userspace */
92 struct fuse_out_header h; 95 struct fuse_out_header h;
93 96
97 /*
98 * The following bitfields are not changed during the request
99 * processing
100 */
101
94 /** Last argument is variable length (can be shorter than 102 /** Last argument is variable length (can be shorter than
95 arg->size) */ 103 arg->size) */
96 unsigned argvar:1; 104 unsigned argvar:1;
@@ -108,15 +116,23 @@ struct fuse_out {
108 struct fuse_arg args[3]; 116 struct fuse_arg args[3];
109}; 117};
110 118
111struct fuse_req; 119/** The request state */
120enum fuse_req_state {
121 FUSE_REQ_INIT = 0,
122 FUSE_REQ_PENDING,
123 FUSE_REQ_READING,
124 FUSE_REQ_SENT,
125 FUSE_REQ_FINISHED
126};
127
112struct fuse_conn; 128struct fuse_conn;
113 129
114/** 130/**
115 * A request to the client 131 * A request to the client
116 */ 132 */
117struct fuse_req { 133struct fuse_req {
118 /** This can be on either unused_list, pending or processing 134 /** This can be on either unused_list, pending processing or
119 lists in fuse_conn */ 135 io lists in fuse_conn */
120 struct list_head list; 136 struct list_head list;
121 137
122 /** Entry on the background list */ 138 /** Entry on the background list */
@@ -125,6 +141,12 @@ struct fuse_req {
125 /** refcount */ 141 /** refcount */
126 atomic_t count; 142 atomic_t count;
127 143
144 /*
145 * The following bitfields are either set once before the
146 * request is queued or setting/clearing them is protected by
147 * fuse_lock
148 */
149
128 /** True if the request has reply */ 150 /** True if the request has reply */
129 unsigned isreply:1; 151 unsigned isreply:1;
130 152
@@ -140,11 +162,8 @@ struct fuse_req {
140 /** Data is being copied to/from the request */ 162 /** Data is being copied to/from the request */
141 unsigned locked:1; 163 unsigned locked:1;
142 164
143 /** Request has been sent to userspace */ 165 /** State of the request */
144 unsigned sent:1; 166 enum fuse_req_state state;
145
146 /** The request is finished */
147 unsigned finished:1;
148 167
149 /** The request input */ 168 /** The request input */
150 struct fuse_in in; 169 struct fuse_in in;
@@ -159,7 +178,9 @@ struct fuse_req {
159 union { 178 union {
160 struct fuse_forget_in forget_in; 179 struct fuse_forget_in forget_in;
161 struct fuse_release_in release_in; 180 struct fuse_release_in release_in;
162 struct fuse_init_in_out init_in_out; 181 struct fuse_init_in init_in;
182 struct fuse_init_out init_out;
183 struct fuse_read_in read_in;
163 } misc; 184 } misc;
164 185
165 /** page vector */ 186 /** page vector */
@@ -179,6 +200,9 @@ struct fuse_req {
179 200
180 /** File used in the request (or NULL) */ 201 /** File used in the request (or NULL) */
181 struct file *file; 202 struct file *file;
203
204 /** Request completion callback */
205 void (*end)(struct fuse_conn *, struct fuse_req *);
182}; 206};
183 207
184/** 208/**
@@ -189,9 +213,6 @@ struct fuse_req {
189 * unmounted. 213 * unmounted.
190 */ 214 */
191struct fuse_conn { 215struct fuse_conn {
192 /** Reference count */
193 int count;
194
195 /** The user id for this mount */ 216 /** The user id for this mount */
196 uid_t user_id; 217 uid_t user_id;
197 218
@@ -216,6 +237,9 @@ struct fuse_conn {
216 /** The list of requests being processed */ 237 /** The list of requests being processed */
217 struct list_head processing; 238 struct list_head processing;
218 239
240 /** The list of requests under I/O */
241 struct list_head io;
242
219 /** Requests put in the background (RELEASE or any other 243 /** Requests put in the background (RELEASE or any other
220 interrupted request) */ 244 interrupted request) */
221 struct list_head background; 245 struct list_head background;
@@ -237,14 +261,22 @@ struct fuse_conn {
237 u64 reqctr; 261 u64 reqctr;
238 262
239 /** Mount is active */ 263 /** Mount is active */
240 unsigned mounted : 1; 264 unsigned mounted;
241 265
242 /** Connection established */ 266 /** Connection established, cleared on umount, connection
243 unsigned connected : 1; 267 abort and device release */
268 unsigned connected;
244 269
245 /** Connection failed (version mismatch) */ 270 /** Connection failed (version mismatch). Cannot race with
271 setting other bitfields since it is only set once in INIT
272 reply, before any other request, and never cleared */
246 unsigned conn_error : 1; 273 unsigned conn_error : 1;
247 274
275 /*
276 * The following bitfields are only for optimization purposes
277 * and hence races in setting them will not cause malfunction
278 */
279
248 /** Is fsync not implemented by fs? */ 280 /** Is fsync not implemented by fs? */
249 unsigned no_fsync : 1; 281 unsigned no_fsync : 1;
250 282
@@ -272,18 +304,22 @@ struct fuse_conn {
272 /** Is create not implemented by fs? */ 304 /** Is create not implemented by fs? */
273 unsigned no_create : 1; 305 unsigned no_create : 1;
274 306
307 /** The number of requests waiting for completion */
308 atomic_t num_waiting;
309
310 /** Negotiated minor version */
311 unsigned minor;
312
275 /** Backing dev info */ 313 /** Backing dev info */
276 struct backing_dev_info bdi; 314 struct backing_dev_info bdi;
277};
278 315
279static inline struct fuse_conn **get_fuse_conn_super_p(struct super_block *sb) 316 /** kobject */
280{ 317 struct kobject kobj;
281 return (struct fuse_conn **) &sb->s_fs_info; 318};
282}
283 319
284static inline struct fuse_conn *get_fuse_conn_super(struct super_block *sb) 320static inline struct fuse_conn *get_fuse_conn_super(struct super_block *sb)
285{ 321{
286 return *get_fuse_conn_super_p(sb); 322 return sb->s_fs_info;
287} 323}
288 324
289static inline struct fuse_conn *get_fuse_conn(struct inode *inode) 325static inline struct fuse_conn *get_fuse_conn(struct inode *inode)
@@ -291,6 +327,11 @@ static inline struct fuse_conn *get_fuse_conn(struct inode *inode)
291 return get_fuse_conn_super(inode->i_sb); 327 return get_fuse_conn_super(inode->i_sb);
292} 328}
293 329
330static inline struct fuse_conn *get_fuse_conn_kobj(struct kobject *obj)
331{
332 return container_of(obj, struct fuse_conn, kobj);
333}
334
294static inline struct fuse_inode *get_fuse_inode(struct inode *inode) 335static inline struct fuse_inode *get_fuse_inode(struct inode *inode)
295{ 336{
296 return container_of(inode, struct fuse_inode, inode); 337 return container_of(inode, struct fuse_inode, inode);
@@ -332,11 +373,10 @@ void fuse_send_forget(struct fuse_conn *fc, struct fuse_req *req,
332 unsigned long nodeid, u64 nlookup); 373 unsigned long nodeid, u64 nlookup);
333 374
334/** 375/**
335 * Send READ or READDIR request 376 * Initialize READ or READDIR request
336 */ 377 */
337size_t fuse_send_read_common(struct fuse_req *req, struct file *file, 378void fuse_read_fill(struct fuse_req *req, struct file *file,
338 struct inode *inode, loff_t pos, size_t count, 379 struct inode *inode, loff_t pos, size_t count, int opcode);
339 int isdir);
340 380
341/** 381/**
342 * Send OPEN or OPENDIR request 382 * Send OPEN or OPENDIR request
@@ -391,12 +431,6 @@ void fuse_init_symlink(struct inode *inode);
391void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr); 431void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr);
392 432
393/** 433/**
394 * Check if the connection can be released, and if yes, then free the
395 * connection structure
396 */
397void fuse_release_conn(struct fuse_conn *fc);
398
399/**
400 * Initialize the client device 434 * Initialize the client device
401 */ 435 */
402int fuse_dev_init(void); 436int fuse_dev_init(void);
@@ -452,6 +486,9 @@ void request_send_background(struct fuse_conn *fc, struct fuse_req *req);
452 */ 486 */
453void fuse_release_background(struct fuse_req *req); 487void fuse_release_background(struct fuse_req *req);
454 488
489/* Abort all requests */
490void fuse_abort_conn(struct fuse_conn *fc);
491
455/** 492/**
456 * Get the attributes of a file 493 * Get the attributes of a file
457 */ 494 */
@@ -461,8 +498,3 @@ int fuse_do_getattr(struct inode *inode);
461 * Invalidate inode attributes 498 * Invalidate inode attributes
462 */ 499 */
463void fuse_invalidate_attr(struct inode *inode); 500void fuse_invalidate_attr(struct inode *inode);
464
465/**
466 * Send the INIT message
467 */
468void fuse_send_init(struct fuse_conn *fc);