]> Git Repo - linux.git/blobdiff - fs/nfs/pnfs.h
mm: convert find_get_entry to return the head page
[linux.git] / fs / nfs / pnfs.h
index 0fafdadc9c8d6548e5ea05edde37991f6508cbbd..2661c44c62db402fbbd4c1832ba533f2f187f433 100644 (file)
@@ -66,6 +66,7 @@ struct nfs4_pnfs_ds {
 struct pnfs_layout_segment {
        struct list_head pls_list;
        struct list_head pls_lc_list;
+       struct list_head pls_commits;
        struct pnfs_layout_range pls_range;
        refcount_t pls_refcount;
        u32 pls_seq;
@@ -105,6 +106,7 @@ enum {
        NFS_LAYOUT_INVALID_STID,        /* layout stateid id is invalid */
        NFS_LAYOUT_FIRST_LAYOUTGET,     /* Serialize first layoutget */
        NFS_LAYOUT_INODE_FREEING,       /* The inode is being freed */
+       NFS_LAYOUT_HASHED,              /* The layout visible */
 };
 
 enum layoutdriver_policy_flags {
@@ -148,22 +150,6 @@ struct pnfs_layoutdriver_type {
        const struct nfs_pageio_ops *pg_write_ops;
 
        struct pnfs_ds_commit_info *(*get_ds_info) (struct inode *inode);
-       void (*mark_request_commit) (struct nfs_page *req,
-                                    struct pnfs_layout_segment *lseg,
-                                    struct nfs_commit_info *cinfo,
-                                    u32 ds_commit_idx);
-       void (*clear_request_commit) (struct nfs_page *req,
-                                     struct nfs_commit_info *cinfo);
-       int (*scan_commit_lists) (struct nfs_commit_info *cinfo,
-                                 int max);
-       void (*recover_commit_reqs) (struct list_head *list,
-                                    struct nfs_commit_info *cinfo);
-       struct nfs_page * (*search_commit_reqs)(struct nfs_commit_info *cinfo,
-                                               struct page *page);
-       int (*commit_pagelist)(struct inode *inode,
-                              struct list_head *mds_pages,
-                              int how,
-                              struct nfs_commit_info *cinfo);
 
        int (*sync)(struct inode *inode, bool datasync);
 
@@ -186,6 +172,29 @@ struct pnfs_layoutdriver_type {
        int (*prepare_layoutstats) (struct nfs42_layoutstat_args *args);
 };
 
+struct pnfs_commit_ops {
+       void (*setup_ds_info)(struct pnfs_ds_commit_info *,
+                             struct pnfs_layout_segment *);
+       void (*release_ds_info)(struct pnfs_ds_commit_info *,
+                               struct inode *inode);
+       int (*commit_pagelist)(struct inode *inode,
+                              struct list_head *mds_pages,
+                              int how,
+                              struct nfs_commit_info *cinfo);
+       void (*mark_request_commit) (struct nfs_page *req,
+                                    struct pnfs_layout_segment *lseg,
+                                    struct nfs_commit_info *cinfo,
+                                    u32 ds_commit_idx);
+       void (*clear_request_commit) (struct nfs_page *req,
+                                     struct nfs_commit_info *cinfo);
+       int (*scan_commit_lists) (struct nfs_commit_info *cinfo,
+                                 int max);
+       void (*recover_commit_reqs) (struct list_head *list,
+                                    struct nfs_commit_info *cinfo);
+       struct nfs_page * (*search_commit_reqs)(struct nfs_commit_info *cinfo,
+                                               struct page *page);
+};
+
 struct pnfs_layout_hdr {
        refcount_t              plh_refcount;
        atomic_t                plh_outstanding; /* number of RPCs out */
@@ -203,6 +212,7 @@ struct pnfs_layout_hdr {
        loff_t                  plh_lwb; /* last write byte for layoutcommit */
        const struct cred       *plh_lc_cred; /* layoutcommit cred */
        struct inode            *plh_inode;
+       struct rcu_head         plh_rcu;
 };
 
 struct pnfs_device {
@@ -242,6 +252,7 @@ void pnfs_put_lseg(struct pnfs_layout_segment *lseg);
 void set_pnfs_layoutdriver(struct nfs_server *, const struct nfs_fh *, struct nfs_fsinfo *);
 void unset_pnfs_layoutdriver(struct nfs_server *);
 void pnfs_generic_pg_check_layout(struct nfs_pageio_descriptor *pgio);
+void pnfs_generic_pg_check_range(struct nfs_pageio_descriptor *pgio, struct nfs_page *req);
 void pnfs_generic_pg_init_read(struct nfs_pageio_descriptor *, struct nfs_page *);
 int pnfs_generic_pg_readpages(struct nfs_pageio_descriptor *desc);
 void pnfs_generic_pg_init_write(struct nfs_pageio_descriptor *pgio,
@@ -267,6 +278,7 @@ bool nfs4_layout_refresh_old_stateid(nfs4_stateid *dst,
 void pnfs_put_layout_hdr(struct pnfs_layout_hdr *lo);
 void pnfs_set_layout_stateid(struct pnfs_layout_hdr *lo,
                             const nfs4_stateid *new,
+                            const struct cred *cred,
                             bool update_barrier);
 int pnfs_mark_matching_lsegs_invalid(struct pnfs_layout_hdr *lo,
                                struct list_head *tmp_list,
@@ -299,7 +311,7 @@ int _pnfs_return_layout(struct inode *);
 int pnfs_commit_and_return_layout(struct inode *);
 void pnfs_ld_write_done(struct nfs_pgio_header *);
 void pnfs_ld_read_done(struct nfs_pgio_header *);
-void pnfs_read_resend_pnfs(struct nfs_pgio_header *);
+void pnfs_read_resend_pnfs(struct nfs_pgio_header *, unsigned int mirror_idx);
 struct pnfs_layout_segment *pnfs_update_layout(struct inode *ino,
                                               struct nfs_open_context *ctx,
                                               loff_t pos,
@@ -326,6 +338,9 @@ int pnfs_write_done_resend_to_mds(struct nfs_pgio_header *);
 struct nfs4_threshold *pnfs_mdsthreshold_alloc(void);
 void pnfs_error_mark_layout_for_return(struct inode *inode,
                                       struct pnfs_layout_segment *lseg);
+void pnfs_layout_return_unused_byclid(struct nfs_client *clp,
+                                     enum pnfs_iomode iomode);
+
 /* nfs4_deviceid_flags */
 enum {
        NFS_DEVICEID_INVALID = 0,       /* set when MDS clientid recalled */
@@ -360,6 +375,16 @@ bool nfs4_test_deviceid_unavailable(struct nfs4_deviceid_node *node);
 void nfs4_deviceid_purge_client(const struct nfs_client *);
 
 /* pnfs_nfs.c */
+struct pnfs_commit_array *pnfs_alloc_commit_array(size_t n, gfp_t gfp_flags);
+void pnfs_free_commit_array(struct pnfs_commit_array *p);
+struct pnfs_commit_array *pnfs_add_commit_array(struct pnfs_ds_commit_info *,
+                                               struct pnfs_commit_array *,
+                                               struct pnfs_layout_segment *);
+
+void pnfs_generic_ds_cinfo_release_lseg(struct pnfs_ds_commit_info *fl_cinfo,
+               struct pnfs_layout_segment *lseg);
+void pnfs_generic_ds_cinfo_destroy(struct pnfs_ds_commit_info *fl_cinfo);
+
 void pnfs_generic_clear_request_commit(struct nfs_page *req,
                                       struct nfs_commit_info *cinfo);
 void pnfs_generic_commit_release(void *calldata);
@@ -367,6 +392,8 @@ void pnfs_generic_prepare_to_resend_writes(struct nfs_commit_data *data);
 void pnfs_generic_rw_release(void *data);
 void pnfs_generic_recover_commit_reqs(struct list_head *dst,
                                      struct nfs_commit_info *cinfo);
+struct nfs_page *pnfs_generic_search_commit_reqs(struct nfs_commit_info *cinfo,
+                                                struct page *page);
 int pnfs_generic_commit_pagelist(struct inode *inode,
                                 struct list_head *mds_pages,
                                 int how,
@@ -438,9 +465,11 @@ static inline int
 pnfs_commit_list(struct inode *inode, struct list_head *mds_pages, int how,
                 struct nfs_commit_info *cinfo)
 {
-       if (cinfo->ds == NULL || cinfo->ds->ncommitting == 0)
+       struct pnfs_ds_commit_info *fl_cinfo = cinfo->ds;
+
+       if (fl_cinfo == NULL || fl_cinfo->ncommitting == 0)
                return PNFS_NOT_ATTEMPTED;
-       return NFS_SERVER(inode)->pnfs_curr_ld->commit_pagelist(inode, mds_pages, how, cinfo);
+       return fl_cinfo->ops->commit_pagelist(inode, mds_pages, how, cinfo);
 }
 
 static inline struct pnfs_ds_commit_info *
@@ -453,6 +482,28 @@ pnfs_get_ds_info(struct inode *inode)
        return ld->get_ds_info(inode);
 }
 
+static inline void
+pnfs_init_ds_commit_info_ops(struct pnfs_ds_commit_info *fl_cinfo, struct inode *inode)
+{
+       struct pnfs_ds_commit_info *inode_cinfo = pnfs_get_ds_info(inode);
+       if (inode_cinfo != NULL)
+               fl_cinfo->ops = inode_cinfo->ops;
+}
+
+static inline void
+pnfs_init_ds_commit_info(struct pnfs_ds_commit_info *fl_cinfo)
+{
+       INIT_LIST_HEAD(&fl_cinfo->commits);
+       fl_cinfo->ops = NULL;
+}
+
+static inline void
+pnfs_release_ds_info(struct pnfs_ds_commit_info *fl_cinfo, struct inode *inode)
+{
+       if (fl_cinfo->ops != NULL && fl_cinfo->ops->release_ds_info != NULL)
+               fl_cinfo->ops->release_ds_info(fl_cinfo, inode);
+}
+
 static inline void
 pnfs_generic_mark_devid_invalid(struct nfs4_deviceid_node *node)
 {
@@ -463,24 +514,22 @@ static inline bool
 pnfs_mark_request_commit(struct nfs_page *req, struct pnfs_layout_segment *lseg,
                         struct nfs_commit_info *cinfo, u32 ds_commit_idx)
 {
-       struct inode *inode = d_inode(nfs_req_openctx(req)->dentry);
-       struct pnfs_layoutdriver_type *ld = NFS_SERVER(inode)->pnfs_curr_ld;
+       struct pnfs_ds_commit_info *fl_cinfo = cinfo->ds;
 
-       if (lseg == NULL || ld->mark_request_commit == NULL)
+       if (!lseg || !fl_cinfo->ops->mark_request_commit)
                return false;
-       ld->mark_request_commit(req, lseg, cinfo, ds_commit_idx);
+       fl_cinfo->ops->mark_request_commit(req, lseg, cinfo, ds_commit_idx);
        return true;
 }
 
 static inline bool
 pnfs_clear_request_commit(struct nfs_page *req, struct nfs_commit_info *cinfo)
 {
-       struct inode *inode = d_inode(nfs_req_openctx(req)->dentry);
-       struct pnfs_layoutdriver_type *ld = NFS_SERVER(inode)->pnfs_curr_ld;
+       struct pnfs_ds_commit_info *fl_cinfo = cinfo->ds;
 
-       if (ld == NULL || ld->clear_request_commit == NULL)
+       if (!fl_cinfo || !fl_cinfo->ops || !fl_cinfo->ops->clear_request_commit)
                return false;
-       ld->clear_request_commit(req, cinfo);
+       fl_cinfo->ops->clear_request_commit(req, cinfo);
        return true;
 }
 
@@ -488,21 +537,31 @@ static inline int
 pnfs_scan_commit_lists(struct inode *inode, struct nfs_commit_info *cinfo,
                       int max)
 {
-       if (cinfo->ds == NULL || cinfo->ds->nwritten == 0)
+       struct pnfs_ds_commit_info *fl_cinfo = cinfo->ds;
+
+       if (!fl_cinfo || fl_cinfo->nwritten == 0)
                return 0;
-       else
-               return NFS_SERVER(inode)->pnfs_curr_ld->scan_commit_lists(cinfo, max);
+       return fl_cinfo->ops->scan_commit_lists(cinfo, max);
+}
+
+static inline void
+pnfs_recover_commit_reqs(struct list_head *head, struct nfs_commit_info *cinfo)
+{
+       struct pnfs_ds_commit_info *fl_cinfo = cinfo->ds;
+
+       if (fl_cinfo && fl_cinfo->nwritten != 0)
+               fl_cinfo->ops->recover_commit_reqs(head, cinfo);
 }
 
 static inline struct nfs_page *
 pnfs_search_commit_reqs(struct inode *inode, struct nfs_commit_info *cinfo,
                        struct page *page)
 {
-       struct pnfs_layoutdriver_type *ld = NFS_SERVER(inode)->pnfs_curr_ld;
+       struct pnfs_ds_commit_info *fl_cinfo = cinfo->ds;
 
-       if (ld == NULL || ld->search_commit_reqs == NULL)
+       if (!fl_cinfo->ops || !fl_cinfo->ops->search_commit_reqs)
                return NULL;
-       return ld->search_commit_reqs(cinfo, page);
+       return fl_cinfo->ops->search_commit_reqs(cinfo, page);
 }
 
 /* Should the pNFS client commit and return the layout upon a setattr */
@@ -750,6 +809,21 @@ pnfs_get_ds_info(struct inode *inode)
        return NULL;
 }
 
+static inline void
+pnfs_init_ds_commit_info_ops(struct pnfs_ds_commit_info *fl_cinfo, struct inode *inode)
+{
+}
+
+static inline void
+pnfs_init_ds_commit_info(struct pnfs_ds_commit_info *fl_cinfo)
+{
+}
+
+static inline void
+pnfs_release_ds_info(struct pnfs_ds_commit_info *fl_cinfo, struct inode *inode)
+{
+}
+
 static inline bool
 pnfs_mark_request_commit(struct nfs_page *req, struct pnfs_layout_segment *lseg,
                         struct nfs_commit_info *cinfo, u32 ds_commit_idx)
@@ -770,6 +844,11 @@ pnfs_scan_commit_lists(struct inode *inode, struct nfs_commit_info *cinfo,
        return 0;
 }
 
+static inline void
+pnfs_recover_commit_reqs(struct list_head *head, struct nfs_commit_info *cinfo)
+{
+}
+
 static inline struct nfs_page *
 pnfs_search_commit_reqs(struct inode *inode, struct nfs_commit_info *cinfo,
                        struct page *page)
This page took 0.045323 seconds and 4 git commands to generate.