~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/include/linux/nfs_page.h

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  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  void nfs_unlock_request(struct nfs_page *req);
156 extern  void nfs_unlock_and_release_request(struct nfs_page *);
157 extern void nfs_join_page_group(struct nfs_page *head,
158                                 struct nfs_commit_info *cinfo,
159                                 struct inode *inode);
160 extern int nfs_page_group_lock(struct nfs_page *);
161 extern void nfs_page_group_unlock(struct nfs_page *);
162 extern bool nfs_page_group_sync_on_bit(struct nfs_page *, unsigned int);
163 extern  int nfs_page_set_headlock(struct nfs_page *req);
164 extern void nfs_page_clear_headlock(struct nfs_page *req);
165 extern bool nfs_async_iocounter_wait(struct rpc_task *, struct nfs_lock_context *);
166 
167 /**
168  * nfs_page_to_folio - Retrieve a struct folio for the request
169  * @req: pointer to a struct nfs_page
170  *
171  * If a folio was assigned to @req, then return it, otherwise return NULL.
172  */
173 static inline struct folio *nfs_page_to_folio(const struct nfs_page *req)
174 {
175         if (test_bit(PG_FOLIO, &req->wb_flags))
176                 return req->wb_folio;
177         return NULL;
178 }
179 
180 /**
181  * nfs_page_to_page - Retrieve a struct page for the request
182  * @req: pointer to a struct nfs_page
183  * @pgbase: folio byte offset
184  *
185  * Return the page containing the byte that is at offset @pgbase relative
186  * to the start of the folio.
187  * Note: The request starts at offset @req->wb_pgbase.
188  */
189 static inline struct page *nfs_page_to_page(const struct nfs_page *req,
190                                             size_t pgbase)
191 {
192         struct folio *folio = nfs_page_to_folio(req);
193 
194         if (folio == NULL)
195                 return req->wb_page;
196         return folio_page(folio, pgbase >> PAGE_SHIFT);
197 }
198 
199 /**
200  * nfs_page_to_inode - Retrieve an inode for the request
201  * @req: pointer to a struct nfs_page
202  */
203 static inline struct inode *nfs_page_to_inode(const struct nfs_page *req)
204 {
205         struct folio *folio = nfs_page_to_folio(req);
206 
207         if (folio == NULL)
208                 return req->wb_page->mapping->host;
209         return folio->mapping->host;
210 }
211 
212 /**
213  * nfs_page_max_length - Retrieve the maximum possible length for a request
214  * @req: pointer to a struct nfs_page
215  *
216  * Returns the maximum possible length of a request
217  */
218 static inline size_t nfs_page_max_length(const struct nfs_page *req)
219 {
220         struct folio *folio = nfs_page_to_folio(req);
221 
222         if (folio == NULL)
223                 return PAGE_SIZE;
224         return folio_size(folio);
225 }
226 
227 /*
228  * Lock the page of an asynchronous request
229  */
230 static inline int
231 nfs_lock_request(struct nfs_page *req)
232 {
233         return !test_and_set_bit(PG_BUSY, &req->wb_flags);
234 }
235 
236 /**
237  * nfs_list_add_request - Insert a request into a list
238  * @req: request
239  * @head: head of list into which to insert the request.
240  */
241 static inline void
242 nfs_list_add_request(struct nfs_page *req, struct list_head *head)
243 {
244         list_add_tail(&req->wb_list, head);
245 }
246 
247 /**
248  * nfs_list_move_request - Move a request to a new list
249  * @req: request
250  * @head: head of list into which to insert the request.
251  */
252 static inline void
253 nfs_list_move_request(struct nfs_page *req, struct list_head *head)
254 {
255         list_move_tail(&req->wb_list, head);
256 }
257 
258 /**
259  * nfs_list_remove_request - Remove a request from its wb_list
260  * @req: request
261  */
262 static inline void
263 nfs_list_remove_request(struct nfs_page *req)
264 {
265         if (list_empty(&req->wb_list))
266                 return;
267         list_del_init(&req->wb_list);
268 }
269 
270 static inline struct nfs_page *
271 nfs_list_entry(struct list_head *head)
272 {
273         return list_entry(head, struct nfs_page, wb_list);
274 }
275 
276 static inline loff_t req_offset(const struct nfs_page *req)
277 {
278         return (((loff_t)req->wb_index) << PAGE_SHIFT) + req->wb_offset;
279 }
280 
281 static inline struct nfs_open_context *
282 nfs_req_openctx(struct nfs_page *req)
283 {
284         return req->wb_lock_context->open_context;
285 }
286 
287 #endif /* _LINUX_NFS_PAGE_H */
288 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php