Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 /*
0003  * linux/include/linux/nfs_page.h
0004  *
0005  * Copyright (C) 2000 Trond Myklebust
0006  *
0007  * NFS page cache wrapper.
0008  */
0009 
0010 #ifndef _LINUX_NFS_PAGE_H
0011 #define _LINUX_NFS_PAGE_H
0012 
0013 
0014 #include <linux/list.h>
0015 #include <linux/pagemap.h>
0016 #include <linux/wait.h>
0017 #include <linux/sunrpc/auth.h>
0018 #include <linux/nfs_xdr.h>
0019 
0020 #include <linux/kref.h>
0021 
0022 /*
0023  * Valid flags for a dirty buffer
0024  */
0025 enum {
0026     PG_BUSY = 0,        /* nfs_{un}lock_request */
0027     PG_MAPPED,      /* page private set for buffered io */
0028     PG_CLEAN,       /* write succeeded */
0029     PG_COMMIT_TO_DS,    /* used by pnfs layouts */
0030     PG_INODE_REF,       /* extra ref held by inode when in writeback */
0031     PG_HEADLOCK,        /* page group lock of wb_head */
0032     PG_TEARDOWN,        /* page group sync for destroy */
0033     PG_UNLOCKPAGE,      /* page group sync bit in read path */
0034     PG_UPTODATE,        /* page group sync bit in read path */
0035     PG_WB_END,      /* page group sync bit in write path */
0036     PG_REMOVE,      /* page group sync bit in write path */
0037     PG_CONTENDED1,      /* Is someone waiting for a lock? */
0038     PG_CONTENDED2,      /* Is someone waiting for a lock? */
0039 };
0040 
0041 struct nfs_inode;
0042 struct nfs_page {
0043     struct list_head    wb_list;    /* Defines state of page: */
0044     struct page     *wb_page;   /* page to read in/write out */
0045     struct nfs_lock_context *wb_lock_context;   /* lock context info */
0046     pgoff_t         wb_index;   /* Offset >> PAGE_SHIFT */
0047     unsigned int        wb_offset,  /* Offset & ~PAGE_MASK */
0048                 wb_pgbase,  /* Start of page data */
0049                 wb_bytes;   /* Length of request */
0050     struct kref     wb_kref;    /* reference count */
0051     unsigned long       wb_flags;
0052     struct nfs_write_verifier   wb_verf;    /* Commit cookie */
0053     struct nfs_page     *wb_this_page;  /* list of reqs for this page */
0054     struct nfs_page     *wb_head;       /* head pointer for req list */
0055     unsigned short      wb_nio;     /* Number of I/O attempts */
0056 };
0057 
0058 struct nfs_pgio_mirror;
0059 struct nfs_pageio_descriptor;
0060 struct nfs_pageio_ops {
0061     void    (*pg_init)(struct nfs_pageio_descriptor *, struct nfs_page *);
0062     size_t  (*pg_test)(struct nfs_pageio_descriptor *, struct nfs_page *,
0063                struct nfs_page *);
0064     int (*pg_doio)(struct nfs_pageio_descriptor *);
0065     unsigned int    (*pg_get_mirror_count)(struct nfs_pageio_descriptor *,
0066                        struct nfs_page *);
0067     void    (*pg_cleanup)(struct nfs_pageio_descriptor *);
0068     struct nfs_pgio_mirror *
0069         (*pg_get_mirror)(struct nfs_pageio_descriptor *, u32);
0070     u32 (*pg_set_mirror)(struct nfs_pageio_descriptor *, u32);
0071 };
0072 
0073 struct nfs_rw_ops {
0074     struct nfs_pgio_header *(*rw_alloc_header)(void);
0075     void (*rw_free_header)(struct nfs_pgio_header *);
0076     int  (*rw_done)(struct rpc_task *, struct nfs_pgio_header *,
0077             struct inode *);
0078     void (*rw_result)(struct rpc_task *, struct nfs_pgio_header *);
0079     void (*rw_initiate)(struct nfs_pgio_header *, struct rpc_message *,
0080                 const struct nfs_rpc_ops *,
0081                 struct rpc_task_setup *, int);
0082 };
0083 
0084 struct nfs_pgio_mirror {
0085     struct list_head    pg_list;
0086     unsigned long       pg_bytes_written;
0087     size_t          pg_count;
0088     size_t          pg_bsize;
0089     unsigned int        pg_base;
0090     unsigned char       pg_recoalesce : 1;
0091 };
0092 
0093 struct nfs_pageio_descriptor {
0094     struct inode        *pg_inode;
0095     const struct nfs_pageio_ops *pg_ops;
0096     const struct nfs_rw_ops *pg_rw_ops;
0097     int             pg_ioflags;
0098     int         pg_error;
0099     const struct rpc_call_ops *pg_rpc_callops;
0100     const struct nfs_pgio_completion_ops *pg_completion_ops;
0101     struct pnfs_layout_segment *pg_lseg;
0102     struct nfs_io_completion *pg_io_completion;
0103     struct nfs_direct_req   *pg_dreq;
0104     unsigned int        pg_bsize;   /* default bsize for mirrors */
0105 
0106     u32         pg_mirror_count;
0107     struct nfs_pgio_mirror  *pg_mirrors;
0108     struct nfs_pgio_mirror  pg_mirrors_static[1];
0109     struct nfs_pgio_mirror  *pg_mirrors_dynamic;
0110     u32         pg_mirror_idx;  /* current mirror */
0111     unsigned short      pg_maxretrans;
0112     unsigned char       pg_moreio : 1;
0113 };
0114 
0115 /* arbitrarily selected limit to number of mirrors */
0116 #define NFS_PAGEIO_DESCRIPTOR_MIRROR_MAX 16
0117 
0118 #define NFS_WBACK_BUSY(req) (test_bit(PG_BUSY,&(req)->wb_flags))
0119 
0120 extern  struct nfs_page *nfs_create_request(struct nfs_open_context *ctx,
0121                         struct page *page,
0122                         unsigned int offset,
0123                         unsigned int count);
0124 extern  void nfs_release_request(struct nfs_page *);
0125 
0126 
0127 extern  void nfs_pageio_init(struct nfs_pageio_descriptor *desc,
0128                  struct inode *inode,
0129                  const struct nfs_pageio_ops *pg_ops,
0130                  const struct nfs_pgio_completion_ops *compl_ops,
0131                  const struct nfs_rw_ops *rw_ops,
0132                  size_t bsize,
0133                  int how);
0134 extern  int nfs_pageio_add_request(struct nfs_pageio_descriptor *,
0135                    struct nfs_page *);
0136 extern  int nfs_pageio_resend(struct nfs_pageio_descriptor *,
0137                   struct nfs_pgio_header *);
0138 extern  void nfs_pageio_complete(struct nfs_pageio_descriptor *desc);
0139 extern  void nfs_pageio_cond_complete(struct nfs_pageio_descriptor *, pgoff_t);
0140 extern size_t nfs_generic_pg_test(struct nfs_pageio_descriptor *desc,
0141                 struct nfs_page *prev,
0142                 struct nfs_page *req);
0143 extern  int nfs_wait_on_request(struct nfs_page *);
0144 extern  void nfs_unlock_request(struct nfs_page *req);
0145 extern  void nfs_unlock_and_release_request(struct nfs_page *);
0146 extern  struct nfs_page *nfs_page_group_lock_head(struct nfs_page *req);
0147 extern  int nfs_page_group_lock_subrequests(struct nfs_page *head);
0148 extern  void nfs_join_page_group(struct nfs_page *head, struct inode *inode);
0149 extern int nfs_page_group_lock(struct nfs_page *);
0150 extern void nfs_page_group_unlock(struct nfs_page *);
0151 extern bool nfs_page_group_sync_on_bit(struct nfs_page *, unsigned int);
0152 extern  int nfs_page_set_headlock(struct nfs_page *req);
0153 extern void nfs_page_clear_headlock(struct nfs_page *req);
0154 extern bool nfs_async_iocounter_wait(struct rpc_task *, struct nfs_lock_context *);
0155 
0156 /*
0157  * Lock the page of an asynchronous request
0158  */
0159 static inline int
0160 nfs_lock_request(struct nfs_page *req)
0161 {
0162     return !test_and_set_bit(PG_BUSY, &req->wb_flags);
0163 }
0164 
0165 /**
0166  * nfs_list_add_request - Insert a request into a list
0167  * @req: request
0168  * @head: head of list into which to insert the request.
0169  */
0170 static inline void
0171 nfs_list_add_request(struct nfs_page *req, struct list_head *head)
0172 {
0173     list_add_tail(&req->wb_list, head);
0174 }
0175 
0176 /**
0177  * nfs_list_move_request - Move a request to a new list
0178  * @req: request
0179  * @head: head of list into which to insert the request.
0180  */
0181 static inline void
0182 nfs_list_move_request(struct nfs_page *req, struct list_head *head)
0183 {
0184     list_move_tail(&req->wb_list, head);
0185 }
0186 
0187 /**
0188  * nfs_list_remove_request - Remove a request from its wb_list
0189  * @req: request
0190  */
0191 static inline void
0192 nfs_list_remove_request(struct nfs_page *req)
0193 {
0194     if (list_empty(&req->wb_list))
0195         return;
0196     list_del_init(&req->wb_list);
0197 }
0198 
0199 static inline struct nfs_page *
0200 nfs_list_entry(struct list_head *head)
0201 {
0202     return list_entry(head, struct nfs_page, wb_list);
0203 }
0204 
0205 static inline loff_t req_offset(const struct nfs_page *req)
0206 {
0207     return (((loff_t)req->wb_index) << PAGE_SHIFT) + req->wb_offset;
0208 }
0209 
0210 static inline struct nfs_open_context *
0211 nfs_req_openctx(struct nfs_page *req)
0212 {
0213     return req->wb_lock_context->open_context;
0214 }
0215 
0216 #endif /* _LINUX_NFS_PAGE_H */