linux/fs/fuse/fuse_i.h
<<
>>
Prefs
   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/mount.h>
  12#include <linux/wait.h>
  13#include <linux/list.h>
  14#include <linux/spinlock.h>
  15#include <linux/mm.h>
  16#include <linux/backing-dev.h>
  17#include <linux/mutex.h>
  18
  19/** Max number of pages that can be used in a single read request */
  20#define FUSE_MAX_PAGES_PER_REQ 32
  21
  22/** Maximum number of outstanding background requests */
  23#define FUSE_MAX_BACKGROUND 12
  24
  25/** Congestion starts at 75% of maximum */
  26#define FUSE_CONGESTION_THRESHOLD (FUSE_MAX_BACKGROUND * 75 / 100)
  27
  28/** It could be as large as PATH_MAX, but would that have any uses? */
  29#define FUSE_NAME_MAX 1024
  30
  31/** Number of dentries for each connection in the control filesystem */
  32#define FUSE_CTL_NUM_DENTRIES 3
  33
  34/** If the FUSE_DEFAULT_PERMISSIONS flag is given, the filesystem
  35    module will check permissions based on the file mode.  Otherwise no
  36    permission checking is done in the kernel */
  37#define FUSE_DEFAULT_PERMISSIONS (1 << 0)
  38
  39/** If the FUSE_ALLOW_OTHER flag is given, then not only the user
  40    doing the mount will be allowed to access the filesystem */
  41#define FUSE_ALLOW_OTHER         (1 << 1)
  42
  43/** List of active connections */
  44extern struct list_head fuse_conn_list;
  45
  46/** Global mutex protecting fuse_conn_list and the control filesystem */
  47extern struct mutex fuse_mutex;
  48
  49/** FUSE inode */
  50struct fuse_inode {
  51        /** Inode data */
  52        struct inode inode;
  53
  54        /** Unique ID, which identifies the inode between userspace
  55         * and kernel */
  56        u64 nodeid;
  57
  58        /** Number of lookups on this inode */
  59        u64 nlookup;
  60
  61        /** The request used for sending the FORGET message */
  62        struct fuse_req *forget_req;
  63
  64        /** Time in jiffies until the file attributes are valid */
  65        u64 i_time;
  66
  67        /** The sticky bit in inode->i_mode may have been removed, so
  68            preserve the original mode */
  69        mode_t orig_i_mode;
  70
  71        /** Version of last attribute change */
  72        u64 attr_version;
  73
  74        /** Files usable in writepage.  Protected by fc->lock */
  75        struct list_head write_files;
  76};
  77
  78/** FUSE specific file data */
  79struct fuse_file {
  80        /** Request reserved for flush and release */
  81        struct fuse_req *reserved_req;
  82
  83        /** File handle used by userspace */
  84        u64 fh;
  85
  86        /** Refcount */
  87        atomic_t count;
  88
  89        /** Entry on inode's write_files list */
  90        struct list_head write_entry;
  91};
  92
  93/** One input argument of a request */
  94struct fuse_in_arg {
  95        unsigned size;
  96        const void *value;
  97};
  98
  99/** The request input */
 100struct fuse_in {
 101        /** The request header */
 102        struct fuse_in_header h;
 103
 104        /** True if the data for the last argument is in req->pages */
 105        unsigned argpages:1;
 106
 107        /** Number of arguments */
 108        unsigned numargs;
 109
 110        /** Array of arguments */
 111        struct fuse_in_arg args[3];
 112};
 113
 114/** One output argument of a request */
 115struct fuse_arg {
 116        unsigned size;
 117        void *value;
 118};
 119
 120/** The request output */
 121struct fuse_out {
 122        /** Header returned from userspace */
 123        struct fuse_out_header h;
 124
 125        /*
 126         * The following bitfields are not changed during the request
 127         * processing
 128         */
 129
 130        /** Last argument is variable length (can be shorter than
 131            arg->size) */
 132        unsigned argvar:1;
 133
 134        /** Last argument is a list of pages to copy data to */
 135        unsigned argpages:1;
 136
 137        /** Zero partially or not copied pages */
 138        unsigned page_zeroing:1;
 139
 140        /** Number or arguments */
 141        unsigned numargs;
 142
 143        /** Array of arguments */
 144        struct fuse_arg args[3];
 145};
 146
 147/** The request state */
 148enum fuse_req_state {
 149        FUSE_REQ_INIT = 0,
 150        FUSE_REQ_PENDING,
 151        FUSE_REQ_READING,
 152        FUSE_REQ_SENT,
 153        FUSE_REQ_WRITING,
 154        FUSE_REQ_FINISHED
 155};
 156
 157struct fuse_conn;
 158
 159/**
 160 * A request to the client
 161 */
 162struct fuse_req {
 163        /** This can be on either pending processing or io lists in
 164            fuse_conn */
 165        struct list_head list;
 166
 167        /** Entry on the interrupts list  */
 168        struct list_head intr_entry;
 169
 170        /** refcount */
 171        atomic_t count;
 172
 173        /** Unique ID for the interrupt request */
 174        u64 intr_unique;
 175
 176        /*
 177         * The following bitfields are either set once before the
 178         * request is queued or setting/clearing them is protected by
 179         * fuse_conn->lock
 180         */
 181
 182        /** True if the request has reply */
 183        unsigned isreply:1;
 184
 185        /** Force sending of the request even if interrupted */
 186        unsigned force:1;
 187
 188        /** The request was aborted */
 189        unsigned aborted:1;
 190
 191        /** Request is sent in the background */
 192        unsigned background:1;
 193
 194        /** The request has been interrupted */
 195        unsigned interrupted:1;
 196
 197        /** Data is being copied to/from the request */
 198        unsigned locked:1;
 199
 200        /** Request is counted as "waiting" */
 201        unsigned waiting:1;
 202
 203        /** State of the request */
 204        enum fuse_req_state state;
 205
 206        /** The request input */
 207        struct fuse_in in;
 208
 209        /** The request output */
 210        struct fuse_out out;
 211
 212        /** Used to wake up the task waiting for completion of request*/
 213        wait_queue_head_t waitq;
 214
 215        /** Data for asynchronous requests */
 216        union {
 217                struct fuse_forget_in forget_in;
 218                struct {
 219                        struct fuse_release_in in;
 220                        struct vfsmount *vfsmount;
 221                        struct dentry *dentry;
 222                } release;
 223                struct fuse_init_in init_in;
 224                struct fuse_init_out init_out;
 225                struct fuse_read_in read_in;
 226                struct {
 227                        struct fuse_write_in in;
 228                        struct fuse_write_out out;
 229                } write;
 230                struct fuse_lk_in lk_in;
 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        /** File used in the request (or NULL) */
 243        struct fuse_file *ff;
 244
 245        /** Request completion callback */
 246        void (*end)(struct fuse_conn *, struct fuse_req *);
 247
 248        /** Request is stolen from fuse_file->reserved_req */
 249        struct file *stolen_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 */
 259struct fuse_conn {
 260        /** Lock protecting accessess to  members of this structure */
 261        spinlock_t lock;
 262
 263        /** Mutex protecting against directory alias creation */
 264        struct mutex inst_mutex;
 265
 266        /** Refcount */
 267        atomic_t count;
 268
 269        /** The user id for this mount */
 270        uid_t user_id;
 271
 272        /** The group id for this mount */
 273        gid_t group_id;
 274
 275        /** The fuse mount flags for this mount */
 276        unsigned flags;
 277
 278        /** Maximum read size */
 279        unsigned max_read;
 280
 281        /** Maximum write size */
 282        unsigned max_write;
 283
 284        /** Readers of the connection are waiting on this */
 285        wait_queue_head_t waitq;
 286
 287        /** The list of pending requests */
 288        struct list_head pending;
 289
 290        /** The list of requests being processed */
 291        struct list_head processing;
 292
 293        /** The list of requests under I/O */
 294        struct list_head io;
 295
 296        /** Number of requests currently in the background */
 297        unsigned num_background;
 298
 299        /** Number of background requests currently queued for userspace */
 300        unsigned active_background;
 301
 302        /** The list of background requests set aside for later queuing */
 303        struct list_head bg_queue;
 304
 305        /** Pending interrupts */
 306        struct list_head interrupts;
 307
 308        /** Flag indicating if connection is blocked.  This will be
 309            the case before the INIT reply is received, and if there
 310            are too many outstading backgrounds requests */
 311        int blocked;
 312
 313        /** waitq for blocked connection */
 314        wait_queue_head_t blocked_waitq;
 315
 316        /** waitq for reserved requests */
 317        wait_queue_head_t reserved_req_waitq;
 318
 319        /** The next unique request id */
 320        u64 reqctr;
 321
 322        /** Connection established, cleared on umount, connection
 323            abort and device release */
 324        unsigned connected;
 325
 326        /** Connection failed (version mismatch).  Cannot race with
 327            setting other bitfields since it is only set once in INIT
 328            reply, before any other request, and never cleared */
 329        unsigned conn_error : 1;
 330
 331        /** Connection successful.  Only set in INIT */
 332        unsigned conn_init : 1;
 333
 334        /** Do readpages asynchronously?  Only set in INIT */
 335        unsigned async_read : 1;
 336
 337        /** Do not send separate SETATTR request before open(O_TRUNC)  */
 338        unsigned atomic_o_trunc : 1;
 339
 340        /*
 341         * The following bitfields are only for optimization purposes
 342         * and hence races in setting them will not cause malfunction
 343         */
 344
 345        /** Is fsync not implemented by fs? */
 346        unsigned no_fsync : 1;
 347
 348        /** Is fsyncdir not implemented by fs? */
 349        unsigned no_fsyncdir : 1;
 350
 351        /** Is flush not implemented by fs? */
 352        unsigned no_flush : 1;
 353
 354        /** Is setxattr not implemented by fs? */
 355        unsigned no_setxattr : 1;
 356
 357        /** Is getxattr not implemented by fs? */
 358        unsigned no_getxattr : 1;
 359
 360        /** Is listxattr not implemented by fs? */
 361        unsigned no_listxattr : 1;
 362
 363        /** Is removexattr not implemented by fs? */
 364        unsigned no_removexattr : 1;
 365
 366        /** Are file locking primitives not implemented by fs? */
 367        unsigned no_lock : 1;
 368
 369        /** Is access not implemented by fs? */
 370        unsigned no_access : 1;
 371
 372        /** Is create not implemented by fs? */
 373        unsigned no_create : 1;
 374
 375        /** Is interrupt not implemented by fs? */
 376        unsigned no_interrupt : 1;
 377
 378        /** Is bmap not implemented by fs? */
 379        unsigned no_bmap : 1;
 380
 381        /** The number of requests waiting for completion */
 382        atomic_t num_waiting;
 383
 384        /** Negotiated minor version */
 385        unsigned minor;
 386
 387        /** Backing dev info */
 388        struct backing_dev_info bdi;
 389
 390        /** Entry on the fuse_conn_list */
 391        struct list_head entry;
 392
 393        /** Unique ID */
 394        u64 id;
 395
 396        /** Dentries in the control filesystem */
 397        struct dentry *ctl_dentry[FUSE_CTL_NUM_DENTRIES];
 398
 399        /** number of dentries used in the above array */
 400        int ctl_ndents;
 401
 402        /** O_ASYNC requests */
 403        struct fasync_struct *fasync;
 404
 405        /** Key for lock owner ID scrambling */
 406        u32 scramble_key[4];
 407
 408        /** Reserved request for the DESTROY message */
 409        struct fuse_req *destroy_req;
 410
 411        /** Version counter for attribute changes */
 412        u64 attr_version;
 413};
 414
 415static inline struct fuse_conn *get_fuse_conn_super(struct super_block *sb)
 416{
 417        return sb->s_fs_info;
 418}
 419
 420static inline struct fuse_conn *get_fuse_conn(struct inode *inode)
 421{
 422        return get_fuse_conn_super(inode->i_sb);
 423}
 424
 425static inline struct fuse_inode *get_fuse_inode(struct inode *inode)
 426{
 427        return container_of(inode, struct fuse_inode, inode);
 428}
 429
 430static inline u64 get_node_id(struct inode *inode)
 431{
 432        return get_fuse_inode(inode)->nodeid;
 433}
 434
 435/** Device operations */
 436extern const struct file_operations fuse_dev_operations;
 437
 438/**
 439 * Get a filled in inode
 440 */
 441struct inode *fuse_iget(struct super_block *sb, unsigned long nodeid,
 442                        int generation, struct fuse_attr *attr,
 443                        u64 attr_valid, u64 attr_version);
 444
 445/**
 446 * Send FORGET command
 447 */
 448void fuse_send_forget(struct fuse_conn *fc, struct fuse_req *req,
 449                      unsigned long nodeid, u64 nlookup);
 450
 451/**
 452 * Initialize READ or READDIR request
 453 */
 454void fuse_read_fill(struct fuse_req *req, struct file *file,
 455                    struct inode *inode, loff_t pos, size_t count, int opcode);
 456
 457/**
 458 * Send OPEN or OPENDIR request
 459 */
 460int fuse_open_common(struct inode *inode, struct file *file, int isdir);
 461
 462struct fuse_file *fuse_file_alloc(void);
 463void fuse_file_free(struct fuse_file *ff);
 464void fuse_finish_open(struct inode *inode, struct file *file,
 465                      struct fuse_file *ff, struct fuse_open_out *outarg);
 466
 467/** Fill in ff->reserved_req with a RELEASE request */
 468void fuse_release_fill(struct fuse_file *ff, u64 nodeid, int flags, int opcode);
 469
 470/**
 471 * Send RELEASE or RELEASEDIR request
 472 */
 473int fuse_release_common(struct inode *inode, struct file *file, int isdir);
 474
 475/**
 476 * Send FSYNC or FSYNCDIR request
 477 */
 478int fuse_fsync_common(struct file *file, struct dentry *de, int datasync,
 479                      int isdir);
 480
 481/**
 482 * Initialize file operations on a regular file
 483 */
 484void fuse_init_file_inode(struct inode *inode);
 485
 486/**
 487 * Initialize inode operations on regular files and special files
 488 */
 489void fuse_init_common(struct inode *inode);
 490
 491/**
 492 * Initialize inode and file operations on a directory
 493 */
 494void fuse_init_dir(struct inode *inode);
 495
 496/**
 497 * Initialize inode operations on a symlink
 498 */
 499void fuse_init_symlink(struct inode *inode);
 500
 501/**
 502 * Change attributes of an inode
 503 */
 504void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr,
 505                            u64 attr_valid, u64 attr_version);
 506
 507/**
 508 * Initialize the client device
 509 */
 510int fuse_dev_init(void);
 511
 512/**
 513 * Cleanup the client device
 514 */
 515void fuse_dev_cleanup(void);
 516
 517int fuse_ctl_init(void);
 518void fuse_ctl_cleanup(void);
 519
 520/**
 521 * Allocate a request
 522 */
 523struct fuse_req *fuse_request_alloc(void);
 524
 525/**
 526 * Free a request
 527 */
 528void fuse_request_free(struct fuse_req *req);
 529
 530/**
 531 * Get a request, may fail with -ENOMEM
 532 */
 533struct fuse_req *fuse_get_req(struct fuse_conn *fc);
 534
 535/**
 536 * Gets a requests for a file operation, always succeeds
 537 */
 538struct fuse_req *fuse_get_req_nofail(struct fuse_conn *fc, struct file *file);
 539
 540/**
 541 * Decrement reference count of a request.  If count goes to zero free
 542 * the request.
 543 */
 544void fuse_put_request(struct fuse_conn *fc, struct fuse_req *req);
 545
 546/**
 547 * Send a request (synchronous)
 548 */
 549void request_send(struct fuse_conn *fc, struct fuse_req *req);
 550
 551/**
 552 * Send a request with no reply
 553 */
 554void request_send_noreply(struct fuse_conn *fc, struct fuse_req *req);
 555
 556/**
 557 * Send a request in the background
 558 */
 559void request_send_background(struct fuse_conn *fc, struct fuse_req *req);
 560
 561/* Abort all requests */
 562void fuse_abort_conn(struct fuse_conn *fc);
 563
 564/**
 565 * Invalidate inode attributes
 566 */
 567void fuse_invalidate_attr(struct inode *inode);
 568
 569/**
 570 * Acquire reference to fuse_conn
 571 */
 572struct fuse_conn *fuse_conn_get(struct fuse_conn *fc);
 573
 574/**
 575 * Release reference to fuse_conn
 576 */
 577void fuse_conn_put(struct fuse_conn *fc);
 578
 579/**
 580 * Add connection to control filesystem
 581 */
 582int fuse_ctl_add_conn(struct fuse_conn *fc);
 583
 584/**
 585 * Remove connection from control filesystem
 586 */
 587void fuse_ctl_remove_conn(struct fuse_conn *fc);
 588
 589/**
 590 * Is file type valid?
 591 */
 592int fuse_valid_type(int m);
 593
 594/**
 595 * Is task allowed to perform filesystem operation?
 596 */
 597int fuse_allow_task(struct fuse_conn *fc, struct task_struct *task);
 598
 599u64 fuse_lock_owner_id(struct fuse_conn *fc, fl_owner_t id);
 600
 601int fuse_update_attributes(struct inode *inode, struct kstat *stat,
 602                           struct file *file, bool *refreshed);
 603
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.