]> err.no Git - linux-2.6/blobdiff - fs/fuse/fuse_i.h
[PATCH] fuse: add asynchronous request support
[linux-2.6] / fs / fuse / fuse_i.h
index 0ea5301f86bee8b585d5b8b1085ac3199a674bb4..145098056ca6556749f12668eaead0006598cf3e 100644 (file)
@@ -21,6 +21,9 @@
 /** If more requests are outstanding, then the operation will block */
 #define FUSE_MAX_OUTSTANDING 10
 
+/** It could be as large as PATH_MAX, but would that have any uses? */
+#define FUSE_NAME_MAX 1024
+
 /** If the FUSE_DEFAULT_PERMISSIONS flag is given, the filesystem
     module will check permissions based on the file mode.  Otherwise no
     permission checking is done in the kernel */
@@ -108,15 +111,23 @@ struct fuse_out {
        struct fuse_arg args[3];
 };
 
-struct fuse_req;
+/** The request state */
+enum fuse_req_state {
+       FUSE_REQ_INIT = 0,
+       FUSE_REQ_PENDING,
+       FUSE_REQ_READING,
+       FUSE_REQ_SENT,
+       FUSE_REQ_FINISHED
+};
+
 struct fuse_conn;
 
 /**
  * A request to the client
  */
 struct fuse_req {
-       /** This can be on either unused_list, pending or processing
-           lists in fuse_conn */
+       /** This can be on either unused_list, pending processing or
+           io lists in fuse_conn */
        struct list_head list;
 
        /** Entry on the background list */
@@ -140,11 +151,8 @@ struct fuse_req {
        /** Data is being copied to/from the request */
        unsigned locked:1;
 
-       /** Request has been sent to userspace */
-       unsigned sent:1;
-
-       /** The request is finished */
-       unsigned finished:1;
+       /** State of the request */
+       enum fuse_req_state state;
 
        /** The request input */
        struct fuse_in in;
@@ -159,7 +167,8 @@ struct fuse_req {
        union {
                struct fuse_forget_in forget_in;
                struct fuse_release_in release_in;
-               struct fuse_init_in_out init_in_out;
+               struct fuse_init_in init_in;
+               struct fuse_init_out init_out;
        } misc;
 
        /** page vector */
@@ -179,6 +188,9 @@ struct fuse_req {
 
        /** File used in the request (or NULL) */
        struct file *file;
+
+       /** Request completion callback */
+       void (*end)(struct fuse_conn *, struct fuse_req *);
 };
 
 /**
@@ -189,9 +201,6 @@ struct fuse_req {
  * unmounted.
  */
 struct fuse_conn {
-       /** Reference count */
-       int count;
-
        /** The user id for this mount */
        uid_t user_id;
 
@@ -216,6 +225,9 @@ struct fuse_conn {
        /** The list of requests being processed */
        struct list_head processing;
 
+       /** The list of requests under I/O */
+       struct list_head io;
+
        /** Requests put in the background (RELEASE or any other
            interrupted request) */
        struct list_head background;
@@ -239,7 +251,8 @@ struct fuse_conn {
        /** Mount is active */
        unsigned mounted : 1;
 
-       /** Connection established */
+       /** Connection established, cleared on umount, connection
+           abort and device release */
        unsigned connected : 1;
 
        /** Connection failed (version mismatch) */
@@ -272,18 +285,22 @@ struct fuse_conn {
        /** Is create not implemented by fs? */
        unsigned no_create : 1;
 
+       /** The number of requests waiting for completion */
+       atomic_t num_waiting;
+
+       /** Negotiated minor version */
+       unsigned minor;
+
        /** Backing dev info */
        struct backing_dev_info bdi;
-};
 
-static inline struct fuse_conn **get_fuse_conn_super_p(struct super_block *sb)
-{
-       return (struct fuse_conn **) &sb->s_fs_info;
-}
+       /** kobject */
+       struct kobject kobj;
+};
 
 static inline struct fuse_conn *get_fuse_conn_super(struct super_block *sb)
 {
-       return *get_fuse_conn_super_p(sb);
+       return sb->s_fs_info;
 }
 
 static inline struct fuse_conn *get_fuse_conn(struct inode *inode)
@@ -291,6 +308,11 @@ static inline struct fuse_conn *get_fuse_conn(struct inode *inode)
        return get_fuse_conn_super(inode->i_sb);
 }
 
+static inline struct fuse_conn *get_fuse_conn_kobj(struct kobject *obj)
+{
+       return container_of(obj, struct fuse_conn, kobj);
+}
+
 static inline struct fuse_inode *get_fuse_inode(struct inode *inode)
 {
        return container_of(inode, struct fuse_inode, inode);
@@ -390,12 +412,6 @@ void fuse_init_symlink(struct inode *inode);
  */
 void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr);
 
-/**
- * Check if the connection can be released, and if yes, then free the
- * connection structure
- */
-void fuse_release_conn(struct fuse_conn *fc);
-
 /**
  * Initialize the client device
  */
@@ -452,6 +468,9 @@ void request_send_background(struct fuse_conn *fc, struct fuse_req *req);
  */
 void fuse_release_background(struct fuse_req *req);
 
+/* Abort all requests */
+void fuse_abort_conn(struct fuse_conn *fc);
+
 /**
  * Get the attributes of a file
  */