~james-w/+junk/fuse-debian-upstream

« back to all changes in this revision

Viewing changes to kernel/fuse_i.h

  • Committer: James Westby
  • Date: 2008-05-16 12:57:40 UTC
  • Revision ID: jw+debian@jameswestby.net-20080516125740-fn2iqsxtfd3olmib
Tags: upstream-debian-2.2.1
Import upstream from fuse_2.2.1.orig.tar.gz

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
#ifdef FUSE_MAINLINE
 
10
#include <linux/fuse.h>
 
11
#else
 
12
#include "fuse_kernel.h"
 
13
#include <linux/version.h>
 
14
 
 
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
 
17
#endif
 
18
 
 
19
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
 
20
#  define KERNEL_2_6
 
21
#  if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,6)
 
22
#    define KERNEL_2_6_6_PLUS
 
23
#  endif
 
24
#  if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,8)
 
25
#    define KERNEL_2_6_8_PLUS
 
26
#  endif
 
27
#  if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10)
 
28
#    define KERNEL_2_6_10_PLUS
 
29
#  endif
 
30
#endif
 
31
 
 
32
#include "config.h"
 
33
#ifndef KERNEL_2_6
 
34
#  include <linux/config.h>
 
35
#  ifdef CONFIG_MODVERSIONS
 
36
#     define MODVERSIONS
 
37
#     include <linux/modversions.h>
 
38
#  endif
 
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)
 
42
#  endif
 
43
#  define new_decode_dev(x) (x)
 
44
#  define new_encode_dev(x) (x)
 
45
#endif /* KERNEL_2_6 */
 
46
#endif /* FUSE_MAINLINE */
 
47
#include <linux/fs.h>
 
48
#include <linux/wait.h>
 
49
#include <linux/list.h>
 
50
#include <linux/spinlock.h>
 
51
#ifdef KERNEL_2_6
 
52
#include <linux/mm.h>
 
53
#include <linux/backing-dev.h>
 
54
#endif
 
55
#include <asm/semaphore.h>
 
56
 
 
57
#ifndef BUG_ON
 
58
#define BUG_ON(x)
 
59
#endif
 
60
#ifndef container_of
 
61
#define container_of(ptr, type, member) ({                      \
 
62
        const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
 
63
        (type *)( (char *)__mptr - offsetof(type,member) );})
 
64
#endif
 
65
#ifndef __user
 
66
#define __user
 
67
#endif
 
68
#ifndef KERNEL_2_6
 
69
#include <linux/pagemap.h>
 
70
static inline void set_page_dirty_lock(struct page *page)
 
71
{
 
72
        lock_page(page);
 
73
        set_page_dirty(page);
 
74
        unlock_page(page);
 
75
}
 
76
#endif
 
77
/** Max number of pages that can be used in a single read request */
 
78
#define FUSE_MAX_PAGES_PER_REQ 32
 
79
 
 
80
/** If more requests are outstanding, then the operation will block */
 
81
#define FUSE_MAX_OUTSTANDING 10
 
82
 
 
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)
 
87
 
 
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)
 
91
 
 
92
/** If the FUSE_KERNEL_CACHE flag is given, then cached data will not
 
93
    be flushed on open */
 
94
#define FUSE_KERNEL_CACHE        (1 << 2)
 
95
 
 
96
#ifndef KERNEL_2_6
 
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)
 
100
#endif
 
101
/** Bypass the page cache for read and write operations  */
 
102
#define FUSE_DIRECT_IO           (1 << 3)
 
103
 
 
104
/** Allow root and setuid-root programs to access fuse-mounted
 
105
    filesystems */
 
106
#define FUSE_ALLOW_ROOT          (1 << 4)
 
107
 
 
108
/** FUSE inode */
 
109
struct fuse_inode {
 
110
        /** Inode data */
 
111
        struct inode inode;
 
112
 
 
113
        /** Unique ID, which identifies the inode between userspace
 
114
         * and kernel */
 
115
        u64 nodeid;
 
116
 
 
117
        /** The request used for sending the FORGET message */
 
118
        struct fuse_req *forget_req;
 
119
 
 
120
        /** Time in jiffies until the file attributes are valid */
 
121
        unsigned long i_time;
 
122
};
 
123
 
 
124
/** FUSE specific file data */
 
