Merge branch 'driver-core-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
[pandora-kernel.git] / fs / nfs / pnfs.h
index 5b083d2..96bf4e6 100644 (file)
@@ -65,6 +65,11 @@ enum {
        NFS_LAYOUT_DESTROYED,           /* no new use of layout allowed */
 };
 
+enum layoutdriver_policy_flags {
+       /* Should the pNFS client commit and return the layout upon a setattr */
+       PNFS_LAYOUTRET_ON_SETATTR       = 1 << 0,
+};
+
 struct nfs4_deviceid_node;
 
 /* Per-layout driver specific registration structure */
@@ -73,11 +78,16 @@ struct pnfs_layoutdriver_type {
        const u32 id;
        const char *name;
        struct module *owner;
+       unsigned flags;
+
+       struct pnfs_layout_hdr * (*alloc_layout_hdr) (struct inode *inode, gfp_t gfp_flags);
+       void (*free_layout_hdr) (struct pnfs_layout_hdr *);
+
        struct pnfs_layout_segment * (*alloc_lseg) (struct pnfs_layout_hdr *layoutid, struct nfs4_layoutget_res *lgr, gfp_t gfp_flags);
        void (*free_lseg) (struct pnfs_layout_segment *lseg);
 
        /* test for nfs page cache coalescing */
-       int (*pg_test)(struct nfs_pageio_descriptor *, struct nfs_page *, struct nfs_page *);
+       bool (*pg_test)(struct nfs_pageio_descriptor *, struct nfs_page *, struct nfs_page *);
 
        /* Returns true if layoutdriver wants to divert this request to
         * driver's commit routine.
@@ -94,6 +104,14 @@ struct pnfs_layoutdriver_type {
        enum pnfs_try_status (*write_pagelist) (struct nfs_write_data *nfs_data, int how);
 
        void (*free_deviceid_node) (struct nfs4_deviceid_node *);
+
+       void (*encode_layoutreturn) (struct pnfs_layout_hdr *layoutid,
+                                    struct xdr_stream *xdr,
+                                    const struct nfs4_layoutreturn_args *args);
+
+       void (*encode_layoutcommit) (struct pnfs_layout_hdr *layoutid,
+                                    struct xdr_stream *xdr,
+                                    const struct nfs4_layoutcommit_args *args);
 };
 
 struct pnfs_layout_hdr {
@@ -125,21 +143,22 @@ extern void pnfs_unregister_layoutdriver(struct pnfs_layoutdriver_type *);
 extern int nfs4_proc_getdeviceinfo(struct nfs_server *server,
                                   struct pnfs_device *dev);
 extern int nfs4_proc_layoutget(struct nfs4_layoutget *lgp);
+extern int nfs4_proc_layoutreturn(struct nfs4_layoutreturn *lrp);
 
 /* pnfs.c */
 void get_layout_hdr(struct pnfs_layout_hdr *lo);
 void put_lseg(struct pnfs_layout_segment *lseg);
 struct pnfs_layout_segment *
 pnfs_update_layout(struct inode *ino, struct nfs_open_context *ctx,
-                  enum pnfs_iomode access_type, gfp_t gfp_flags);
+                  loff_t pos, u64 count, enum pnfs_iomode access_type,
+                  gfp_t gfp_flags);
 void set_pnfs_layoutdriver(struct nfs_server *, u32 id);
 void unset_pnfs_layoutdriver(struct nfs_server *);
 enum pnfs_try_status pnfs_try_to_write_data(struct nfs_write_data *,
                                             const struct rpc_call_ops *, int);
 enum pnfs_try_status pnfs_try_to_read_data(struct nfs_read_data *,
                                            const struct rpc_call_ops *);
-void pnfs_pageio_init_read(struct nfs_pageio_descriptor *, struct inode *);
-void pnfs_pageio_init_write(struct nfs_pageio_descriptor *, struct inode *);
+bool pnfs_generic_pg_test(struct nfs_pageio_descriptor *pgio, struct nfs_page *prev, struct nfs_page *req);
 int pnfs_layout_process(struct nfs4_layoutget *lgp);
 void pnfs_free_lseg_list(struct list_head *tmp_list);
 void pnfs_destroy_layout(struct nfs_inode *);
