File Index
Files and directories
Sign in
FILE

nfs_page.h

File preview with syntax highlighting.

linux-6.19.14/include/linux/nfs_page.h C
  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 */
 25enum {
 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
 42struct nfs_inode;
 43struct 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
 62struct nfs_pgio_mirror;
 63struct nfs_pageio_descriptor;
 64struct 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
 77struct 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
 88struct 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
 97struct 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
125extern struct nfs_page *nfs_page_create_from_page(struct nfs_open_context *ctx,
126						  struct page *page,
127						  unsigned int pgbase,
128						  loff_t offset,
129						  unsigned int count);
130extern struct nfs_page *nfs_page_create_from_folio(struct nfs_open_context *ctx,
131						   struct folio *folio,
132						   unsigned int offset,
133						   unsigned int count);
134extern	void nfs_release_request(struct nfs_page *);
135
136
137extern	void nfs_pageio_init(struct nfs_pageio_descriptor *desc,
138			     struct inode *inode,
139			     const struct nfs_pageio_ops *pg_ops,
140			     const struct nfs_pgio_completion_ops *compl_ops,
141			     const struct nfs_rw_ops *rw_ops,
142			     size_t bsize,
143			     int how);
144extern	int nfs_pageio_add_request(struct nfs_pageio_descriptor *,
145				   struct nfs_page *);
146extern  int nfs_pageio_resend(struct nfs_pageio_descriptor *,
147			      struct nfs_pgio_header *);
148extern	void nfs_pageio_complete(struct nfs_pageio_descriptor *desc);
149extern	void nfs_pageio_cond_complete(struct nfs_pageio_descriptor *, pgoff_t);
150extern size_t nfs_generic_pg_test(struct nfs_pageio_descriptor *desc,
151				struct nfs_page *prev,
152				struct nfs_page *req);
153extern	void nfs_unlock_request(struct nfs_page *req);
154extern	void nfs_unlock_and_release_request(struct nfs_page *);
155extern void nfs_join_page_group(struct nfs_page *head,
156				struct nfs_commit_info *cinfo,
157				struct inode *inode);
158extern int nfs_page_group_lock(struct nfs_page *);
159extern void nfs_page_group_unlock(struct nfs_page *);
160extern bool nfs_page_group_sync_on_bit(struct nfs_page *, unsigned int);
161extern bool nfs_page_group_sync_on_bit_locked(struct nfs_page *, unsigned int);
162extern	int nfs_page_set_headlock(struct nfs_page *req);
163extern void nfs_page_clear_headlock(struct nfs_page *req);
164extern bool nfs_async_iocounter_wait(struct rpc_task *, struct nfs_lock_context *);
165
166/**
167 * nfs_page_to_folio - Retrieve a struct folio for the request
168 * @req: pointer to a struct nfs_page
169 *
170 * If a folio was assigned to @req, then return it, otherwise return NULL.
171 */
172static inline struct folio *nfs_page_to_folio(const struct nfs_page *req)
173{
174	if (test_bit(PG_FOLIO, &req->wb_flags))
175		return req->wb_folio;
176	return NULL;
177}
178
179/**
180 * nfs_page_to_page - Retrieve a struct page for the request
181 * @req: pointer to a struct nfs_page
182 * @pgbase: folio byte offset
183 *
184 * Return the page containing the byte that is at offset @pgbase relative
185 * to the start of the folio.
186 * Note: The request starts at offset @req->wb_pgbase.
187 */
188static inline struct page *nfs_page_to_page(const struct nfs_page *req,
189					    size_t pgbase)
190{
191	struct folio *folio = nfs_page_to_folio(req);
192
193	if (folio == NULL)
194		return req->wb_page;
195	return folio_page(folio, pgbase >> PAGE_SHIFT);
196}
197
198/**
199 * nfs_page_to_inode - Retrieve an inode for the request
200 * @req: pointer to a struct nfs_page
201 */
202static inline struct inode *nfs_page_to_inode(const struct nfs_page *req)
203{
204	struct folio *folio = nfs_page_to_folio(req);
205
206	if (folio == NULL)
207		return req->wb_page->mapping->host;
208	return folio->mapping->host;
209}
210
211/**
212 * nfs_page_max_length - Retrieve the maximum possible length for a request
213 * @req: pointer to a struct nfs_page
214 *
215 * Returns the maximum possible length of a request
216 */
217static inline size_t nfs_page_max_length(const struct nfs_page *req)
218{
219	struct folio *folio = nfs_page_to_folio(req);
220
221	if (folio == NULL)
222		return PAGE_SIZE;
223	return folio_size(folio);
224}
225
226/*
227 * Lock the page of an asynchronous request
228 */
229static inline int
230nfs_lock_request(struct nfs_page *req)
231{
232	return !test_and_set_bit(PG_BUSY, &req->wb_flags);
233}
234
235/**
236 * nfs_list_add_request - Insert a request into a list
237 * @req: request
238 * @head: head of list into which to insert the request.
239 */
240static inline void
241nfs_list_add_request(struct nfs_page *req, struct list_head *head)
242{
243	list_add_tail(&req->wb_list, head);
244}
245
246/**
247 * nfs_list_move_request - Move a request to a new list
248 * @req: request
249 * @head: head of list into which to insert the request.
250 */
251static inline void
252nfs_list_move_request(struct nfs_page *req, struct list_head *head)
253{
254	list_move_tail(&req->wb_list, head);
255}
256
257/**
258 * nfs_list_remove_request - Remove a request from its wb_list
259 * @req: request
260 */
261static inline void
262nfs_list_remove_request(struct nfs_page *req)
263{
264	if (list_empty(&req->wb_list))
265		return;
266	list_del_init(&req->wb_list);
267}
268
269static inline struct nfs_page *
270nfs_list_entry(struct list_head *head)
271{
272	return list_entry(head, struct nfs_page, wb_list);
273}
274
275static inline loff_t req_offset(const struct nfs_page *req)
276{
277	return (((loff_t)req->wb_index) << PAGE_SHIFT) + req->wb_offset;
278}
279
280static inline struct nfs_open_context *
281nfs_req_openctx(struct nfs_page *req)
282{
283	return req->wb_lock_context->open_context;
284}
285
286#endif /* _LINUX_NFS_PAGE_H */
~/ Read-only file preview.