Merge tag 'powerpc-6.6-6' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc...
[platform/kernel/linux-starfive.git] / include / linux / nfs_page.h
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * linux/include/linux/nfs_page.h
4  *
5  * Copyright (C) 2000 Trond Myklebust
6  *
7  * NFS page cache wrapper.
8  */
9
10 #ifndef _LINUX_NFS_PAGE_H
11 #define _LINUX_NFS_PAGE_H
12
13
14 #include <linux/list.h>
15 #include <linux/pagemap.h>
16 #include <linux/wait.h>
17 #include <linux/sunrpc/auth.h>
18 #include <linux/nfs_xdr.h>
19
20 #include <linux/kref.h>
21
22 /*
23  * Valid flags for a dirty buffer
24  */
25 enum {
26         PG_BUSY = 0,            /* nfs_{un}lock_request */
27         PG_MAPPED,              /* page private set for buffered io */
28         PG_FOLIO,               /* Tracking a folio (unset for O_DIRECT) */
29         PG_CLEAN,               /* write succeeded */
30         PG_COMMIT_TO_DS,        /* used by pnfs layouts */
31         PG_INODE_REF,           /* extra ref held by inode when in writeback */
32         PG_HEADLOCK,            /* page group lock of wb_head */
33         PG_TEARDOWN,            /* page group sync for destroy */
34         PG_UNLOCKPAGE,          /* page group sync bit in read path */
35         PG_UPTODATE,            /* page group sync bit in read path */
36         PG_WB_END,              /* page group sync bit in write path */
37         PG_REMOVE,              /* page group sync bit in write path */
38         PG_CONTENDED1,          /* Is someone waiting for a lock? */
39         PG_CONTENDED2,          /* Is someone waiting for a lock? */
40 };
41
42 struct nfs_inode;
43 struct nfs_page {
44         struct list_head        wb_list;        /* Defines state of page: */
45         union {
46                 struct page     *wb_page;       /* page to read in/write out */
47                 struct folio    *wb_folio;
48         };
49         struct nfs_lock_context *wb_lock_context;       /* lock context info */
50         pgoff_t                 wb_index;       /* Offset >> PAGE_SHIFT */
51         unsigned int            wb_offset,      /* Offset & ~PAGE_MASK */
52                                 wb_pgbase,      /* Start of page data */
53                                 wb_bytes;       /* Length of request */
54         struct kref             wb_kref;        /* reference count */
55         unsigned long           wb_flags;
56         struct nfs_write_verifier       wb_verf;        /* Commit cookie */
57         struct nfs_page         *wb_this_page;  /* list of reqs for this page */
58         struct nfs_page         *wb_head;       /* head pointer for req list */
59         unsigned short          wb_nio;         /* Number of I/O attempts */
60 };
61
62 struct nfs_pgio_mirror;
63 struct nfs_pageio_descriptor;
64 struct nfs_pageio_ops {
65         void    (*pg_init)(struct nfs_pageio_descriptor *, struct nfs_page *);
66         size_t  (*pg_test)(struct nfs_pageio_descriptor *, struct nfs_page *,
67                            struct nfs_page *);
68         int     (*pg_doio)(struct nfs_pageio_descriptor *);
69         unsigned int    (*pg_get_mirror_count)(struct nfs_pageio_descriptor *,
70                                        struct nfs_page *);
71         void    (*pg_cleanup)(struct nfs_pageio_descriptor *);
72         struct nfs_pgio_mirror *
73                 (*pg_get_mirror)(struct nfs_pageio_descriptor *, u32);
74         u32     (*pg_set_mirror)(struct nfs_pageio_descriptor *, u32);
75 };
76
77 struct nfs_rw_ops {
78         struct nfs_pgio_header *(*rw_alloc_header)(void);
79         void (*rw_free_header)(struct nfs_pgio_header *);
80         int  (*rw_done)(struct rpc_task *, struct nfs_pgio_header *,
81                         struct inode *);
82         void (*rw_result)(struct rpc_task *, struct nfs_pgio_header *);
83         void (*rw_initiate)(struct nfs_pgio_header *, struct rpc_message *,
84                             const struct nfs_rpc_ops *,
85                             struct rpc_task_setup *, int);
86 };
87
88 struct nfs_pgio_mirror {
89         struct list_head        pg_list;
90         unsigned long           pg_bytes_written;
91         size_t                  pg_count;
92         size_t                  pg_bsize;
93         unsigned int            pg_base;
94         unsigned char           pg_recoalesce : 1;
95 };
96
97 struct nfs_pageio_descriptor {
98         struct inode            *pg_inode;
99         const struct nfs_pageio_ops *pg_ops;
100         const struct nfs_rw_ops *pg_rw_ops;
101         int                     pg_ioflags;
102         int                     pg_error;
103         const struct rpc_call_ops *pg_rpc_callops;
104         const struct nfs_pgio_completion_ops *pg_completion_ops;
105         struct pnfs_layout_segment *pg_lseg;
106         struct nfs_io_completion *pg_io_completion;
107         struct nfs_direct_req   *pg_dreq;
108 #ifdef CONFIG_NFS_FSCACHE
109         void                    *pg_netfs;
110 #endif
111         unsigned int            pg_bsize;       /* default bsize for mirrors */
112
113         u32                     pg_mirror_count;
114         struct nfs_pgio_mirror  *pg_mirrors;
115         struct nfs_pgio_mirror  pg_mirrors_static[1];
116         struct nfs_pgio_mirror  *pg_mirrors_dynamic;
117         u32                     pg_mirror_idx;  /* current mirror */
118         unsigned short          pg_maxretrans;
119         unsigned char           pg_moreio : 1;
120 };
121
122 /* arbitrarily selected limit to number of mirrors */
123 #define NFS_PAGEIO_DESCRIPTOR_MIRROR_MAX 16
124
125 #define NFS_WBACK_BUSY(req)     (test_bit(PG_BUSY,&(req)->wb_flags))
126
127 extern struct nfs_page *nfs_page_create_from_page(struct nfs_open_context *ctx,
128                                                   struct page *page,
129                                                   unsigned int pgbase,
130                                                   loff_t offset,
131                                                   unsigned int count);
132 extern struct nfs_page *nfs_page_create_from_folio(struct nfs_open_context *ctx,
133                                                    struct folio *folio,
134                                                    unsigned int offset,
135                                                    unsigned int count);
136 extern  void nfs_release_request(struct nfs_page *);
137
138
139 extern  void nfs_pageio_init(struct nfs_pageio_descriptor *desc,
140                              struct inode *inode,
141                              const struct nfs_pageio_ops *pg_ops,
142                              const struct nfs_pgio_completion_ops *compl_ops,
143                              const struct nfs_rw_ops *rw_ops,
144                              size_t bsize,
145                              int how);
146 extern  int nfs_pageio_add_request(struct nfs_pageio_descriptor *,
147                                    struct nfs_page *);
148 extern  int nfs_pageio_resend(struct nfs_pageio_descriptor *,
149                               struct nfs_pgio_header *);
150 extern  void nfs_pageio_complete(struct nfs_pageio_descriptor *desc);
151 extern  void nfs_pageio_cond_complete(struct nfs_pageio_descriptor *, pgoff_t);
152 extern size_t nfs_generic_pg_test(struct nfs_pageio_descriptor *desc,
153                                 struct nfs_page *prev,
154                                 struct nfs_page *req);
155 extern  int nfs_wait_on_request(struct nfs_page *);
156 extern  void nfs_unlock_request(struct nfs_page *req);
157 extern  void nfs_unlock_and_release_request(struct nfs_page *);
158 extern  struct nfs_page *nfs_page_group_lock_head(struct nfs_page *req);
159 extern  int nfs_page_group_lock_subrequests(struct nfs_page *head);
160 extern void nfs_join_page_group(struct nfs_page *head,
161                                 struct nfs_commit_info *cinfo,
162                                 struct inode *inode);
163 extern int nfs_page_group_lock(struct nfs_page *);
164 extern void nfs_page_group_unlock(struct nfs_page *);
165 extern bool nfs_page_group_sync_on_bit(struct nfs_page *, unsigned int);
166 extern  int nfs_page_set_headlock(struct nfs_page *req);
167 extern void nfs_page_clear_headlock(struct nfs_page *req);
168 extern bool nfs_async_iocounter_wait(struct rpc_task *, struct nfs_lock_context *);
169
170 /**
171  * nfs_page_to_folio - Retrieve a struct folio for the request
172  * @req: pointer to a struct nfs_page
173  *
174  * If a folio was assigned to @req, then return it, otherwise return NULL.
175  */
176 static inline struct folio *nfs_page_to_folio(const struct nfs_page *req)
177 {
178         if (test_bit(PG_FOLIO, &req->wb_flags))
179                 return req->wb_folio;
180         return NULL;
181 }
182
183 /**
184  * nfs_page_to_page - Retrieve a struct page for the request
185  * @req: pointer to a struct nfs_page
186  * @pgbase: folio byte offset
187  *
188  * Return the page containing the byte that is at offset @pgbase relative
189  * to the start of the folio.
190  * Note: The request starts at offset @req->wb_pgbase.
191  */
192 static inline struct page *nfs_page_to_page(const struct nfs_page *req,
193                                             size_t pgbase)
194 {
195         struct folio *folio = nfs_page_to_folio(req);
196
197         if (folio == NULL)
198                 return req->wb_page;
199         return folio_page(folio, pgbase >> PAGE_SHIFT);
200 }
201
202 /**
203  * nfs_page_to_inode - Retrieve an inode for the request
204  * @req: pointer to a struct nfs_page
205  */
206 static inline struct inode *nfs_page_to_inode(const struct nfs_page *req)
207 {
208         struct folio *folio = nfs_page_to_folio(req);
209
210         if (folio == NULL)
211                 return page_file_mapping(req->wb_page)->host;
212         return folio_file_mapping(folio)->host;
213 }
214
215 /**
216  * nfs_page_max_length - Retrieve the maximum possible length for a request
217  * @req: pointer to a struct nfs_page
218  *
219  * Returns the maximum possible length of a request
220  */
221 static inline size_t nfs_page_max_length(const struct nfs_page *req)
222 {
223         struct folio *folio = nfs_page_to_folio(req);
224
225         if (folio == NULL)
226                 return PAGE_SIZE;
227         return folio_size(folio);
228 }
229
230 /*
231  * Lock the page of an asynchronous request
232  */
233 static inline int
234 nfs_lock_request(struct nfs_page *req)
235 {
236         return !test_and_set_bit(PG_BUSY, &req->wb_flags);
237 }
238
239 /**
240  * nfs_list_add_request - Insert a request into a list
241  * @req: request
242  * @head: head of list into which to insert the request.
243  */
244 static inline void
245 nfs_list_add_request(struct nfs_page *req, struct list_head *head)
246 {
247         list_add_tail(&req->wb_list, head);
248 }
249
250 /**
251  * nfs_list_move_request - Move a request to a new list
252  * @req: request
253  * @head: head of list into which to insert the request.
254  */
255 static inline void
256 nfs_list_move_request(struct nfs_page *req, struct list_head *head)
257 {
258         list_move_tail(&req->wb_list, head);
259 }
260
261 /**
262  * nfs_list_remove_request - Remove a request from its wb_list
263  * @req: request
264  */
265 static inline void
266 nfs_list_remove_request(struct nfs_page *req)
267 {
268         if (list_empty(&req->wb_list))
269                 return;
270         list_del_init(&req->wb_list);
271 }
272
273 static inline struct nfs_page *
274 nfs_list_entry(struct list_head *head)
275 {
276         return list_entry(head, struct nfs_page, wb_list);
277 }
278
279 static inline loff_t req_offset(const struct nfs_page *req)
280 {
281         return (((loff_t)req->wb_index) << PAGE_SHIFT) + req->wb_offset;
282 }
283
284 static inline struct nfs_open_context *
285 nfs_req_openctx(struct nfs_page *req)
286 {
287         return req->wb_lock_context->open_context;
288 }
289
290 #endif /* _LINUX_NFS_PAGE_H */