125
struct fuse_file {
 
126
        /** Request reserved for flush and release */
 
127
        struct fuse_req *release_req;
 
128
 
 
129
        /** File handle used by userspace */
 
130
        u64 fh;
 
131
};
 
132
 
 
133
/** One input argument of a request */
 
134
struct fuse_in_arg {
 
135
        unsigned size;
 
136
        const void *value;
 
137
};
 
138
 
 
139
/** The request input */
 
140
struct fuse_in {
 
141
        /** The request header */
 
142
        struct fuse_in_header h;
 
143
 
 
144
        /** True if the data for the last argument is in req->pages */
 
145
        unsigned argpages:1;
 
146
 
 
147
        /** Number of arguments */
 
148
        unsigned numargs;
 
149
 
 
150
        /** Array of arguments */
 
151
        struct fuse_in_arg args[3];
 
152
};
 
153
 
 
154
/** One output argument of a request */
 
155
struct fuse_arg {
 
156
        unsigned size;
 
157
        void *value;
 
158
};
 
159
 
 
160
/** The request output */
 
161
struct fuse_out {
 
162
        /** Header returned from userspace */
 
163
        struct fuse_out_header h;
 
164
 
 
165
        /** Last argument is variable length (can be shorter than
 
166
            arg->size) */
 
167
        unsigned argvar:1;
 
168
 
 
169
        /** Last argument is a list of pages to copy data to */
 
170
        unsigned argpages:1;
 
171
 
 
172
        /** Zero partially or not copied pages */
 
173
        unsigned page_zeroing:1;
 
174
 
 
175
        /** Number or arguments */
 
176
        unsigned numargs;
 
177
 
 
178
        /** Array of arguments */
 
179
        struct fuse_arg args[3];
 
180
};
 
181
 
 
182
struct fuse_req;
 
183
struct fuse_conn;
 
184
 
 
185
/**
 
186
 * A request to the client
 
187
 */
 
188
struct fuse_req {
 
189
        /** This can be on either unused_list, pending or processing
 
190
            lists in fuse_conn */
 
191
        struct list_head list;
 
192
 
 
193
        /** refcount */
 
194
        atomic_t count;
 
195
 
 
196
        /** True if the request has reply */
 
197
        unsigned isreply:1;
 
198
 
 
199
        /** The request is preallocated */
 
200
        unsigned preallocated:1;
 
201
 
 
202
        /** The request was interrupted */
 
203
        unsigned interrupted:1;
 
204
 
 
205
        /** Request is sent in the background */
 
206
        unsigned background:1;
 
207
 
 
208
        /** Data is being copied to/from the request */
 
209
        unsigned locked:1;
 
210
 
 
211
        /** Request has been sent to userspace */
 
212
        unsigned sent:1;
 
213
 
 
214
        /** The request is finished */
 
215
        unsigned finished:1;
 
216
 
 
217
        /** The request input */
 
218
        struct fuse_in in;
 
219
 
 
220
        /** The request output */
 
221
        struct fuse_out out;
 
222
 
 
223
        /** Used to wake up the task waiting for completion of request*/
 
224
        wait_queue_head_t waitq;
 
225
 
 
226
        /** Data for asynchronous requests */
 
227
        union {
 
228
                struct fuse_forget_in forget_in;
 
229
                struct fuse_release_in release_in;
 
230
                struct fuse_init_in_out init_in_out;
 
231
        } misc;
 
232
 
 
233
        /** page vector */
 
234
        struct page *pages[FUSE_MAX_PAGES_PER_REQ];
 
235
 
 
236
        /** number of pages in vector */
 
237
        unsigned num_pages;
 
238
 
 
239
        /** offset of data on first page */
 
240
        unsigned page_offset;
 
241
 
 
242
        /** Inode used in the request */
 
243
        struct inode *inode;
 
244
 
 
245
        /** Second inode used in the request (or NULL) */
 
246
        struct inode *inode2;
 
247
 
 
248
        /** File used in the request (or NULL) */
 
249
        struct file *file;
 
250
};
 
251
 
 
252
/**
 
253
 * A Fuse connection.
 
254
 *
 
255
 * This structure is created, when the filesystem is mounted, and is
 
256
 * destroyed, when the client device is closed and the filesystem is
 
257
 * unmounted.
 
258
 */
 