@@ -153,17 +172,21 @@ int pnfs_choose_layoutget_stateid(nfs4_stateid *dst,
                                  struct nfs4_state *open_state);
 int mark_matching_lsegs_invalid(struct pnfs_layout_hdr *lo,
                                struct list_head *tmp_list,
-                               u32 iomode);
+                               struct pnfs_layout_range *recall_range);
 bool pnfs_roc(struct inode *ino);
 void pnfs_roc_release(struct inode *ino);
 void pnfs_roc_set_barrier(struct inode *ino, u32 barrier);
 bool pnfs_roc_drain(struct inode *ino, u32 *barrier);
 void pnfs_set_layoutcommit(struct nfs_write_data *wdata);
 int pnfs_layoutcommit_inode(struct inode *inode, bool sync);
+int _pnfs_return_layout(struct inode *);
+int pnfs_ld_write_done(struct nfs_write_data *);
+int pnfs_ld_read_done(struct nfs_read_data *);
 
 /* pnfs_dev.c */
 struct nfs4_deviceid_node {
        struct hlist_node               node;
+       struct hlist_node               tmpnode;
        const struct pnfs_layoutdriver_type *ld;
        const struct nfs_client         *nfs_client;
        struct nfs4_deviceid            deviceid;
@@ -249,6 +272,36 @@ static inline void pnfs_clear_request_commit(struct nfs_page *req)
                put_lseg(req->wb_commit_lseg);
 }
 
+/* Should the pNFS client commit and return the layout upon a setattr */
+static inline bool
+pnfs_ld_layoutret_on_setattr(struct inode *inode)
+{
+       if (!pnfs_enabled_sb(NFS_SERVER(inode)))
+               return false;
+       return NFS_SERVER(inode)->pnfs_curr_ld->flags &
+               PNFS_LAYOUTRET_ON_SETATTR;
+}
+
+static inline int pnfs_return_layout(struct inode *ino)
+{
+       struct nfs_inode *nfsi = NFS_I(ino);
+       struct nfs_server *nfss = NFS_SERVER(ino);
+
+       if (pnfs_enabled_sb(nfss) && nfsi->layout)
+               return _pnfs_return_layout(ino);
+
+       return 0;
+}
+
+static inline void pnfs_pageio_init(struct nfs_pageio_descriptor *pgio,
+                                   struct inode *inode)
+{
+       struct pnfs_layoutdriver_type *ld = NFS_SERVER(inode)->pnfs_curr_ld;
+
+       if (ld)
+               pgio->pg_test = ld->pg_test;
+}
+
 #else  /* CONFIG_NFS_V4_1 */
 
 static inline void pnfs_destroy_all_layouts(struct nfs_client *clp)
@@ -271,7 +324,8 @@ static inline void put_lseg(struct pnfs_layout_segment *lseg)
 
 static inline struct pnfs_layout_segment *
 pnfs_update_layout(struct inode *ino, struct nfs_open_context *ctx,
-                  enum pnfs_iomode access_type, gfp_t gfp_flags)
+                  loff_t pos, u64 count, enum pnfs_iomode access_type,
+                  gfp_t gfp_flags)
 {
        return NULL;
 }
@@ -290,6 +344,17 @@ pnfs_try_to_write_data(struct nfs_write_data *data,
        return PNFS_NOT_ATTEMPTED;
 }
 
+static inline int pnfs_return_layout(struct inode *ino)
+{
+       return 0;
+}
+
+static inline bool
+pnfs_ld_layoutret_on_setattr(struct inode *inode)
+{
+       return false;
+}
+
 static inline bool
 pnfs_roc(struct inode *ino)
 {
@@ -320,16 +385,9 @@ static inline void unset_pnfs_layoutdriver(struct nfs_server *s)
 {
 }
 
-static inline void
-pnfs_pageio_init_read(struct nfs_pageio_descriptor *pgio, struct inode *ino)
-{
-       pgio->pg_test = NULL;
-}
-
-static inline void
-pnfs_pageio_init_write(struct nfs_pageio_descriptor *pgio, struct inode *ino)
+static inline void pnfs_pageio_init(struct nfs_pageio_descriptor *pgio,
+                                   struct inode *inode)
 {
-       pgio->pg_test = NULL;
 }
 
 static inline void