Detach sched.h from mm.h
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / fs / afs / internal.h
index 34665f7d7a19360769daac981be9c2d042ce036e..2dac3ad2c44b6c1110452208826dfac0186b901b 100644 (file)
 #include <linux/skbuff.h>
 #include <linux/rxrpc.h>
 #include <linux/key.h>
+#include <linux/workqueue.h>
 #include "afs.h"
 #include "afs_vl.h"
 
 #define AFS_CELL_MAX_ADDRS 15
 
+struct pagevec;
 struct afs_call;
 
 typedef enum {
@@ -75,12 +77,15 @@ struct afs_call {
        struct key              *key;           /* security for this call */
        struct afs_server       *server;        /* server affected by incoming CM call */
        void                    *request;       /* request data (first part) */
-       void                    *request2;      /* request data (second part) */
+       struct address_space    *mapping;       /* page set */
+       struct afs_writeback    *wb;            /* writeback being performed */
        void                    *buffer;        /* reply receive buffer */
        void                    *reply;         /* reply buffer (first part) */
        void                    *reply2;        /* reply buffer (second part) */
        void                    *reply3;        /* reply buffer (third part) */
        void                    *reply4;        /* reply buffer (fourth part) */
+       pgoff_t                 first;          /* first page in mapping to deal with */
+       pgoff_t                 last;           /* last page in mapping to deal with */
        enum {                                  /* call state */
                AFS_CALL_REQUESTING,    /* request is being sent for outgoing call */
                AFS_CALL_AWAIT_REPLY,   /* awaiting reply to outgoing call */
@@ -97,14 +102,18 @@ struct afs_call {
        unsigned                request_size;   /* size of request data */
        unsigned                reply_max;      /* maximum size of reply */
        unsigned                reply_size;     /* current size of reply */
+       unsigned                first_offset;   /* offset into mapping[first] */
+       unsigned                last_to;        /* amount of mapping[last] */
        unsigned short          offset;         /* offset into received data store */
        unsigned char           unmarshall;     /* unmarshalling phase */
        bool                    incoming;       /* T if incoming call */
+       bool                    send_pages;     /* T if data from mapping should be sent */
        u16                     service_id;     /* RxRPC service ID to call */
        __be16                  port;           /* target UDP port */
        __be32                  operation_ID;   /* operation ID for an incoming call */
        u32                     count;          /* count for use in unmarshalling */
        __be32                  tmp;            /* place to extract temporary data */
+       afs_dataversion_t       store_version;  /* updated version expected from store */
 };
 
 struct afs_call_type {
@@ -123,6 +132,32 @@ struct afs_call_type {
        void (*destructor)(struct afs_call *call);
 };
 
+/*
+ * record of an outstanding writeback on a vnode
+ */
+struct afs_writeback {
+       struct list_head        link;           /* link in vnode->writebacks */
+       struct work_struct      writer;         /* work item to perform the writeback */
+       struct afs_vnode        *vnode;         /* vnode to which this write applies */
+       struct key              *key;           /* owner of this write */
+       wait_queue_head_t       waitq;          /* completion and ready wait queue */
+       pgoff_t                 first;          /* first page in batch */
+       pgoff_t                 point;          /* last page in current store op */
+       pgoff_t                 last;           /* last page in batch (inclusive) */
+       unsigned                offset_first;   /* offset into first page of start of write */
+       unsigned                to_last;        /* offset into last page of end of write */
+       int                     num_conflicts;  /* count of conflicting writes in list */
+       int                     usage;
+       bool                    conflicts;      /* T if has dependent conflicts */
+       enum {
+               AFS_WBACK_SYNCING,              /* synchronisation being performed */
+               AFS_WBACK_PENDING,              /* write pending */
+               AFS_WBACK_CONFLICTING,          /* conflicting writes posted */
+               AFS_WBACK_WRITING,              /* writing back */
+               AFS_WBACK_COMPLETE              /* the writeback record has been unlinked */
+       } state __attribute__((packed));
+};
+
 /*
  * AFS superblock private data
  * - there's one superblock per volume
@@ -305,6 +340,7 @@ struct afs_vnode {
        wait_queue_head_t       update_waitq;   /* status fetch waitqueue */
        int                     update_cnt;     /* number of outstanding ops that will update the
                                                 * status */
+       spinlock_t              writeback_lock; /* lock for writebacks */
        spinlock_t              lock;           /* waitqueue/flags lock */
        unsigned long           flags;
 #define AFS_VNODE_CB_BROKEN    0               /* set if vnode's callback was broken */
@@ -316,6 +352,8 @@ struct afs_vnode {
 
        long                    acl_order;      /* ACL check count (callback break count) */
 
+       struct list_head        writebacks;     /* alterations in pagecache that need writing */
+
        /* outstanding callback notification on this file */
        struct rb_node          server_rb;      /* link in server->fs_vnodes */
        struct rb_node          cb_promise;     /* link in server->cb_promises */
@@ -349,7 +387,6 @@ struct afs_permits {
  * record of one of a system's set of network interfaces
  */
 struct afs_interface {
-       unsigned        index;          /* interface index */
        struct in_addr  address;        /* IPv4 address bound to interface */
        struct in_addr  netmask;        /* netmask applied to address */
        unsigned        mtu;            /* MTU of interface */
@@ -392,7 +429,7 @@ extern void afs_give_up_callback(struct afs_vnode *);
 extern void afs_dispatch_give_up_callbacks(struct work_struct *);
 extern void afs_flush_callback_breaks(struct afs_server *);
 extern int __init afs_callback_update_init(void);
-extern void __exit afs_callback_update_kill(void);
+extern void afs_callback_update_kill(void);
 
 /*
  * cell.c
@@ -434,10 +471,6 @@ extern const struct file_operations afs_file_operations;
 extern int afs_open(struct inode *, struct file *);
 extern int afs_release(struct inode *, struct file *);
 
-#ifdef AFS_CACHING_SUPPORT
-extern int afs_cache_get_page_cookie(struct page *, struct cachefs_page **);
-#endif
-
 /*
  * fsclient.c
  */
@@ -468,6 +501,16 @@ extern int afs_fs_rename(struct afs_server *, struct key *,
                         struct afs_vnode *, const char *,
                         struct afs_vnode *, const char *,
                         const struct afs_wait_mode *);
+extern int afs_fs_store_data(struct afs_server *, struct afs_writeback *,
+                            pgoff_t, pgoff_t, unsigned, unsigned,
+                            const struct afs_wait_mode *);
+extern int afs_fs_setattr(struct afs_server *, struct key *,
+                         struct afs_vnode *, struct iattr *,
+                         const struct afs_wait_mode *);
+extern int afs_fs_get_volume_status(struct afs_server *, struct key *,
+                                   struct afs_vnode *,
+                                   struct afs_volume_status *,
+                                   const struct afs_wait_mode *);
 
 /*
  * inode.c
@@ -475,10 +518,10 @@ extern int afs_fs_rename(struct afs_server *, struct key *,
 extern struct inode *afs_iget(struct super_block *, struct key *,
                              struct afs_fid *, struct afs_file_status *,
                              struct afs_callback *);
+extern void afs_zap_data(struct afs_vnode *);
 extern int afs_validate(struct afs_vnode *, struct key *);
-extern int afs_inode_getattr(struct vfsmount *, struct dentry *,
-                            struct kstat *);
-extern void afs_zap_permits(struct rcu_head *);
+extern int afs_getattr(struct vfsmount *, struct dentry *, struct kstat *);
+extern int afs_setattr(struct dentry *, struct iattr *);
 extern void afs_clear_inode(struct inode *);
 
 /*
@@ -534,6 +577,7 @@ extern int afs_extract_data(struct afs_call *, struct sk_buff *, bool, void *,
  */
 extern void afs_clear_permits(struct afs_vnode *);
 extern void afs_cache_permit(struct afs_vnode *, struct key *, long);
+extern void afs_zap_permits(struct rcu_head *);
 extern struct key *afs_request_key(struct afs_cell *);
 extern int afs_permission(struct inode *, int, struct nameidata *);
 
@@ -564,7 +608,7 @@ extern void afs_fs_exit(void);
  * use-rtnetlink.c
  */
 extern int afs_get_ipv4_interfaces(struct afs_interface *, size_t, bool);
-extern int afs_get_MAC_address(u8 [6]);
+extern int afs_get_MAC_address(u8 *, size_t);
 
 /*
  * vlclient.c
@@ -591,7 +635,7 @@ extern struct afs_vlocation *afs_vlocation_lookup(struct afs_cell *,
                                                  struct key *,
                                                  const char *, size_t);
 extern void afs_put_vlocation(struct afs_vlocation *);
-extern void __exit afs_vlocation_purge(void);
+extern void afs_vlocation_purge(void);
 
 /*
  * vnode.c
@@ -630,6 +674,11 @@ extern int afs_vnode_symlink(struct afs_vnode *, struct key *, const char *,
                             struct afs_file_status *, struct afs_server **);
 extern int afs_vnode_rename(struct afs_vnode *, struct afs_vnode *,
                            struct key *, const char *, const char *);
+extern int afs_vnode_store_data(struct afs_writeback *, pgoff_t, pgoff_t,
+                               unsigned, unsigned);
+extern int afs_vnode_setattr(struct afs_vnode *, struct key *, struct iattr *);
+extern int afs_vnode_get_volume_status(struct afs_vnode *, struct key *,
+                                      struct afs_volume_status *);
 
 /*
  * volume.c
@@ -646,6 +695,23 @@ extern struct afs_server *afs_volume_pick_fileserver(struct afs_vnode *);
 extern int afs_volume_release_fileserver(struct afs_vnode *,
                                         struct afs_server *, int);
 
+/*
+ * write.c
+ */
+extern int afs_set_page_dirty(struct page *);
+extern void afs_put_writeback(struct afs_writeback *);
+extern int afs_prepare_write(struct file *, struct page *, unsigned, unsigned);
+extern int afs_commit_write(struct file *, struct page *, unsigned, unsigned);
+extern int afs_writepage(struct page *, struct writeback_control *);
+extern int afs_writepages(struct address_space *, struct writeback_control *);
+extern int afs_write_inode(struct inode *, int);
+extern void afs_pages_written_back(struct afs_vnode *, struct afs_call *);
+extern ssize_t afs_file_write(struct kiocb *, const struct iovec *,
+                             unsigned long, loff_t);
+extern int afs_writeback_all(struct afs_vnode *);
+extern int afs_fsync(struct file *, struct dentry *, int);
+
+
 /*****************************************************************************/
 /*
  * debug tracing
@@ -727,6 +793,21 @@ do {                                                                       \
        }                                                               \
 } while(0)
 
+#define ASSERTRANGE(L, OP1, N, OP2, H)                                 \
+do {                                                                   \
+       if (unlikely(!((L) OP1 (N)) || !((N) OP2 (H)))) {               \
+               printk(KERN_ERR "\n");                                  \
+               printk(KERN_ERR "AFS: Assertion failed\n");             \
+               printk(KERN_ERR "%lu "#OP1" %lu "#OP2" %lu is false\n", \
+                      (unsigned long)(L), (unsigned long)(N),          \
+                      (unsigned long)(H));                             \
+               printk(KERN_ERR "0x%lx "#OP1" 0x%lx "#OP2" 0x%lx is false\n", \
+                      (unsigned long)(L), (unsigned long)(N),          \
+                      (unsigned long)(H));                             \
+               BUG();                                                  \
+       }                                                               \
+} while(0)
+
 #define ASSERTIF(C, X)                                         \
 do {                                                           \
        if (unlikely((C) && !(X))) {                            \
@@ -759,6 +840,10 @@ do {                                               \
 do {                                           \
 } while(0)
 
+#define ASSERTRANGE(L, OP1, N, OP2, H)         \
+do {                                           \
+} while(0)
+
 #define ASSERTIF(C, X)                         \
 do {                                           \
 } while(0)