259
struct fuse_conn {
 
260
        /** The superblock of the mounted filesystem */
 
261
        struct super_block *sb;
 
262
 
 
263
        /** The opened client device */
 
264
        struct file *file;
 
265
 
 
266
        /** The user id for this mount */
 
267
        uid_t user_id;
 
268
 
 
269
        /** The fuse mount flags for this mount */
 
270
        unsigned flags;
 
271
 
 
272
        /** Maximum read size */
 
273
        unsigned max_read;
 
274
 
 
275
        /** Maximum write size */
 
276
        unsigned max_write;
 
277
 
 
278
        /** Readers of the connection are waiting on this */
 
279
        wait_queue_head_t waitq;
 
280
 
 
281
        /** The list of pending requests */
 
282
        struct list_head pending;
 
283
 
 
284
        /** The list of requests being processed */
 
285
        struct list_head processing;
 
286
 
 
287
        /** Controls the maximum number of outstanding requests */
 
288
        struct semaphore outstanding_sem;
 
289
 
 
290
        /** This counts the number of outstanding requests if
 
291
            outstanding_sem would go negative */
 
292
        unsigned outstanding_debt;
 
293
 
 
294
        /** The list of unused requests */
 
295
        struct list_head unused_list;
 
296
 
 
297
        /** The next unique request id */
 
298
        int reqctr;
 
299
 
 
300
        /** Is fsync not implemented by fs? */
 
301
        unsigned no_fsync : 1;
 
302
 
 
303
        /** Is flush not implemented by fs? */
 
304
        unsigned no_flush : 1;
 
305
 
 
306
        /** Is setxattr not implemented by fs? */
 
307
        unsigned no_setxattr : 1;
 
308
 
 
309
        /** Is getxattr not implemented by fs? */
 
310
        unsigned no_getxattr : 1;
 
311
 
 
312
        /** Is listxattr not implemented by fs? */
 
313
        unsigned no_listxattr : 1;
 
314
 
 
315
        /** Is removexattr not implemented by fs? */
 
316
        unsigned no_removexattr : 1;
 
317
 
 
318
#ifdef KERNEL_2_6
 
319
        /** Backing dev info */
 
320
        struct backing_dev_info bdi;
 
321
#endif
 
322
};
 
323
 
 
324
static inline struct fuse_conn **get_fuse_conn_super_p(struct super_block *sb)
 
325
{
 
326
#ifdef KERNEL_2_6
 
327
        return (struct fuse_conn **) &sb->s_fs_info;
 
328
#else
 
329
        return (struct fuse_conn **) &sb->u.generic_sbp;
 
330
#endif
 
331
}
 
332
 
 
333
static inline struct fuse_conn *get_fuse_conn_super(struct super_block *sb)
 
334
{
 
335
        return *get_fuse_conn_super_p(sb);
 
336
}
 
337
 
 
338
static inline struct fuse_conn *get_fuse_conn(struct inode *inode)
 
339
{
 
340
        return get_fuse_conn_super(inode->i_sb);
 
341
}
 
342
 
 
343
static inline struct fuse_inode *get_fuse_inode(struct inode *inode)
 
344
{
 
345
        return container_of(inode, struct fuse_inode, inode);
 
346
}
 
347
 
 
348
static inline u64 get_node_id(struct inode *inode)
 
349
{
 
350
        return get_fuse_inode(inode)->nodeid;
 
351
}
 
352
 
 
353
/** Device operations */
 
354
extern struct file_operations fuse_dev_operations;
 
355
 
 
356
/**
 
357
 * This is the single global spinlock which protects FUSE's structures
 
358
 *
 
359
 * The following data is protected by this lock:
 
360
 *
 
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
 
367
 */
 
368
extern spinlock_t fuse_lock;
 
369
 
 
370
/**
 
371
 * Get a filled in inode
 
372
 */
 
373
struct inode *fuse_iget(struct super_block *sb, unsigned long nodeid,
 
374
                        int generation, struct fuse_attr *attr, int version);
 
375
 
 
376
/**
 
377
 * Send FORGET command
 
378
 */
 
379
void fuse_send_forget(struct fuse_conn *fc, struct fuse_req *req,
 
380
                      unsigned long nodeid, int version);
 
