Merge tag '6.3-rc6-smb311-client-negcontext-fix' of git://git.samba.org/sfrench/cifs-2.6
[linux-2.6-microblaze.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         unsigned int            pg_bsize;       /* default bsize for mirrors */
109
110         u32                     pg_mirror_count;
111         struct nfs_pgio_mirror  *pg_mirrors;
112         struct nfs_pgio_mirror  pg_mirrors_static[1];
113         struct nfs_pgio_mirror  *pg_mirrors_dynamic;
114         u32                     pg_mirror_idx;  /* current mirror */
115         unsigned short          pg_maxretrans;
116         unsigned char           pg_moreio : 1;
117 };
118
119 /* arbitrarily selected limit to number of mirrors */
120 #define NFS_PAGEIO_DESCRIPTOR_MIRROR_MAX 16
121
122 #define NFS_WBACK_BUSY(req)     (test_bit(PG_BUSY,&(req)->wb_flags))
123
124 extern struct nfs_page *nfs_page_create_from_page(struct nfs_open_context *ctx,
125                                                   struct page *page,
126                                                   unsigned int pgbase,
127                                                   loff_t offset,
128                                                   unsigned int count);
129 extern struct nfs_page *nfs_page_create_from_folio(struct nfs_open_context *ctx,
130                                                    struct folio *folio,
131                                                    unsigned int offset,
132                                                    unsigned int count);
133 extern  void nfs_release_request(struct nfs_page *);
134
135
136 extern  void nfs_pageio_init(struct nfs_pageio_descriptor *desc,
137                              struct inode *inode,
138                              const struct nfs_pageio_ops *pg_ops,
139                              const struct nfs_pgio_completion_ops *compl_ops,
140                              const struct nfs_rw_ops *rw_ops,
141                              size_t bsize,
142                              int how);
143 extern  int nfs_pageio_add_request(struct nfs_pageio_descriptor *,
144                                    struct nfs_page *);
145 extern  int nfs_pageio_resend(struct nfs_pageio_descriptor *,
146                               struct nfs_pgio_header *);
147 extern  void nfs_pageio_complete(struct nfs_pageio_descriptor *desc);
148 extern  void nfs_pageio_cond_complete(struct nfs_pageio_descriptor *, pgoff_t);
149 extern size_t nfs_generic_pg_test(struct nfs_pageio_descriptor *desc,
150                                 struct nfs_page *prev,
151                                 struct nfs_page *req);
152 extern  int nfs_wait_on_request(struct nfs_page *);
153 extern  void nfs_unlock_request(struct nfs_page *req);
154 extern  void nfs_unlock_and_release_request(struct nfs_page *);
155 extern  struct nfs_page *nfs_page_group_lock_head(struct nfs_page *req);
156 extern  int nfs_page_group_lock_subrequests(struct nfs_page *head);
157 extern  void nfs_join_page_group(struct nfs_page *head, struct inode *inode);
158 extern int nfs_page_group_lock(struct nfs_page *);
159 extern void nfs_page_group_unlock(struct nfs_page *);
160 extern bool nfs_page_group_sync_on_bit(struct nfs_page *, unsigned int);
161 extern  int nfs_page_set_headlock(struct nfs_page *req);
162 extern void nfs_page_clear_headlock(struct nfs_page *req);
163 extern bool nfs_async_iocounter_wait(struct rpc_task *, struct nfs_lock_context *);
164
165 /**
166  * nfs_page_to_folio - Retrieve a struct folio for the request
167  * @req: pointer to a struct nfs_page
168  *
169  * If a folio was assigned to @req, then return it, otherwise return NULL.
170  */
171 static inline struct folio *nfs_page_to_folio(const struct nfs_page *req)
172 {
173         if (test_bit(PG_FOLIO, &req->wb_flags))
174                 return req->wb_folio;
175         return NULL;
176 }
177
178 /**
179  * nfs_page_to_page - Retrieve a struct page for the request
180  * @req: pointer to a struct nfs_page
181  * @pgbase: folio byte offset
182  *
183  * Return the page containing the byte that is at offset @pgbase relative
184  * to the start of the folio.
185  * Note: The request starts at offset @req->wb_pgbase.
186  */
187 static inline struct page *nfs_page_to_page(const struct nfs_page *req,
188                                             size_t pgbase)
189 {
190         struct folio *folio = nfs_page_to_folio(req);
191
192         if (folio == NULL)
193                 return req->wb_page;
194         return folio_page(folio, pgbase >> PAGE_SHIFT);
195 }
196
197 /**
198  * nfs_page_to_inode - Retrieve an inode for the request
199  * @req: pointer to a struct nfs_page
200  */
201 static inline struct inode *nfs_page_to_inode(const struct nfs_page *req)
202 {
203         struct folio *folio = nfs_page_to_folio(req);
204
205         if (folio == NULL)
206                 return page_file_mapping(req->wb_page)->host;
207         return folio_file_mapping(folio)->host;
208 }
209
210 /**
211  * nfs_page_max_length - Retrieve the maximum possible length for a request
212  * @req: pointer to a struct nfs_page
213  *
214  * Returns the maximum possible length of a request
215  */
216 static inline size_t nfs_page_max_length(const struct nfs_page *req)
217 {
218         struct folio *folio = nfs_page_to_folio(req);
219
220         if (folio == NULL)
221                 return PAGE_SIZE;
222         return folio_size(folio);
223 }
224
225 /*
226  * Lock the page of an asynchronous request
227  */
228 static inline int
229 nfs_lock_request(struct nfs_page *req)
230 {
231         return !test_and_set_bit(PG_BUSY, &req->wb_flags);
232 }
233
234 /**
235  * nfs_list_add_request - Insert a request into a list
236  * @req: request
237  * @head: head of list into which to insert the request.
238  */
239 static inline void
240 nfs_list_add_request(struct nfs_page *req, struct list_head *head)
241 {
242         list_add_tail(&req->wb_list, head);
243 }
244
245 /**
246  * nfs_list_move_request - Move a request to a new list
247  * @req: request
248  * @head: head of list into which to insert the request.
249  */
250 static inline void
251 nfs_list_move_request(struct nfs_page *req, struct list_head *head)
252 {
253         list_move_tail(&req->wb_list, head);
254 }
255
256 /**
257  * nfs_list_remove_request - Remove a request from its wb_list
258  * @req: request
259  */
260 static inline void
261 nfs_list_remove_request(struct nfs_page *req)
262 {
263         if (list_empty(&req->wb_list))
264                 return;
265         list_del_init(&req->wb_list);
266 }
267
268 static inline struct nfs_page *
269 nfs_list_entry(struct list_head *head)
270 {
271         return list_entry(head, struct nfs_page, wb_list);
272 }
273
274 static inline loff_t req_offset(const struct nfs_page *req)
275 {
276         return (((loff_t)req->wb_index) << PAGE_SHIFT) + req->wb_offset;
277 }
278
279 static inline struct nfs_open_context *
280 nfs_req_openctx(struct nfs_page *req)
281 {
282         return req->wb_lock_context->open_context;
283 }
284
285 #endif /* _LINUX_NFS_PAGE_H */