ARM64: dts: rk3368-tb-sheep: add grf offset property for dwc-control-usb
[firefly-linux-kernel-4.4.55.git] / fs / fuse / fuse_i.h
index fde7249a3a9608c8c6e49be4316a1d155b7cdfba..405113101db8d868fcb40c34199978be576d0961 100644 (file)
@@ -115,6 +115,10 @@ struct fuse_inode {
 enum {
        /** Advise readdirplus  */
        FUSE_I_ADVISE_RDPLUS,
+       /** Initialized with readdirplus */
+       FUSE_I_INIT_RDPLUS,
+       /** An operation changing file size is in progress  */
+       FUSE_I_SIZE_UNSTABLE,
 };
 
 struct fuse_conn;
@@ -209,7 +213,7 @@ struct fuse_out {
        unsigned numargs;
 
        /** Array of arguments */
-       struct fuse_arg args[3];
+       struct fuse_arg args[2];
 };
 
 /** FUSE page descriptor */
@@ -218,16 +222,25 @@ struct fuse_page_desc {
        unsigned int offset;
 };
 
-/** The request state */
-enum fuse_req_state {
-       FUSE_REQ_INIT = 0,
-       FUSE_REQ_PENDING,
-       FUSE_REQ_READING,
-       FUSE_REQ_SENT,
-       FUSE_REQ_WRITING,
-       FUSE_REQ_FINISHED
+struct fuse_args {
+       struct {
+               struct {
+                       uint32_t opcode;
+                       uint64_t nodeid;
+               } h;
+               unsigned numargs;
+               struct fuse_in_arg args[3];
+
+       } in;
+       struct {
+               unsigned argvar:1;
+               unsigned numargs;
+               struct fuse_arg args[2];
+       } out;
 };
 
+#define FUSE_ARGS(args) struct fuse_args args = {}
+
 /** The request IO state (for asynchronous processing) */
 struct fuse_io_priv {
        int async;
@@ -240,10 +253,44 @@ struct fuse_io_priv {
        int err;
        struct kiocb *iocb;
        struct file *file;
+       struct completion *done;
+};
+
+/**
+ * Request flags
+ *
+ * FR_ISREPLY:         set if the request has reply
+ * FR_FORCE:           force sending of the request even if interrupted
+ * FR_BACKGROUND:      request is sent in the background
+ * FR_WAITING:         request is counted as "waiting"
+ * FR_ABORTED:         the request was aborted
+ * FR_INTERRUPTED:     the request has been interrupted
+ * FR_LOCKED:          data is being copied to/from the request
+ * FR_PENDING:         request is not yet in userspace
+ * FR_SENT:            request is in userspace, waiting for an answer
+ * FR_FINISHED:                request is finished
+ * FR_PRIVATE:         request is on private list
+ */
+enum fuse_req_flag {
+       FR_ISREPLY,
+       FR_FORCE,
+       FR_BACKGROUND,
+       FR_WAITING,
+       FR_ABORTED,
+       FR_INTERRUPTED,
+       FR_LOCKED,
+       FR_PENDING,
+       FR_SENT,
+       FR_FINISHED,
+       FR_PRIVATE,
 };
 
 /**
  * A request to the client
+ *
+ * .waitq.lock protects the following fields:
+ *   - FR_ABORTED
+ *   - FR_LOCKED (may also be modified under fc->lock, tested under both)
  */
 struct fuse_req {
        /** This can be on either pending processing or io lists in
@@ -259,35 +306,8 @@ struct fuse_req {
        /** Unique ID for the interrupt request */
        u64 intr_unique;
 
-       /*
-        * The following bitfields are either set once before the
-        * request is queued or setting/clearing them is protected by
-        * fuse_conn->lock
-        */
-
-       /** True if the request has reply */
-       unsigned isreply:1;
-
-       /** Force sending of the request even if interrupted */
-       unsigned force:1;
-
-       /** The request was aborted */
-       unsigned aborted:1;
-
-       /** Request is sent in the background */
-       unsigned background:1;
-
-       /** The request has been interrupted */
-       unsigned interrupted:1;
-
-       /** Data is being copied to/from the request */
-       unsigned locked:1;
-
-       /** Request is counted as "waiting" */
-       unsigned waiting:1;
-
-       /** State of the request */
-       enum fuse_req_state state;
+       /* Request flags, updated with test/set/clear_bit() */
+       unsigned long flags;
 
        /** The request input */
        struct fuse_in in;
@@ -301,11 +321,8 @@ struct fuse_req {
        /** Data for asynchronous requests */
        union {
                struct {
-                       union {
-                               struct fuse_release_in in;
-                               struct work_struct work;
-                       };
-                       struct path path;
+                       struct fuse_release_in in;
+                       struct inode *inode;
                } release;
                struct fuse_init_in init_in;
                struct fuse_init_out init_out;
@@ -317,9 +334,9 @@ struct fuse_req {
                struct {
                        struct fuse_write_in in;
                        struct fuse_write_out out;
+                       struct fuse_req *next;
                } write;
                struct fuse_notify_retrieve_in retrieve_in;
-               struct fuse_lk_in lk_in;
        } misc;
 
        /** page vector */
@@ -359,6 +376,61 @@ struct fuse_req {
        struct file *stolen_file;
 };
 
+struct fuse_iqueue {
+       /** Connection established */
+       unsigned connected;
+
+       /** Readers of the connection are waiting on this */
+       wait_queue_head_t waitq;
+
+       /** The next unique request id */
+       u64 reqctr;
+
+       /** The list of pending requests */
+       struct list_head pending;
+
+       /** Pending interrupts */
+       struct list_head interrupts;
+
+       /** Queue of pending forgets */
+       struct fuse_forget_link forget_list_head;
+       struct fuse_forget_link *forget_list_tail;
+
+       /** Batching of FORGET requests (positive indicates FORGET batch) */
+       int forget_batch;
+
+       /** O_ASYNC requests */
+       struct fasync_struct *fasync;
+};
+
+struct fuse_pqueue {
+       /** Connection established */
+       unsigned connected;
+
+       /** Lock protecting accessess to  members of this structure */
+       spinlock_t lock;
+
+       /** The list of requests being processed */
+       struct list_head processing;
+
+       /** The list of requests under I/O */
+       struct list_head io;
+};
+
+/**
+ * Fuse device instance
+ */
+struct fuse_dev {
+       /** Fuse connection for this device */
+       struct fuse_conn *fc;
+
+       /** Processing queue */
+       struct fuse_pqueue pq;
+
+       /** list entry on fc->devices */
+       struct list_head entry;
+};
+
 /**
  * A Fuse connection.
  *
@@ -370,12 +442,14 @@ struct fuse_conn {
        /** Lock protecting accessess to  members of this structure */
        spinlock_t lock;
 
-       /** Mutex protecting against directory alias creation */
-       struct mutex inst_mutex;
-
        /** Refcount */
        atomic_t count;
 
+       /** Number of fuse_dev's */
+       atomic_t dev_count;
+
+       struct rcu_head rcu;
+
        /** The user id for this mount */
        kuid_t user_id;
 
@@ -391,17 +465,8 @@ struct fuse_conn {
        /** Maximum write size */
        unsigned max_write;
 
-       /** Readers of the connection are waiting on this */
-       wait_queue_head_t waitq;
-
-       /** The list of pending requests */
-       struct list_head pending;
-
-       /** The list of requests being processed */
-       struct list_head processing;
-
-       /** The list of requests under I/O */
-       struct list_head io;
+       /** Input queue */
+       struct fuse_iqueue iq;
 
        /** The next unique kernel file handle */
        u64 khctr;
@@ -424,16 +489,6 @@ struct fuse_conn {
        /** The list of background requests set aside for later queuing */
        struct list_head bg_queue;
 
-       /** Pending interrupts */
-       struct list_head interrupts;
-
-       /** Queue of pending forgets */
-       struct fuse_forget_link forget_list_head;
-       struct fuse_forget_link *forget_list_tail;
-
-       /** Batching of FORGET requests (positive indicates FORGET batch) */
-       int forget_batch;
-
        /** Flag indicating that INIT reply has been received. Allocating
         * any fuse request will be suspended until the flag is set */
        int initialized;
@@ -449,9 +504,6 @@ struct fuse_conn {
        /** waitq for reserved requests */
        wait_queue_head_t reserved_req_waitq;
 
-       /** The next unique request id */
-       u64 reqctr;
-
        /** Connection established, cleared on umount, connection
            abort and device release */
        unsigned connected;
@@ -476,11 +528,17 @@ struct fuse_conn {
        /** Set if bdi is valid */
        unsigned bdi_initialized:1;
 
+       /** write-back cache policy (default is write-through) */
+       unsigned writeback_cache:1;
+
        /*
         * The following bitfields are only for optimization purposes
         * and hence races in setting them will not cause malfunction
         */
 
+       /** Is open/release not implemented by fs? */
+       unsigned no_open:1;
+
        /** Is fsync not implemented by fs? */
        unsigned no_fsync:1;
 
@@ -532,6 +590,9 @@ struct fuse_conn {
        /** Is fallocate not implemented by fs? */
        unsigned no_fallocate:1;
 
+       /** Is rename with flags implemented by fs? */
+       unsigned no_rename2:1;
+
        /** Use enhanced/automatic page cache invalidation. */
        unsigned auto_inval_data:1;
 
@@ -565,9 +626,6 @@ struct fuse_conn {
        /** number of dentries used in the above array */
        int ctl_ndents;
 
-       /** O_ASYNC requests */
-       struct fasync_struct *fasync;
-
        /** Key for lock owner ID scrambling */
        u32 scramble_key[4];
 
@@ -585,6 +643,9 @@ struct fuse_conn {
 
        /** Read/write semaphore to hold when accessing sb. */
        struct rw_semaphore killsb;
+
+       /** List of device instances belonging to this connection */
+       struct list_head devices;
 };
 
 static inline struct fuse_conn *get_fuse_conn_super(struct super_block *sb)
@@ -713,7 +774,7 @@ int fuse_dev_init(void);
 void fuse_dev_cleanup(void);
 
 int fuse_ctl_init(void);
-void fuse_ctl_cleanup(void);
+void __exit fuse_ctl_cleanup(void);
 
 /**
  * Allocate a request
@@ -740,15 +801,6 @@ struct fuse_req *fuse_get_req_for_background(struct fuse_conn *fc,
  */
 void __fuse_get_request(struct fuse_req *req);
 
-/**
- * Get a request, may fail with -ENOMEM,
- * useful for callers who doesn't use req->pages[]
- */
-static inline struct fuse_req *fuse_get_req_nopages(struct fuse_conn *fc)
-{
-       return fuse_get_req(fc, 0);
-}
-
 /**
  * Gets a requests for a file operation, always succeeds
  */
@@ -766,6 +818,11 @@ void fuse_put_request(struct fuse_conn *fc, struct fuse_req *req);
  */
 void fuse_request_send(struct fuse_conn *fc, struct fuse_req *req);
 
+/**
+ * Simple request sending that does request allocation and freeing
+ */
+ssize_t fuse_simple_request(struct fuse_conn *fc, struct fuse_args *args);
+
 /**
  * Send a request in the background
  */
@@ -784,13 +841,13 @@ void fuse_invalidate_attr(struct inode *inode);
 
 void fuse_invalidate_entry_cache(struct dentry *entry);
 
+void fuse_invalidate_atime(struct inode *inode);
+
 /**
  * Acquire reference to fuse_conn
  */
 struct fuse_conn *fuse_conn_get(struct fuse_conn *fc);
 
-void fuse_conn_kill(struct fuse_conn *fc);
-
 /**
  * Initialize fuse_conn
  */
@@ -801,6 +858,9 @@ void fuse_conn_init(struct fuse_conn *fc);
  */
 void fuse_conn_put(struct fuse_conn *fc);
 
+struct fuse_dev *fuse_dev_alloc(struct fuse_conn *fc);
+void fuse_dev_free(struct fuse_dev *fud);
+
 /**
  * Add connection to control filesystem
  */
@@ -854,9 +914,19 @@ int fuse_reverse_inval_entry(struct super_block *sb, u64 parent_nodeid,
 
 int fuse_do_open(struct fuse_conn *fc, u64 nodeid, struct file *file,
                 bool isdir);
-ssize_t fuse_direct_io(struct fuse_io_priv *io, const struct iovec *iov,
-                      unsigned long nr_segs, size_t count, loff_t *ppos,
-                      int write);
+
+/**
+ * fuse_direct_io() flags
+ */
+
+/** If set, it is WRITE; otherwise - READ */
+#define FUSE_DIO_WRITE (1 << 0)
+
+/** CUSE pass fuse_direct_io() a file which f_mapping->host is not from FUSE */
+#define FUSE_DIO_CUSE  (1 << 1)
+
+ssize_t fuse_direct_io(struct fuse_io_priv *io, struct iov_iter *iter,
+                      loff_t *ppos, int flags);
 long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg,
                   unsigned int flags);
 long fuse_ioctl_common(struct file *file, unsigned int cmd,
@@ -864,9 +934,14 @@ long fuse_ioctl_common(struct file *file, unsigned int cmd,
 unsigned fuse_file_poll(struct file *file, poll_table *wait);
 int fuse_dev_release(struct inode *inode, struct file *file);
 
-void fuse_write_update_size(struct inode *inode, loff_t pos);
+bool fuse_write_update_size(struct inode *inode, loff_t pos);
+
+int fuse_flush_times(struct inode *inode, struct fuse_file *ff);
+int fuse_write_inode(struct inode *inode, struct writeback_control *wbc);
 
 int fuse_do_setattr(struct inode *inode, struct iattr *attr,
                    struct file *file);
 
+void fuse_set_initialized(struct fuse_conn *fc);
+
 #endif /* _FS_FUSE_I_H */