381
 
 
382
/**
 
383
 * Send READ or READDIR request
 
384
 */
 
385
size_t fuse_send_read_common(struct fuse_req *req, struct file *file,
 
386
                             struct inode *inode, loff_t pos, size_t count,
 
387
                             int isdir);
 
388
 
 
389
/**
 
390
 * Send OPEN or OPENDIR request
 
391
 */
 
392
int fuse_open_common(struct inode *inode, struct file *file, int isdir);
 
393
 
 
394
/**
 
395
 * Send RELEASE or RELEASEDIR request
 
396
 */
 
397
int fuse_release_common(struct inode *inode, struct file *file, int isdir);
 
398
 
 
399
/**
 
400
 * Initialise file operations on a regular file
 
401
 */
 
402
void fuse_init_file_inode(struct inode *inode);
 
403
 
 
404
/**
 
405
 * Initialise inode operations on regular files and special files
 
406
 */
 
407
void fuse_init_common(struct inode *inode);
 
408
 
 
409
/**
 
410
 * Initialise inode and file operations on a directory
 
411
 */
 
412
void fuse_init_dir(struct inode *inode);
 
413
 
 
414
/**
 
415
 * Initialise inode operations on a symlink
 
416
 */
 
417
void fuse_init_symlink(struct inode *inode);
 
418
 
 
419
/**
 
420
 * Change attributes of an inode
 
421
 */
 
422
void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr);
 
423
 
 
424
/**
 
425
 * Check if the connection can be released, and if yes, then free the
 
426
 * connection structure
 
427
 */
 
428
void fuse_release_conn(struct fuse_conn *fc);
 
429
 
 
430
/**
 
431
 * Initialize the client device
 
432
 */
 
433
int fuse_dev_init(void);
 
434
 
 
435
/**
 
436
 * Cleanup the client device
 
437
 */
 
438
void fuse_dev_cleanup(void);
 
439
 
 
440
/**
 
441
 * Allocate a request
 
442
 */
 
443
struct fuse_req *fuse_request_alloc(void);
 
444
 
 
445
/**
 
446
 * Free a request
 
447
 */
 
448
void fuse_request_free(struct fuse_req *req);
 
449
 
 
450
/**
 
451
 * Reinitialize a request, the preallocated flag is left unmodified
 
452
 */
 
453
void fuse_reset_request(struct fuse_req *req);
 
454
 
 
455
/**
 
456
 * Reserve a preallocated request
 
457
 */
 
458
struct fuse_req *fuse_get_request(struct fuse_conn *fc);
 
459
 
 
460
/**
 
461
 * Reserve a preallocated request, only interruptible by SIGKILL
 
462
 */
 
463
struct fuse_req *fuse_get_request_nonint(struct fuse_conn *fc);
 
464
 
 
465
/**
 
466
 * Decrement reference count of a request.  If count goes to zero put
 
467
 * on unused list (preallocated) or free reqest (not preallocated).
 
468
 */
 
469
void fuse_put_request(struct fuse_conn *fc, struct fuse_req *req);
 
470
 
 
471
/**
 
472
 * Send a request (synchronous, interruptible)
 
473
 */
 
474
void request_send(struct fuse_conn *fc, struct fuse_req *req);
 
475
 
 
476
/**
 
477
 * Send a request (synchronous, non-interruptible except by SIGKILL)
 
478
 */
 
479
void request_send_nonint(struct fuse_conn *fc, struct fuse_req *req);
 
480
 
 
481
/**
 
482
 * Send a request with no reply
 
483
 */
 
484
void request_send_noreply(struct fuse_conn *fc, struct fuse_req *req);
 
485
 
 
486
/**
 
487
 * Send a request in the background
 
488
 */
 
489
void request_send_background(struct fuse_conn *fc, struct fuse_req *req);
 
490
 
 
491
/**
 
492
 * Get the attributes of a file
 
493
 */
 
494
int fuse_do_getattr(struct inode *inode);
 
495
 
 
496
/**
 
497
 * Invalidate inode attributes
 
498
 */
 
499
void fuse_invalidate_attr(struct inode *inode);
 
500
 
 
501
/**
 
502
 * Send the INIT message
 
503
 */
 
504
void fuse_send_init(struct fuse_conn *fc);