xref: /OK3568_Linux_fs/kernel/fs/nfs/pnfs.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  *  pNFS client data structures.
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  *  Copyright (c) 2002
5*4882a593Smuzhiyun  *  The Regents of the University of Michigan
6*4882a593Smuzhiyun  *  All Rights Reserved
7*4882a593Smuzhiyun  *
8*4882a593Smuzhiyun  *  Dean Hildebrand <dhildebz@umich.edu>
9*4882a593Smuzhiyun  *
10*4882a593Smuzhiyun  *  Permission is granted to use, copy, create derivative works, and
11*4882a593Smuzhiyun  *  redistribute this software and such derivative works for any purpose,
12*4882a593Smuzhiyun  *  so long as the name of the University of Michigan is not used in
13*4882a593Smuzhiyun  *  any advertising or publicity pertaining to the use or distribution
14*4882a593Smuzhiyun  *  of this software without specific, written prior authorization. If
15*4882a593Smuzhiyun  *  the above copyright notice or any other identification of the
16*4882a593Smuzhiyun  *  University of Michigan is included in any copy of any portion of
17*4882a593Smuzhiyun  *  this software, then the disclaimer below must also be included.
18*4882a593Smuzhiyun  *
19*4882a593Smuzhiyun  *  This software is provided as is, without representation or warranty
20*4882a593Smuzhiyun  *  of any kind either express or implied, including without limitation
21*4882a593Smuzhiyun  *  the implied warranties of merchantability, fitness for a particular
22*4882a593Smuzhiyun  *  purpose, or noninfringement.  The Regents of the University of
23*4882a593Smuzhiyun  *  Michigan shall not be liable for any damages, including special,
24*4882a593Smuzhiyun  *  indirect, incidental, or consequential damages, with respect to any
25*4882a593Smuzhiyun  *  claim arising out of or in connection with the use of the software,
26*4882a593Smuzhiyun  *  even if it has been or is hereafter advised of the possibility of
27*4882a593Smuzhiyun  *  such damages.
28*4882a593Smuzhiyun  */
29*4882a593Smuzhiyun 
30*4882a593Smuzhiyun #ifndef FS_NFS_PNFS_H
31*4882a593Smuzhiyun #define FS_NFS_PNFS_H
32*4882a593Smuzhiyun 
33*4882a593Smuzhiyun #include <linux/refcount.h>
34*4882a593Smuzhiyun #include <linux/nfs_fs.h>
35*4882a593Smuzhiyun #include <linux/nfs_page.h>
36*4882a593Smuzhiyun #include <linux/workqueue.h>
37*4882a593Smuzhiyun 
38*4882a593Smuzhiyun struct nfs4_opendata;
39*4882a593Smuzhiyun 
40*4882a593Smuzhiyun enum {
41*4882a593Smuzhiyun 	NFS_LSEG_VALID = 0,	/* cleared when lseg is recalled/returned */
42*4882a593Smuzhiyun 	NFS_LSEG_ROC,		/* roc bit received from server */
43*4882a593Smuzhiyun 	NFS_LSEG_LAYOUTCOMMIT,	/* layoutcommit bit set for layoutcommit */
44*4882a593Smuzhiyun 	NFS_LSEG_LAYOUTRETURN,	/* layoutreturn bit set for layoutreturn */
45*4882a593Smuzhiyun 	NFS_LSEG_UNAVAILABLE,	/* unavailable bit set for temporary problem */
46*4882a593Smuzhiyun };
47*4882a593Smuzhiyun 
48*4882a593Smuzhiyun /* Individual ip address */
49*4882a593Smuzhiyun struct nfs4_pnfs_ds_addr {
50*4882a593Smuzhiyun 	struct sockaddr_storage	da_addr;
51*4882a593Smuzhiyun 	size_t			da_addrlen;
52*4882a593Smuzhiyun 	struct list_head	da_node;  /* nfs4_pnfs_dev_hlist dev_dslist */
53*4882a593Smuzhiyun 	char			*da_remotestr;	/* human readable addr+port */
54*4882a593Smuzhiyun };
55*4882a593Smuzhiyun 
56*4882a593Smuzhiyun struct nfs4_pnfs_ds {
57*4882a593Smuzhiyun 	struct list_head	ds_node;  /* nfs4_pnfs_dev_hlist dev_dslist */
58*4882a593Smuzhiyun 	char			*ds_remotestr;	/* comma sep list of addrs */
59*4882a593Smuzhiyun 	struct list_head	ds_addrs;
60*4882a593Smuzhiyun 	struct nfs_client	*ds_clp;
61*4882a593Smuzhiyun 	refcount_t		ds_count;
62*4882a593Smuzhiyun 	unsigned long		ds_state;
63*4882a593Smuzhiyun #define NFS4DS_CONNECTING	0	/* ds is establishing connection */
64*4882a593Smuzhiyun };
65*4882a593Smuzhiyun 
66*4882a593Smuzhiyun struct pnfs_layout_segment {
67*4882a593Smuzhiyun 	struct list_head pls_list;
68*4882a593Smuzhiyun 	struct list_head pls_lc_list;
69*4882a593Smuzhiyun 	struct list_head pls_commits;
70*4882a593Smuzhiyun 	struct pnfs_layout_range pls_range;
71*4882a593Smuzhiyun 	refcount_t pls_refcount;
72*4882a593Smuzhiyun 	u32 pls_seq;
73*4882a593Smuzhiyun 	unsigned long pls_flags;
74*4882a593Smuzhiyun 	struct pnfs_layout_hdr *pls_layout;
75*4882a593Smuzhiyun };
76*4882a593Smuzhiyun 
77*4882a593Smuzhiyun enum pnfs_try_status {
78*4882a593Smuzhiyun 	PNFS_ATTEMPTED     = 0,
79*4882a593Smuzhiyun 	PNFS_NOT_ATTEMPTED = 1,
80*4882a593Smuzhiyun 	PNFS_TRY_AGAIN     = 2,
81*4882a593Smuzhiyun };
82*4882a593Smuzhiyun 
83*4882a593Smuzhiyun /* error codes for internal use */
84*4882a593Smuzhiyun #define NFS4ERR_RESET_TO_MDS   12001
85*4882a593Smuzhiyun #define NFS4ERR_RESET_TO_PNFS  12002
86*4882a593Smuzhiyun 
87*4882a593Smuzhiyun #ifdef CONFIG_NFS_V4_1
88*4882a593Smuzhiyun 
89*4882a593Smuzhiyun #define LAYOUT_NFSV4_1_MODULE_PREFIX "nfs-layouttype4"
90*4882a593Smuzhiyun 
91*4882a593Smuzhiyun /*
92*4882a593Smuzhiyun  * Default data server connection timeout and retrans vaules.
93*4882a593Smuzhiyun  * Set by module parameters dataserver_timeo and dataserver_retrans.
94*4882a593Smuzhiyun  */
95*4882a593Smuzhiyun #define NFS4_DEF_DS_TIMEO   600 /* in tenths of a second */
96*4882a593Smuzhiyun #define NFS4_DEF_DS_RETRANS 5
97*4882a593Smuzhiyun #define PNFS_DEVICE_RETRY_TIMEOUT (120*HZ)
98*4882a593Smuzhiyun 
99*4882a593Smuzhiyun enum {
100*4882a593Smuzhiyun 	NFS_LAYOUT_RO_FAILED = 0,	/* get ro layout failed stop trying */
101*4882a593Smuzhiyun 	NFS_LAYOUT_RW_FAILED,		/* get rw layout failed stop trying */
102*4882a593Smuzhiyun 	NFS_LAYOUT_BULK_RECALL,		/* bulk recall affecting layout */
103*4882a593Smuzhiyun 	NFS_LAYOUT_RETURN,		/* layoutreturn in progress */
104*4882a593Smuzhiyun 	NFS_LAYOUT_RETURN_LOCK,		/* Serialise layoutreturn */
105*4882a593Smuzhiyun 	NFS_LAYOUT_RETURN_REQUESTED,	/* Return this layout ASAP */
106*4882a593Smuzhiyun 	NFS_LAYOUT_INVALID_STID,	/* layout stateid id is invalid */
107*4882a593Smuzhiyun 	NFS_LAYOUT_FIRST_LAYOUTGET,	/* Serialize first layoutget */
108*4882a593Smuzhiyun 	NFS_LAYOUT_INODE_FREEING,	/* The inode is being freed */
109*4882a593Smuzhiyun 	NFS_LAYOUT_HASHED,		/* The layout visible */
110*4882a593Smuzhiyun 	NFS_LAYOUT_DRAIN,
111*4882a593Smuzhiyun };
112*4882a593Smuzhiyun 
113*4882a593Smuzhiyun enum layoutdriver_policy_flags {
114*4882a593Smuzhiyun 	/* Should the pNFS client commit and return the layout upon truncate to
115*4882a593Smuzhiyun 	 * a smaller size */
116*4882a593Smuzhiyun 	PNFS_LAYOUTRET_ON_SETATTR	= 1 << 0,
117*4882a593Smuzhiyun 	PNFS_LAYOUTRET_ON_ERROR		= 1 << 1,
118*4882a593Smuzhiyun 	PNFS_READ_WHOLE_PAGE		= 1 << 2,
119*4882a593Smuzhiyun 	PNFS_LAYOUTGET_ON_OPEN		= 1 << 3,
120*4882a593Smuzhiyun };
121*4882a593Smuzhiyun 
122*4882a593Smuzhiyun struct nfs4_deviceid_node;
123*4882a593Smuzhiyun 
124*4882a593Smuzhiyun /* Per-layout driver specific registration structure */
125*4882a593Smuzhiyun struct pnfs_layoutdriver_type {
126*4882a593Smuzhiyun 	struct list_head pnfs_tblid;
127*4882a593Smuzhiyun 	const u32 id;
128*4882a593Smuzhiyun 	const char *name;
129*4882a593Smuzhiyun 	struct module *owner;
130*4882a593Smuzhiyun 	unsigned flags;
131*4882a593Smuzhiyun 	unsigned max_deviceinfo_size;
132*4882a593Smuzhiyun 	unsigned max_layoutget_response;
133*4882a593Smuzhiyun 
134*4882a593Smuzhiyun 	int (*set_layoutdriver) (struct nfs_server *, const struct nfs_fh *);
135*4882a593Smuzhiyun 	int (*clear_layoutdriver) (struct nfs_server *);
136*4882a593Smuzhiyun 
137*4882a593Smuzhiyun 	struct pnfs_layout_hdr * (*alloc_layout_hdr) (struct inode *inode, gfp_t gfp_flags);
138*4882a593Smuzhiyun 	void (*free_layout_hdr) (struct pnfs_layout_hdr *);
139*4882a593Smuzhiyun 
140*4882a593Smuzhiyun 	struct pnfs_layout_segment * (*alloc_lseg) (struct pnfs_layout_hdr *layoutid, struct nfs4_layoutget_res *lgr, gfp_t gfp_flags);
141*4882a593Smuzhiyun 	void (*free_lseg) (struct pnfs_layout_segment *lseg);
142*4882a593Smuzhiyun 	void (*add_lseg) (struct pnfs_layout_hdr *layoutid,
143*4882a593Smuzhiyun 			struct pnfs_layout_segment *lseg,
144*4882a593Smuzhiyun 			struct list_head *free_me);
145*4882a593Smuzhiyun 
146*4882a593Smuzhiyun 	void (*return_range) (struct pnfs_layout_hdr *lo,
147*4882a593Smuzhiyun 			      struct pnfs_layout_range *range);
148*4882a593Smuzhiyun 
149*4882a593Smuzhiyun 	/* test for nfs page cache coalescing */
150*4882a593Smuzhiyun 	const struct nfs_pageio_ops *pg_read_ops;
151*4882a593Smuzhiyun 	const struct nfs_pageio_ops *pg_write_ops;
152*4882a593Smuzhiyun 
153*4882a593Smuzhiyun 	struct pnfs_ds_commit_info *(*get_ds_info) (struct inode *inode);
154*4882a593Smuzhiyun 
155*4882a593Smuzhiyun 	int (*sync)(struct inode *inode, bool datasync);
156*4882a593Smuzhiyun 
157*4882a593Smuzhiyun 	/*
158*4882a593Smuzhiyun 	 * Return PNFS_ATTEMPTED to indicate the layout code has attempted
159*4882a593Smuzhiyun 	 * I/O, else return PNFS_NOT_ATTEMPTED to fall back to normal NFS
160*4882a593Smuzhiyun 	 */
161*4882a593Smuzhiyun 	enum pnfs_try_status (*read_pagelist)(struct nfs_pgio_header *);
162*4882a593Smuzhiyun 	enum pnfs_try_status (*write_pagelist)(struct nfs_pgio_header *, int);
163*4882a593Smuzhiyun 
164*4882a593Smuzhiyun 	void (*free_deviceid_node) (struct nfs4_deviceid_node *);
165*4882a593Smuzhiyun 	struct nfs4_deviceid_node * (*alloc_deviceid_node)
166*4882a593Smuzhiyun 			(struct nfs_server *server, struct pnfs_device *pdev,
167*4882a593Smuzhiyun 			gfp_t gfp_flags);
168*4882a593Smuzhiyun 
169*4882a593Smuzhiyun 	int (*prepare_layoutreturn) (struct nfs4_layoutreturn_args *);
170*4882a593Smuzhiyun 
171*4882a593Smuzhiyun 	void (*cleanup_layoutcommit) (struct nfs4_layoutcommit_data *data);
172*4882a593Smuzhiyun 	int (*prepare_layoutcommit) (struct nfs4_layoutcommit_args *args);
173*4882a593Smuzhiyun 	int (*prepare_layoutstats) (struct nfs42_layoutstat_args *args);
174*4882a593Smuzhiyun };
175*4882a593Smuzhiyun 
176*4882a593Smuzhiyun struct pnfs_commit_ops {
177*4882a593Smuzhiyun 	void (*setup_ds_info)(struct pnfs_ds_commit_info *,
178*4882a593Smuzhiyun 			      struct pnfs_layout_segment *);
179*4882a593Smuzhiyun 	void (*release_ds_info)(struct pnfs_ds_commit_info *,
180*4882a593Smuzhiyun 				struct inode *inode);
181*4882a593Smuzhiyun 	int (*commit_pagelist)(struct inode *inode,
182*4882a593Smuzhiyun 			       struct list_head *mds_pages,
183*4882a593Smuzhiyun 			       int how,
184*4882a593Smuzhiyun 			       struct nfs_commit_info *cinfo);
185*4882a593Smuzhiyun 	void (*mark_request_commit) (struct nfs_page *req,
186*4882a593Smuzhiyun 				     struct pnfs_layout_segment *lseg,
187*4882a593Smuzhiyun 				     struct nfs_commit_info *cinfo,
188*4882a593Smuzhiyun 				     u32 ds_commit_idx);
189*4882a593Smuzhiyun 	void (*clear_request_commit) (struct nfs_page *req,
190*4882a593Smuzhiyun 				      struct nfs_commit_info *cinfo);
191*4882a593Smuzhiyun 	int (*scan_commit_lists) (struct nfs_commit_info *cinfo,
192*4882a593Smuzhiyun 				  int max);
193*4882a593Smuzhiyun 	void (*recover_commit_reqs) (struct list_head *list,
194*4882a593Smuzhiyun 				     struct nfs_commit_info *cinfo);
195*4882a593Smuzhiyun 	struct nfs_page * (*search_commit_reqs)(struct nfs_commit_info *cinfo,
196*4882a593Smuzhiyun 						struct page *page);
197*4882a593Smuzhiyun };
198*4882a593Smuzhiyun 
199*4882a593Smuzhiyun struct pnfs_layout_hdr {
200*4882a593Smuzhiyun 	refcount_t		plh_refcount;
201*4882a593Smuzhiyun 	atomic_t		plh_outstanding; /* number of RPCs out */
202*4882a593Smuzhiyun 	struct list_head	plh_layouts;   /* other client layouts */
203*4882a593Smuzhiyun 	struct list_head	plh_bulk_destroy;
204*4882a593Smuzhiyun 	struct list_head	plh_segs;      /* layout segments list */
205*4882a593Smuzhiyun 	struct list_head	plh_return_segs; /* invalid layout segments */
206*4882a593Smuzhiyun 	unsigned long		plh_block_lgets; /* block LAYOUTGET if >0 */
207*4882a593Smuzhiyun 	unsigned long		plh_retry_timestamp;
208*4882a593Smuzhiyun 	unsigned long		plh_flags;
209*4882a593Smuzhiyun 	nfs4_stateid		plh_stateid;
210*4882a593Smuzhiyun 	u32			plh_barrier; /* ignore lower seqids */
211*4882a593Smuzhiyun 	u32			plh_return_seq;
212*4882a593Smuzhiyun 	enum pnfs_iomode	plh_return_iomode;
213*4882a593Smuzhiyun 	loff_t			plh_lwb; /* last write byte for layoutcommit */
214*4882a593Smuzhiyun 	const struct cred	*plh_lc_cred; /* layoutcommit cred */
215*4882a593Smuzhiyun 	struct inode		*plh_inode;
216*4882a593Smuzhiyun 	struct rcu_head		plh_rcu;
217*4882a593Smuzhiyun };
218*4882a593Smuzhiyun 
219*4882a593Smuzhiyun struct pnfs_device {
220*4882a593Smuzhiyun 	struct nfs4_deviceid dev_id;
221*4882a593Smuzhiyun 	unsigned int  layout_type;
222*4882a593Smuzhiyun 	unsigned int  mincount;
223*4882a593Smuzhiyun 	unsigned int  maxcount;	/* gdia_maxcount */
224*4882a593Smuzhiyun 	struct page **pages;
225*4882a593Smuzhiyun 	unsigned int  pgbase;
226*4882a593Smuzhiyun 	unsigned int  pglen;	/* reply buffer length */
227*4882a593Smuzhiyun 	unsigned char nocache : 1;/* May not be cached */
228*4882a593Smuzhiyun };
229*4882a593Smuzhiyun 
230*4882a593Smuzhiyun #define NFS4_PNFS_GETDEVLIST_MAXNUM 16
231*4882a593Smuzhiyun 
232*4882a593Smuzhiyun struct pnfs_devicelist {
233*4882a593Smuzhiyun 	unsigned int		eof;
234*4882a593Smuzhiyun 	unsigned int		num_devs;
235*4882a593Smuzhiyun 	struct nfs4_deviceid	dev_id[NFS4_PNFS_GETDEVLIST_MAXNUM];
236*4882a593Smuzhiyun };
237*4882a593Smuzhiyun 
238*4882a593Smuzhiyun extern int pnfs_register_layoutdriver(struct pnfs_layoutdriver_type *);
239*4882a593Smuzhiyun extern void pnfs_unregister_layoutdriver(struct pnfs_layoutdriver_type *);
240*4882a593Smuzhiyun extern const struct pnfs_layoutdriver_type *pnfs_find_layoutdriver(u32 id);
241*4882a593Smuzhiyun extern void pnfs_put_layoutdriver(const struct pnfs_layoutdriver_type *ld);
242*4882a593Smuzhiyun 
243*4882a593Smuzhiyun /* nfs4proc.c */
244*4882a593Smuzhiyun extern size_t max_response_pages(struct nfs_server *server);
245*4882a593Smuzhiyun extern int nfs4_proc_getdeviceinfo(struct nfs_server *server,
246*4882a593Smuzhiyun 				   struct pnfs_device *dev,
247*4882a593Smuzhiyun 				   const struct cred *cred);
248*4882a593Smuzhiyun extern struct pnfs_layout_segment* nfs4_proc_layoutget(struct nfs4_layoutget *lgp, long *timeout);
249*4882a593Smuzhiyun extern int nfs4_proc_layoutreturn(struct nfs4_layoutreturn *lrp, bool sync);
250*4882a593Smuzhiyun 
251*4882a593Smuzhiyun /* pnfs.c */
252*4882a593Smuzhiyun void pnfs_get_layout_hdr(struct pnfs_layout_hdr *lo);
253*4882a593Smuzhiyun void pnfs_put_lseg(struct pnfs_layout_segment *lseg);
254*4882a593Smuzhiyun 
255*4882a593Smuzhiyun void set_pnfs_layoutdriver(struct nfs_server *, const struct nfs_fh *, struct nfs_fsinfo *);
256*4882a593Smuzhiyun void unset_pnfs_layoutdriver(struct nfs_server *);
257*4882a593Smuzhiyun void pnfs_generic_pg_check_layout(struct nfs_pageio_descriptor *pgio);
258*4882a593Smuzhiyun void pnfs_generic_pg_check_range(struct nfs_pageio_descriptor *pgio, struct nfs_page *req);
259*4882a593Smuzhiyun void pnfs_generic_pg_init_read(struct nfs_pageio_descriptor *, struct nfs_page *);
260*4882a593Smuzhiyun int pnfs_generic_pg_readpages(struct nfs_pageio_descriptor *desc);
261*4882a593Smuzhiyun void pnfs_generic_pg_init_write(struct nfs_pageio_descriptor *pgio,
262*4882a593Smuzhiyun 			        struct nfs_page *req, u64 wb_size);
263*4882a593Smuzhiyun void pnfs_generic_pg_cleanup(struct nfs_pageio_descriptor *);
264*4882a593Smuzhiyun int pnfs_generic_pg_writepages(struct nfs_pageio_descriptor *desc);
265*4882a593Smuzhiyun size_t pnfs_generic_pg_test(struct nfs_pageio_descriptor *pgio,
266*4882a593Smuzhiyun 			    struct nfs_page *prev, struct nfs_page *req);
267*4882a593Smuzhiyun void pnfs_set_lo_fail(struct pnfs_layout_segment *lseg);
268*4882a593Smuzhiyun struct pnfs_layout_segment *pnfs_layout_process(struct nfs4_layoutget *lgp);
269*4882a593Smuzhiyun void pnfs_layoutget_free(struct nfs4_layoutget *lgp);
270*4882a593Smuzhiyun void pnfs_free_lseg_list(struct list_head *tmp_list);
271*4882a593Smuzhiyun void pnfs_destroy_layout(struct nfs_inode *);
272*4882a593Smuzhiyun void pnfs_destroy_layout_final(struct nfs_inode *);
273*4882a593Smuzhiyun void pnfs_destroy_all_layouts(struct nfs_client *);
274*4882a593Smuzhiyun int pnfs_destroy_layouts_byfsid(struct nfs_client *clp,
275*4882a593Smuzhiyun 		struct nfs_fsid *fsid,
276*4882a593Smuzhiyun 		bool is_recall);
277*4882a593Smuzhiyun int pnfs_destroy_layouts_byclid(struct nfs_client *clp,
278*4882a593Smuzhiyun 		bool is_recall);
279*4882a593Smuzhiyun bool nfs4_layout_refresh_old_stateid(nfs4_stateid *dst,
280*4882a593Smuzhiyun 		struct pnfs_layout_range *dst_range,
281*4882a593Smuzhiyun 		struct inode *inode);
282*4882a593Smuzhiyun void pnfs_put_layout_hdr(struct pnfs_layout_hdr *lo);
283*4882a593Smuzhiyun void pnfs_set_layout_stateid(struct pnfs_layout_hdr *lo,
284*4882a593Smuzhiyun 			     const nfs4_stateid *new,
285*4882a593Smuzhiyun 			     const struct cred *cred,
286*4882a593Smuzhiyun 			     bool update_barrier);
287*4882a593Smuzhiyun int pnfs_mark_matching_lsegs_invalid(struct pnfs_layout_hdr *lo,
288*4882a593Smuzhiyun 				struct list_head *tmp_list,
289*4882a593Smuzhiyun 				const struct pnfs_layout_range *recall_range,
290*4882a593Smuzhiyun 				u32 seq);
291*4882a593Smuzhiyun int pnfs_mark_matching_lsegs_return(struct pnfs_layout_hdr *lo,
292*4882a593Smuzhiyun 				struct list_head *tmp_list,
293*4882a593Smuzhiyun 				const struct pnfs_layout_range *recall_range,
294*4882a593Smuzhiyun 				u32 seq);
295*4882a593Smuzhiyun int pnfs_mark_layout_stateid_invalid(struct pnfs_layout_hdr *lo,
296*4882a593Smuzhiyun 		struct list_head *lseg_list);
297*4882a593Smuzhiyun bool pnfs_roc(struct inode *ino,
298*4882a593Smuzhiyun 		struct nfs4_layoutreturn_args *args,
299*4882a593Smuzhiyun 		struct nfs4_layoutreturn_res *res,
300*4882a593Smuzhiyun 		const struct cred *cred);
301*4882a593Smuzhiyun int pnfs_roc_done(struct rpc_task *task, struct nfs4_layoutreturn_args **argpp,
302*4882a593Smuzhiyun 		  struct nfs4_layoutreturn_res **respp, int *ret);
303*4882a593Smuzhiyun void pnfs_roc_release(struct nfs4_layoutreturn_args *args,
304*4882a593Smuzhiyun 		struct nfs4_layoutreturn_res *res,
305*4882a593Smuzhiyun 		int ret);
306*4882a593Smuzhiyun bool pnfs_wait_on_layoutreturn(struct inode *ino, struct rpc_task *task);
307*4882a593Smuzhiyun void pnfs_set_layoutcommit(struct inode *, struct pnfs_layout_segment *, loff_t);
308*4882a593Smuzhiyun void pnfs_cleanup_layoutcommit(struct nfs4_layoutcommit_data *data);
309*4882a593Smuzhiyun int pnfs_layoutcommit_inode(struct inode *inode, bool sync);
310*4882a593Smuzhiyun int pnfs_generic_sync(struct inode *inode, bool datasync);
311*4882a593Smuzhiyun int pnfs_nfs_generic_sync(struct inode *inode, bool datasync);
312*4882a593Smuzhiyun int _pnfs_return_layout(struct inode *);
313*4882a593Smuzhiyun int pnfs_commit_and_return_layout(struct inode *);
314*4882a593Smuzhiyun void pnfs_ld_write_done(struct nfs_pgio_header *);
315*4882a593Smuzhiyun void pnfs_ld_read_done(struct nfs_pgio_header *);
316*4882a593Smuzhiyun void pnfs_read_resend_pnfs(struct nfs_pgio_header *, unsigned int mirror_idx);
317*4882a593Smuzhiyun struct pnfs_layout_segment *pnfs_update_layout(struct inode *ino,
318*4882a593Smuzhiyun 					       struct nfs_open_context *ctx,
319*4882a593Smuzhiyun 					       loff_t pos,
320*4882a593Smuzhiyun 					       u64 count,
321*4882a593Smuzhiyun 					       enum pnfs_iomode iomode,
322*4882a593Smuzhiyun 					       bool strict_iomode,
323*4882a593Smuzhiyun 					       gfp_t gfp_flags);
324*4882a593Smuzhiyun void pnfs_layoutreturn_free_lsegs(struct pnfs_layout_hdr *lo,
325*4882a593Smuzhiyun 		const nfs4_stateid *arg_stateid,
326*4882a593Smuzhiyun 		const struct pnfs_layout_range *range,
327*4882a593Smuzhiyun 		const nfs4_stateid *stateid);
328*4882a593Smuzhiyun 
329*4882a593Smuzhiyun void pnfs_generic_layout_insert_lseg(struct pnfs_layout_hdr *lo,
330*4882a593Smuzhiyun 		   struct pnfs_layout_segment *lseg,
331*4882a593Smuzhiyun 		   bool (*is_after)(const struct pnfs_layout_range *lseg_range,
332*4882a593Smuzhiyun 			   const struct pnfs_layout_range *old),
333*4882a593Smuzhiyun 		   bool (*do_merge)(struct pnfs_layout_segment *lseg,
334*4882a593Smuzhiyun 			   struct pnfs_layout_segment *old),
335*4882a593Smuzhiyun 		   struct list_head *free_me);
336*4882a593Smuzhiyun 
337*4882a593Smuzhiyun void nfs4_deviceid_mark_client_invalid(struct nfs_client *clp);
338*4882a593Smuzhiyun int pnfs_read_done_resend_to_mds(struct nfs_pgio_header *);
339*4882a593Smuzhiyun int pnfs_write_done_resend_to_mds(struct nfs_pgio_header *);
340*4882a593Smuzhiyun struct nfs4_threshold *pnfs_mdsthreshold_alloc(void);
341*4882a593Smuzhiyun void pnfs_error_mark_layout_for_return(struct inode *inode,
342*4882a593Smuzhiyun 				       struct pnfs_layout_segment *lseg);
343*4882a593Smuzhiyun void pnfs_layout_return_unused_byclid(struct nfs_client *clp,
344*4882a593Smuzhiyun 				      enum pnfs_iomode iomode);
345*4882a593Smuzhiyun 
346*4882a593Smuzhiyun /* nfs4_deviceid_flags */
347*4882a593Smuzhiyun enum {
348*4882a593Smuzhiyun 	NFS_DEVICEID_INVALID = 0,       /* set when MDS clientid recalled */
349*4882a593Smuzhiyun 	NFS_DEVICEID_UNAVAILABLE,	/* device temporarily unavailable */
350*4882a593Smuzhiyun 	NFS_DEVICEID_NOCACHE,		/* device may not be cached */
351*4882a593Smuzhiyun };
352*4882a593Smuzhiyun 
353*4882a593Smuzhiyun /* pnfs_dev.c */
354*4882a593Smuzhiyun struct nfs4_deviceid_node {
355*4882a593Smuzhiyun 	struct hlist_node		node;
356*4882a593Smuzhiyun 	struct hlist_node		tmpnode;
357*4882a593Smuzhiyun 	const struct pnfs_layoutdriver_type *ld;
358*4882a593Smuzhiyun 	const struct nfs_client		*nfs_client;
359*4882a593Smuzhiyun 	unsigned long 			flags;
360*4882a593Smuzhiyun 	unsigned long			timestamp_unavailable;
361*4882a593Smuzhiyun 	struct nfs4_deviceid		deviceid;
362*4882a593Smuzhiyun 	struct rcu_head			rcu;
363*4882a593Smuzhiyun 	atomic_t			ref;
364*4882a593Smuzhiyun };
365*4882a593Smuzhiyun 
366*4882a593Smuzhiyun struct nfs4_deviceid_node *
367*4882a593Smuzhiyun nfs4_find_get_deviceid(struct nfs_server *server,
368*4882a593Smuzhiyun 		const struct nfs4_deviceid *id, const struct cred *cred,
369*4882a593Smuzhiyun 		gfp_t gfp_mask);
370*4882a593Smuzhiyun void nfs4_delete_deviceid(const struct pnfs_layoutdriver_type *, const struct nfs_client *, const struct nfs4_deviceid *);
371*4882a593Smuzhiyun void nfs4_init_deviceid_node(struct nfs4_deviceid_node *, struct nfs_server *,
372*4882a593Smuzhiyun 			     const struct nfs4_deviceid *);
373*4882a593Smuzhiyun bool nfs4_put_deviceid_node(struct nfs4_deviceid_node *);
374*4882a593Smuzhiyun void nfs4_mark_deviceid_available(struct nfs4_deviceid_node *node);
375*4882a593Smuzhiyun void nfs4_mark_deviceid_unavailable(struct nfs4_deviceid_node *node);
376*4882a593Smuzhiyun bool nfs4_test_deviceid_unavailable(struct nfs4_deviceid_node *node);
377*4882a593Smuzhiyun void nfs4_deviceid_purge_client(const struct nfs_client *);
378*4882a593Smuzhiyun 
379*4882a593Smuzhiyun /* pnfs_nfs.c */
380*4882a593Smuzhiyun struct pnfs_commit_array *pnfs_alloc_commit_array(size_t n, gfp_t gfp_flags);
381*4882a593Smuzhiyun void pnfs_free_commit_array(struct pnfs_commit_array *p);
382*4882a593Smuzhiyun struct pnfs_commit_array *pnfs_add_commit_array(struct pnfs_ds_commit_info *,
383*4882a593Smuzhiyun 						struct pnfs_commit_array *,
384*4882a593Smuzhiyun 						struct pnfs_layout_segment *);
385*4882a593Smuzhiyun 
386*4882a593Smuzhiyun void pnfs_generic_ds_cinfo_release_lseg(struct pnfs_ds_commit_info *fl_cinfo,
387*4882a593Smuzhiyun 		struct pnfs_layout_segment *lseg);
388*4882a593Smuzhiyun void pnfs_generic_ds_cinfo_destroy(struct pnfs_ds_commit_info *fl_cinfo);
389*4882a593Smuzhiyun 
390*4882a593Smuzhiyun void pnfs_generic_clear_request_commit(struct nfs_page *req,
391*4882a593Smuzhiyun 				       struct nfs_commit_info *cinfo);
392*4882a593Smuzhiyun void pnfs_generic_commit_release(void *calldata);
393*4882a593Smuzhiyun void pnfs_generic_prepare_to_resend_writes(struct nfs_commit_data *data);
394*4882a593Smuzhiyun void pnfs_generic_rw_release(void *data);
395*4882a593Smuzhiyun void pnfs_generic_recover_commit_reqs(struct list_head *dst,
396*4882a593Smuzhiyun 				      struct nfs_commit_info *cinfo);
397*4882a593Smuzhiyun struct nfs_page *pnfs_generic_search_commit_reqs(struct nfs_commit_info *cinfo,
398*4882a593Smuzhiyun 						 struct page *page);
399*4882a593Smuzhiyun int pnfs_generic_commit_pagelist(struct inode *inode,
400*4882a593Smuzhiyun 				 struct list_head *mds_pages,
401*4882a593Smuzhiyun 				 int how,
402*4882a593Smuzhiyun 				 struct nfs_commit_info *cinfo,
403*4882a593Smuzhiyun 				 int (*initiate_commit)(struct nfs_commit_data *data,
404*4882a593Smuzhiyun 							int how));
405*4882a593Smuzhiyun int pnfs_generic_scan_commit_lists(struct nfs_commit_info *cinfo, int max);
406*4882a593Smuzhiyun void pnfs_generic_write_commit_done(struct rpc_task *task, void *data);
407*4882a593Smuzhiyun void nfs4_pnfs_ds_put(struct nfs4_pnfs_ds *ds);
408*4882a593Smuzhiyun struct nfs4_pnfs_ds *nfs4_pnfs_ds_add(struct list_head *dsaddrs,
409*4882a593Smuzhiyun 				      gfp_t gfp_flags);
410*4882a593Smuzhiyun void nfs4_pnfs_v3_ds_connect_unload(void);
411*4882a593Smuzhiyun int nfs4_pnfs_ds_connect(struct nfs_server *mds_srv, struct nfs4_pnfs_ds *ds,
412*4882a593Smuzhiyun 			  struct nfs4_deviceid_node *devid, unsigned int timeo,
413*4882a593Smuzhiyun 			  unsigned int retrans, u32 version, u32 minor_version);
414*4882a593Smuzhiyun struct nfs4_pnfs_ds_addr *nfs4_decode_mp_ds_addr(struct net *net,
415*4882a593Smuzhiyun 						 struct xdr_stream *xdr,
416*4882a593Smuzhiyun 						 gfp_t gfp_flags);
417*4882a593Smuzhiyun void pnfs_layout_mark_request_commit(struct nfs_page *req,
418*4882a593Smuzhiyun 				     struct pnfs_layout_segment *lseg,
419*4882a593Smuzhiyun 				     struct nfs_commit_info *cinfo,
420*4882a593Smuzhiyun 				     u32 ds_commit_idx);
421*4882a593Smuzhiyun void pnfs_lgopen_prepare(struct nfs4_opendata *data,
422*4882a593Smuzhiyun 			 struct nfs_open_context *ctx);
423*4882a593Smuzhiyun void pnfs_parse_lgopen(struct inode *ino, struct nfs4_layoutget *lgp,
424*4882a593Smuzhiyun 		       struct nfs_open_context *ctx);
425*4882a593Smuzhiyun void nfs4_lgopen_release(struct nfs4_layoutget *lgp);
426*4882a593Smuzhiyun 
nfs_have_layout(struct inode * inode)427*4882a593Smuzhiyun static inline bool nfs_have_layout(struct inode *inode)
428*4882a593Smuzhiyun {
429*4882a593Smuzhiyun 	return NFS_I(inode)->layout != NULL;
430*4882a593Smuzhiyun }
431*4882a593Smuzhiyun 
pnfs_layout_is_valid(const struct pnfs_layout_hdr * lo)432*4882a593Smuzhiyun static inline bool pnfs_layout_is_valid(const struct pnfs_layout_hdr *lo)
433*4882a593Smuzhiyun {
434*4882a593Smuzhiyun 	return test_bit(NFS_LAYOUT_INVALID_STID, &lo->plh_flags) == 0;
435*4882a593Smuzhiyun }
436*4882a593Smuzhiyun 
437*4882a593Smuzhiyun static inline struct nfs4_deviceid_node *
nfs4_get_deviceid(struct nfs4_deviceid_node * d)438*4882a593Smuzhiyun nfs4_get_deviceid(struct nfs4_deviceid_node *d)
439*4882a593Smuzhiyun {
440*4882a593Smuzhiyun 	atomic_inc(&d->ref);
441*4882a593Smuzhiyun 	return d;
442*4882a593Smuzhiyun }
443*4882a593Smuzhiyun 
444*4882a593Smuzhiyun static inline struct pnfs_layout_segment *
pnfs_get_lseg(struct pnfs_layout_segment * lseg)445*4882a593Smuzhiyun pnfs_get_lseg(struct pnfs_layout_segment *lseg)
446*4882a593Smuzhiyun {
447*4882a593Smuzhiyun 	if (lseg) {
448*4882a593Smuzhiyun 		refcount_inc(&lseg->pls_refcount);
449*4882a593Smuzhiyun 		smp_mb__after_atomic();
450*4882a593Smuzhiyun 	}
451*4882a593Smuzhiyun 	return lseg;
452*4882a593Smuzhiyun }
453*4882a593Smuzhiyun 
454*4882a593Smuzhiyun static inline bool
pnfs_is_valid_lseg(struct pnfs_layout_segment * lseg)455*4882a593Smuzhiyun pnfs_is_valid_lseg(struct pnfs_layout_segment *lseg)
456*4882a593Smuzhiyun {
457*4882a593Smuzhiyun 	return test_bit(NFS_LSEG_VALID, &lseg->pls_flags) != 0;
458*4882a593Smuzhiyun }
459*4882a593Smuzhiyun 
460*4882a593Smuzhiyun /* Return true if a layout driver is being used for this mountpoint */
pnfs_enabled_sb(struct nfs_server * nfss)461*4882a593Smuzhiyun static inline int pnfs_enabled_sb(struct nfs_server *nfss)
462*4882a593Smuzhiyun {
463*4882a593Smuzhiyun 	return nfss->pnfs_curr_ld != NULL;
464*4882a593Smuzhiyun }
465*4882a593Smuzhiyun 
466*4882a593Smuzhiyun static inline int
pnfs_commit_list(struct inode * inode,struct list_head * mds_pages,int how,struct nfs_commit_info * cinfo)467*4882a593Smuzhiyun pnfs_commit_list(struct inode *inode, struct list_head *mds_pages, int how,
468*4882a593Smuzhiyun 		 struct nfs_commit_info *cinfo)
469*4882a593Smuzhiyun {
470*4882a593Smuzhiyun 	struct pnfs_ds_commit_info *fl_cinfo = cinfo->ds;
471*4882a593Smuzhiyun 
472*4882a593Smuzhiyun 	if (fl_cinfo == NULL || fl_cinfo->ncommitting == 0)
473*4882a593Smuzhiyun 		return PNFS_NOT_ATTEMPTED;
474*4882a593Smuzhiyun 	return fl_cinfo->ops->commit_pagelist(inode, mds_pages, how, cinfo);
475*4882a593Smuzhiyun }
476*4882a593Smuzhiyun 
477*4882a593Smuzhiyun static inline struct pnfs_ds_commit_info *
pnfs_get_ds_info(struct inode * inode)478*4882a593Smuzhiyun pnfs_get_ds_info(struct inode *inode)
479*4882a593Smuzhiyun {
480*4882a593Smuzhiyun 	struct pnfs_layoutdriver_type *ld = NFS_SERVER(inode)->pnfs_curr_ld;
481*4882a593Smuzhiyun 
482*4882a593Smuzhiyun 	if (ld == NULL || ld->get_ds_info == NULL)
483*4882a593Smuzhiyun 		return NULL;
484*4882a593Smuzhiyun 	return ld->get_ds_info(inode);
485*4882a593Smuzhiyun }
486*4882a593Smuzhiyun 
487*4882a593Smuzhiyun static inline void
pnfs_init_ds_commit_info_ops(struct pnfs_ds_commit_info * fl_cinfo,struct inode * inode)488*4882a593Smuzhiyun pnfs_init_ds_commit_info_ops(struct pnfs_ds_commit_info *fl_cinfo, struct inode *inode)
489*4882a593Smuzhiyun {
490*4882a593Smuzhiyun 	struct pnfs_ds_commit_info *inode_cinfo = pnfs_get_ds_info(inode);
491*4882a593Smuzhiyun 	if (inode_cinfo != NULL)
492*4882a593Smuzhiyun 		fl_cinfo->ops = inode_cinfo->ops;
493*4882a593Smuzhiyun }
494*4882a593Smuzhiyun 
495*4882a593Smuzhiyun static inline void
pnfs_init_ds_commit_info(struct pnfs_ds_commit_info * fl_cinfo)496*4882a593Smuzhiyun pnfs_init_ds_commit_info(struct pnfs_ds_commit_info *fl_cinfo)
497*4882a593Smuzhiyun {
498*4882a593Smuzhiyun 	INIT_LIST_HEAD(&fl_cinfo->commits);
499*4882a593Smuzhiyun 	fl_cinfo->ops = NULL;
500*4882a593Smuzhiyun }
501*4882a593Smuzhiyun 
502*4882a593Smuzhiyun static inline void
pnfs_release_ds_info(struct pnfs_ds_commit_info * fl_cinfo,struct inode * inode)503*4882a593Smuzhiyun pnfs_release_ds_info(struct pnfs_ds_commit_info *fl_cinfo, struct inode *inode)
504*4882a593Smuzhiyun {
505*4882a593Smuzhiyun 	if (fl_cinfo->ops != NULL && fl_cinfo->ops->release_ds_info != NULL)
506*4882a593Smuzhiyun 		fl_cinfo->ops->release_ds_info(fl_cinfo, inode);
507*4882a593Smuzhiyun }
508*4882a593Smuzhiyun 
509*4882a593Smuzhiyun static inline void
pnfs_generic_mark_devid_invalid(struct nfs4_deviceid_node * node)510*4882a593Smuzhiyun pnfs_generic_mark_devid_invalid(struct nfs4_deviceid_node *node)
511*4882a593Smuzhiyun {
512*4882a593Smuzhiyun 	set_bit(NFS_DEVICEID_INVALID, &node->flags);
513*4882a593Smuzhiyun }
514*4882a593Smuzhiyun 
515*4882a593Smuzhiyun static inline bool
pnfs_mark_request_commit(struct nfs_page * req,struct pnfs_layout_segment * lseg,struct nfs_commit_info * cinfo,u32 ds_commit_idx)516*4882a593Smuzhiyun pnfs_mark_request_commit(struct nfs_page *req, struct pnfs_layout_segment *lseg,
517*4882a593Smuzhiyun 			 struct nfs_commit_info *cinfo, u32 ds_commit_idx)
518*4882a593Smuzhiyun {
519*4882a593Smuzhiyun 	struct pnfs_ds_commit_info *fl_cinfo = cinfo->ds;
520*4882a593Smuzhiyun 
521*4882a593Smuzhiyun 	if (!lseg || !fl_cinfo->ops || !fl_cinfo->ops->mark_request_commit)
522*4882a593Smuzhiyun 		return false;
523*4882a593Smuzhiyun 	fl_cinfo->ops->mark_request_commit(req, lseg, cinfo, ds_commit_idx);
524*4882a593Smuzhiyun 	return true;
525*4882a593Smuzhiyun }
526*4882a593Smuzhiyun 
527*4882a593Smuzhiyun static inline bool
pnfs_clear_request_commit(struct nfs_page * req,struct nfs_commit_info * cinfo)528*4882a593Smuzhiyun pnfs_clear_request_commit(struct nfs_page *req, struct nfs_commit_info *cinfo)
529*4882a593Smuzhiyun {
530*4882a593Smuzhiyun 	struct pnfs_ds_commit_info *fl_cinfo = cinfo->ds;
531*4882a593Smuzhiyun 
532*4882a593Smuzhiyun 	if (!fl_cinfo || !fl_cinfo->ops || !fl_cinfo->ops->clear_request_commit)
533*4882a593Smuzhiyun 		return false;
534*4882a593Smuzhiyun 	fl_cinfo->ops->clear_request_commit(req, cinfo);
535*4882a593Smuzhiyun 	return true;
536*4882a593Smuzhiyun }
537*4882a593Smuzhiyun 
538*4882a593Smuzhiyun static inline int
pnfs_scan_commit_lists(struct inode * inode,struct nfs_commit_info * cinfo,int max)539*4882a593Smuzhiyun pnfs_scan_commit_lists(struct inode *inode, struct nfs_commit_info *cinfo,
540*4882a593Smuzhiyun 		       int max)
541*4882a593Smuzhiyun {
542*4882a593Smuzhiyun 	struct pnfs_ds_commit_info *fl_cinfo = cinfo->ds;
543*4882a593Smuzhiyun 
544*4882a593Smuzhiyun 	if (!fl_cinfo || fl_cinfo->nwritten == 0)
545*4882a593Smuzhiyun 		return 0;
546*4882a593Smuzhiyun 	return fl_cinfo->ops->scan_commit_lists(cinfo, max);
547*4882a593Smuzhiyun }
548*4882a593Smuzhiyun 
549*4882a593Smuzhiyun static inline void
pnfs_recover_commit_reqs(struct list_head * head,struct nfs_commit_info * cinfo)550*4882a593Smuzhiyun pnfs_recover_commit_reqs(struct list_head *head, struct nfs_commit_info *cinfo)
551*4882a593Smuzhiyun {
552*4882a593Smuzhiyun 	struct pnfs_ds_commit_info *fl_cinfo = cinfo->ds;
553*4882a593Smuzhiyun 
554*4882a593Smuzhiyun 	if (fl_cinfo && fl_cinfo->nwritten != 0)
555*4882a593Smuzhiyun 		fl_cinfo->ops->recover_commit_reqs(head, cinfo);
556*4882a593Smuzhiyun }
557*4882a593Smuzhiyun 
558*4882a593Smuzhiyun static inline struct nfs_page *
pnfs_search_commit_reqs(struct inode * inode,struct nfs_commit_info * cinfo,struct page * page)559*4882a593Smuzhiyun pnfs_search_commit_reqs(struct inode *inode, struct nfs_commit_info *cinfo,
560*4882a593Smuzhiyun 			struct page *page)
561*4882a593Smuzhiyun {
562*4882a593Smuzhiyun 	struct pnfs_ds_commit_info *fl_cinfo = cinfo->ds;
563*4882a593Smuzhiyun 
564*4882a593Smuzhiyun 	if (!fl_cinfo->ops || !fl_cinfo->ops->search_commit_reqs)
565*4882a593Smuzhiyun 		return NULL;
566*4882a593Smuzhiyun 	return fl_cinfo->ops->search_commit_reqs(cinfo, page);
567*4882a593Smuzhiyun }
568*4882a593Smuzhiyun 
569*4882a593Smuzhiyun /* Should the pNFS client commit and return the layout upon a setattr */
570*4882a593Smuzhiyun static inline bool
pnfs_ld_layoutret_on_setattr(struct inode * inode)571*4882a593Smuzhiyun pnfs_ld_layoutret_on_setattr(struct inode *inode)
572*4882a593Smuzhiyun {
573*4882a593Smuzhiyun 	if (!pnfs_enabled_sb(NFS_SERVER(inode)))
574*4882a593Smuzhiyun 		return false;
575*4882a593Smuzhiyun 	return NFS_SERVER(inode)->pnfs_curr_ld->flags &
576*4882a593Smuzhiyun 		PNFS_LAYOUTRET_ON_SETATTR;
577*4882a593Smuzhiyun }
578*4882a593Smuzhiyun 
579*4882a593Smuzhiyun static inline bool
pnfs_ld_read_whole_page(struct inode * inode)580*4882a593Smuzhiyun pnfs_ld_read_whole_page(struct inode *inode)
581*4882a593Smuzhiyun {
582*4882a593Smuzhiyun 	if (!pnfs_enabled_sb(NFS_SERVER(inode)))
583*4882a593Smuzhiyun 		return false;
584*4882a593Smuzhiyun 	return NFS_SERVER(inode)->pnfs_curr_ld->flags & PNFS_READ_WHOLE_PAGE;
585*4882a593Smuzhiyun }
586*4882a593Smuzhiyun 
587*4882a593Smuzhiyun static inline int
pnfs_sync_inode(struct inode * inode,bool datasync)588*4882a593Smuzhiyun pnfs_sync_inode(struct inode *inode, bool datasync)
589*4882a593Smuzhiyun {
590*4882a593Smuzhiyun 	if (!pnfs_enabled_sb(NFS_SERVER(inode)))
591*4882a593Smuzhiyun 		return 0;
592*4882a593Smuzhiyun 	return NFS_SERVER(inode)->pnfs_curr_ld->sync(inode, datasync);
593*4882a593Smuzhiyun }
594*4882a593Smuzhiyun 
595*4882a593Smuzhiyun static inline bool
pnfs_layoutcommit_outstanding(struct inode * inode)596*4882a593Smuzhiyun pnfs_layoutcommit_outstanding(struct inode *inode)
597*4882a593Smuzhiyun {
598*4882a593Smuzhiyun 	struct nfs_inode *nfsi = NFS_I(inode);
599*4882a593Smuzhiyun 
600*4882a593Smuzhiyun 	return test_bit(NFS_INO_LAYOUTCOMMIT, &nfsi->flags) != 0 ||
601*4882a593Smuzhiyun 		test_bit(NFS_INO_LAYOUTCOMMITTING, &nfsi->flags) != 0;
602*4882a593Smuzhiyun }
603*4882a593Smuzhiyun 
pnfs_return_layout(struct inode * ino)604*4882a593Smuzhiyun static inline int pnfs_return_layout(struct inode *ino)
605*4882a593Smuzhiyun {
606*4882a593Smuzhiyun 	struct nfs_inode *nfsi = NFS_I(ino);
607*4882a593Smuzhiyun 	struct nfs_server *nfss = NFS_SERVER(ino);
608*4882a593Smuzhiyun 
609*4882a593Smuzhiyun 	if (pnfs_enabled_sb(nfss) && nfsi->layout) {
610*4882a593Smuzhiyun 		set_bit(NFS_LAYOUT_RETURN_REQUESTED, &nfsi->layout->plh_flags);
611*4882a593Smuzhiyun 		return _pnfs_return_layout(ino);
612*4882a593Smuzhiyun 	}
613*4882a593Smuzhiyun 
614*4882a593Smuzhiyun 	return 0;
615*4882a593Smuzhiyun }
616*4882a593Smuzhiyun 
617*4882a593Smuzhiyun static inline bool
pnfs_use_threshold(struct nfs4_threshold ** dst,struct nfs4_threshold * src,struct nfs_server * nfss)618*4882a593Smuzhiyun pnfs_use_threshold(struct nfs4_threshold **dst, struct nfs4_threshold *src,
619*4882a593Smuzhiyun 		   struct nfs_server *nfss)
620*4882a593Smuzhiyun {
621*4882a593Smuzhiyun 	return (dst && src && src->bm != 0 && nfss->pnfs_curr_ld &&
622*4882a593Smuzhiyun 					nfss->pnfs_curr_ld->id == src->l_type);
623*4882a593Smuzhiyun }
624*4882a593Smuzhiyun 
625*4882a593Smuzhiyun static inline u64
pnfs_calc_offset_end(u64 offset,u64 len)626*4882a593Smuzhiyun pnfs_calc_offset_end(u64 offset, u64 len)
627*4882a593Smuzhiyun {
628*4882a593Smuzhiyun 	if (len == NFS4_MAX_UINT64 || len >= NFS4_MAX_UINT64 - offset)
629*4882a593Smuzhiyun 		return NFS4_MAX_UINT64;
630*4882a593Smuzhiyun 	return offset + len - 1;
631*4882a593Smuzhiyun }
632*4882a593Smuzhiyun 
633*4882a593Smuzhiyun static inline u64
pnfs_calc_offset_length(u64 offset,u64 end)634*4882a593Smuzhiyun pnfs_calc_offset_length(u64 offset, u64 end)
635*4882a593Smuzhiyun {
636*4882a593Smuzhiyun 	if (end == NFS4_MAX_UINT64 || end <= offset)
637*4882a593Smuzhiyun 		return NFS4_MAX_UINT64;
638*4882a593Smuzhiyun 	return 1 + end - offset;
639*4882a593Smuzhiyun }
640*4882a593Smuzhiyun 
641*4882a593Smuzhiyun static inline void
pnfs_copy_range(struct pnfs_layout_range * dst,const struct pnfs_layout_range * src)642*4882a593Smuzhiyun pnfs_copy_range(struct pnfs_layout_range *dst,
643*4882a593Smuzhiyun 		const struct pnfs_layout_range *src)
644*4882a593Smuzhiyun {
645*4882a593Smuzhiyun 	memcpy(dst, src, sizeof(*dst));
646*4882a593Smuzhiyun }
647*4882a593Smuzhiyun 
648*4882a593Smuzhiyun static inline u64
pnfs_end_offset(u64 start,u64 len)649*4882a593Smuzhiyun pnfs_end_offset(u64 start, u64 len)
650*4882a593Smuzhiyun {
651*4882a593Smuzhiyun 	if (NFS4_MAX_UINT64 - start <= len)
652*4882a593Smuzhiyun 		return NFS4_MAX_UINT64;
653*4882a593Smuzhiyun 	return start + len;
654*4882a593Smuzhiyun }
655*4882a593Smuzhiyun 
656*4882a593Smuzhiyun /*
657*4882a593Smuzhiyun  * Are 2 ranges intersecting?
658*4882a593Smuzhiyun  *   start1                             end1
659*4882a593Smuzhiyun  *   [----------------------------------)
660*4882a593Smuzhiyun  *                                start2           end2
661*4882a593Smuzhiyun  *                                [----------------)
662*4882a593Smuzhiyun  */
663*4882a593Smuzhiyun static inline bool
pnfs_is_range_intersecting(u64 start1,u64 end1,u64 start2,u64 end2)664*4882a593Smuzhiyun pnfs_is_range_intersecting(u64 start1, u64 end1, u64 start2, u64 end2)
665*4882a593Smuzhiyun {
666*4882a593Smuzhiyun 	return (end1 == NFS4_MAX_UINT64 || start2 < end1) &&
667*4882a593Smuzhiyun 		(end2 == NFS4_MAX_UINT64 || start1 < end2);
668*4882a593Smuzhiyun }
669*4882a593Smuzhiyun 
670*4882a593Smuzhiyun static inline bool
pnfs_lseg_range_intersecting(const struct pnfs_layout_range * l1,const struct pnfs_layout_range * l2)671*4882a593Smuzhiyun pnfs_lseg_range_intersecting(const struct pnfs_layout_range *l1,
672*4882a593Smuzhiyun 		const struct pnfs_layout_range *l2)
673*4882a593Smuzhiyun {
674*4882a593Smuzhiyun 	u64 end1 = pnfs_end_offset(l1->offset, l1->length);
675*4882a593Smuzhiyun 	u64 end2 = pnfs_end_offset(l2->offset, l2->length);
676*4882a593Smuzhiyun 
677*4882a593Smuzhiyun 	return pnfs_is_range_intersecting(l1->offset, end1, l2->offset, end2);
678*4882a593Smuzhiyun }
679*4882a593Smuzhiyun 
680*4882a593Smuzhiyun static inline bool
pnfs_lseg_request_intersecting(struct pnfs_layout_segment * lseg,struct nfs_page * req)681*4882a593Smuzhiyun pnfs_lseg_request_intersecting(struct pnfs_layout_segment *lseg, struct nfs_page *req)
682*4882a593Smuzhiyun {
683*4882a593Smuzhiyun 	u64 seg_last = pnfs_end_offset(lseg->pls_range.offset, lseg->pls_range.length);
684*4882a593Smuzhiyun 	u64 req_last = req_offset(req) + req->wb_bytes;
685*4882a593Smuzhiyun 
686*4882a593Smuzhiyun 	return pnfs_is_range_intersecting(lseg->pls_range.offset, seg_last,
687*4882a593Smuzhiyun 				req_offset(req), req_last);
688*4882a593Smuzhiyun }
689*4882a593Smuzhiyun 
690*4882a593Smuzhiyun extern unsigned int layoutstats_timer;
691*4882a593Smuzhiyun 
692*4882a593Smuzhiyun #ifdef NFS_DEBUG
693*4882a593Smuzhiyun void nfs4_print_deviceid(const struct nfs4_deviceid *dev_id);
694*4882a593Smuzhiyun #else
nfs4_print_deviceid(const struct nfs4_deviceid * dev_id)695*4882a593Smuzhiyun static inline void nfs4_print_deviceid(const struct nfs4_deviceid *dev_id)
696*4882a593Smuzhiyun {
697*4882a593Smuzhiyun }
698*4882a593Smuzhiyun 
699*4882a593Smuzhiyun #endif /* NFS_DEBUG */
700*4882a593Smuzhiyun #else  /* CONFIG_NFS_V4_1 */
701*4882a593Smuzhiyun 
nfs_have_layout(struct inode * inode)702*4882a593Smuzhiyun static inline bool nfs_have_layout(struct inode *inode)
703*4882a593Smuzhiyun {
704*4882a593Smuzhiyun 	return false;
705*4882a593Smuzhiyun }
706*4882a593Smuzhiyun 
pnfs_destroy_all_layouts(struct nfs_client * clp)707*4882a593Smuzhiyun static inline void pnfs_destroy_all_layouts(struct nfs_client *clp)
708*4882a593Smuzhiyun {
709*4882a593Smuzhiyun }
710*4882a593Smuzhiyun 
pnfs_destroy_layout(struct nfs_inode * nfsi)711*4882a593Smuzhiyun static inline void pnfs_destroy_layout(struct nfs_inode *nfsi)
712*4882a593Smuzhiyun {
713*4882a593Smuzhiyun }
714*4882a593Smuzhiyun 
pnfs_destroy_layout_final(struct nfs_inode * nfsi)715*4882a593Smuzhiyun static inline void pnfs_destroy_layout_final(struct nfs_inode *nfsi)
716*4882a593Smuzhiyun {
717*4882a593Smuzhiyun }
718*4882a593Smuzhiyun 
719*4882a593Smuzhiyun static inline struct pnfs_layout_segment *
pnfs_get_lseg(struct pnfs_layout_segment * lseg)720*4882a593Smuzhiyun pnfs_get_lseg(struct pnfs_layout_segment *lseg)
721*4882a593Smuzhiyun {
722*4882a593Smuzhiyun 	return NULL;
723*4882a593Smuzhiyun }
724*4882a593Smuzhiyun 
pnfs_put_lseg(struct pnfs_layout_segment * lseg)725*4882a593Smuzhiyun static inline void pnfs_put_lseg(struct pnfs_layout_segment *lseg)
726*4882a593Smuzhiyun {
727*4882a593Smuzhiyun }
728*4882a593Smuzhiyun 
pnfs_return_layout(struct inode * ino)729*4882a593Smuzhiyun static inline int pnfs_return_layout(struct inode *ino)
730*4882a593Smuzhiyun {
731*4882a593Smuzhiyun 	return 0;
732*4882a593Smuzhiyun }
733*4882a593Smuzhiyun 
pnfs_commit_and_return_layout(struct inode * inode)734*4882a593Smuzhiyun static inline int pnfs_commit_and_return_layout(struct inode *inode)
735*4882a593Smuzhiyun {
736*4882a593Smuzhiyun 	return 0;
737*4882a593Smuzhiyun }
738*4882a593Smuzhiyun 
739*4882a593Smuzhiyun static inline bool
pnfs_ld_layoutret_on_setattr(struct inode * inode)740*4882a593Smuzhiyun pnfs_ld_layoutret_on_setattr(struct inode *inode)
741*4882a593Smuzhiyun {
742*4882a593Smuzhiyun 	return false;
743*4882a593Smuzhiyun }
744*4882a593Smuzhiyun 
745*4882a593Smuzhiyun static inline bool
pnfs_ld_read_whole_page(struct inode * inode)746*4882a593Smuzhiyun pnfs_ld_read_whole_page(struct inode *inode)
747*4882a593Smuzhiyun {
748*4882a593Smuzhiyun 	return false;
749*4882a593Smuzhiyun }
750*4882a593Smuzhiyun 
751*4882a593Smuzhiyun static inline int
pnfs_sync_inode(struct inode * inode,bool datasync)752*4882a593Smuzhiyun pnfs_sync_inode(struct inode *inode, bool datasync)
753*4882a593Smuzhiyun {
754*4882a593Smuzhiyun 	return 0;
755*4882a593Smuzhiyun }
756*4882a593Smuzhiyun 
757*4882a593Smuzhiyun static inline bool
pnfs_layoutcommit_outstanding(struct inode * inode)758*4882a593Smuzhiyun pnfs_layoutcommit_outstanding(struct inode *inode)
759*4882a593Smuzhiyun {
760*4882a593Smuzhiyun 	return false;
761*4882a593Smuzhiyun }
762*4882a593Smuzhiyun 
763*4882a593Smuzhiyun 
764*4882a593Smuzhiyun static inline bool
pnfs_roc(struct inode * ino,struct nfs4_layoutreturn_args * args,struct nfs4_layoutreturn_res * res,const struct cred * cred)765*4882a593Smuzhiyun pnfs_roc(struct inode *ino,
766*4882a593Smuzhiyun 		struct nfs4_layoutreturn_args *args,
767*4882a593Smuzhiyun 		struct nfs4_layoutreturn_res *res,
768*4882a593Smuzhiyun 		const struct cred *cred)
769*4882a593Smuzhiyun {
770*4882a593Smuzhiyun 	return false;
771*4882a593Smuzhiyun }
772*4882a593Smuzhiyun 
773*4882a593Smuzhiyun static inline int
pnfs_roc_done(struct rpc_task * task,struct nfs4_layoutreturn_args ** argpp,struct nfs4_layoutreturn_res ** respp,int * ret)774*4882a593Smuzhiyun pnfs_roc_done(struct rpc_task *task,
775*4882a593Smuzhiyun 		struct nfs4_layoutreturn_args **argpp,
776*4882a593Smuzhiyun 		struct nfs4_layoutreturn_res **respp,
777*4882a593Smuzhiyun 		int *ret)
778*4882a593Smuzhiyun {
779*4882a593Smuzhiyun 	return 0;
780*4882a593Smuzhiyun }
781*4882a593Smuzhiyun 
782*4882a593Smuzhiyun static inline void
pnfs_roc_release(struct nfs4_layoutreturn_args * args,struct nfs4_layoutreturn_res * res,int ret)783*4882a593Smuzhiyun pnfs_roc_release(struct nfs4_layoutreturn_args *args,
784*4882a593Smuzhiyun 		struct nfs4_layoutreturn_res *res,
785*4882a593Smuzhiyun 		int ret)
786*4882a593Smuzhiyun {
787*4882a593Smuzhiyun }
788*4882a593Smuzhiyun 
789*4882a593Smuzhiyun static inline bool
pnfs_wait_on_layoutreturn(struct inode * ino,struct rpc_task * task)790*4882a593Smuzhiyun pnfs_wait_on_layoutreturn(struct inode *ino, struct rpc_task *task)
791*4882a593Smuzhiyun {
792*4882a593Smuzhiyun 	return false;
793*4882a593Smuzhiyun }
794*4882a593Smuzhiyun 
set_pnfs_layoutdriver(struct nfs_server * s,const struct nfs_fh * mntfh,struct nfs_fsinfo * fsinfo)795*4882a593Smuzhiyun static inline void set_pnfs_layoutdriver(struct nfs_server *s,
796*4882a593Smuzhiyun 					 const struct nfs_fh *mntfh,
797*4882a593Smuzhiyun 					 struct nfs_fsinfo *fsinfo)
798*4882a593Smuzhiyun {
799*4882a593Smuzhiyun }
800*4882a593Smuzhiyun 
unset_pnfs_layoutdriver(struct nfs_server * s)801*4882a593Smuzhiyun static inline void unset_pnfs_layoutdriver(struct nfs_server *s)
802*4882a593Smuzhiyun {
803*4882a593Smuzhiyun }
804*4882a593Smuzhiyun 
805*4882a593Smuzhiyun static inline int
pnfs_commit_list(struct inode * inode,struct list_head * mds_pages,int how,struct nfs_commit_info * cinfo)806*4882a593Smuzhiyun pnfs_commit_list(struct inode *inode, struct list_head *mds_pages, int how,
807*4882a593Smuzhiyun 		 struct nfs_commit_info *cinfo)
808*4882a593Smuzhiyun {
809*4882a593Smuzhiyun 	return PNFS_NOT_ATTEMPTED;
810*4882a593Smuzhiyun }
811*4882a593Smuzhiyun 
812*4882a593Smuzhiyun static inline struct pnfs_ds_commit_info *
pnfs_get_ds_info(struct inode * inode)813*4882a593Smuzhiyun pnfs_get_ds_info(struct inode *inode)
814*4882a593Smuzhiyun {
815*4882a593Smuzhiyun 	return NULL;
816*4882a593Smuzhiyun }
817*4882a593Smuzhiyun 
818*4882a593Smuzhiyun static inline void
pnfs_init_ds_commit_info_ops(struct pnfs_ds_commit_info * fl_cinfo,struct inode * inode)819*4882a593Smuzhiyun pnfs_init_ds_commit_info_ops(struct pnfs_ds_commit_info *fl_cinfo, struct inode *inode)
820*4882a593Smuzhiyun {
821*4882a593Smuzhiyun }
822*4882a593Smuzhiyun 
823*4882a593Smuzhiyun static inline void
pnfs_init_ds_commit_info(struct pnfs_ds_commit_info * fl_cinfo)824*4882a593Smuzhiyun pnfs_init_ds_commit_info(struct pnfs_ds_commit_info *fl_cinfo)
825*4882a593Smuzhiyun {
826*4882a593Smuzhiyun }
827*4882a593Smuzhiyun 
828*4882a593Smuzhiyun static inline void
pnfs_release_ds_info(struct pnfs_ds_commit_info * fl_cinfo,struct inode * inode)829*4882a593Smuzhiyun pnfs_release_ds_info(struct pnfs_ds_commit_info *fl_cinfo, struct inode *inode)
830*4882a593Smuzhiyun {
831*4882a593Smuzhiyun }
832*4882a593Smuzhiyun 
833*4882a593Smuzhiyun static inline bool
pnfs_mark_request_commit(struct nfs_page * req,struct pnfs_layout_segment * lseg,struct nfs_commit_info * cinfo,u32 ds_commit_idx)834*4882a593Smuzhiyun pnfs_mark_request_commit(struct nfs_page *req, struct pnfs_layout_segment *lseg,
835*4882a593Smuzhiyun 			 struct nfs_commit_info *cinfo, u32 ds_commit_idx)
836*4882a593Smuzhiyun {
837*4882a593Smuzhiyun 	return false;
838*4882a593Smuzhiyun }
839*4882a593Smuzhiyun 
840*4882a593Smuzhiyun static inline bool
pnfs_clear_request_commit(struct nfs_page * req,struct nfs_commit_info * cinfo)841*4882a593Smuzhiyun pnfs_clear_request_commit(struct nfs_page *req, struct nfs_commit_info *cinfo)
842*4882a593Smuzhiyun {
843*4882a593Smuzhiyun 	return false;
844*4882a593Smuzhiyun }
845*4882a593Smuzhiyun 
846*4882a593Smuzhiyun static inline int
pnfs_scan_commit_lists(struct inode * inode,struct nfs_commit_info * cinfo,int max)847*4882a593Smuzhiyun pnfs_scan_commit_lists(struct inode *inode, struct nfs_commit_info *cinfo,
848*4882a593Smuzhiyun 		       int max)
849*4882a593Smuzhiyun {
850*4882a593Smuzhiyun 	return 0;
851*4882a593Smuzhiyun }
852*4882a593Smuzhiyun 
853*4882a593Smuzhiyun static inline void
pnfs_recover_commit_reqs(struct list_head * head,struct nfs_commit_info * cinfo)854*4882a593Smuzhiyun pnfs_recover_commit_reqs(struct list_head *head, struct nfs_commit_info *cinfo)
855*4882a593Smuzhiyun {
856*4882a593Smuzhiyun }
857*4882a593Smuzhiyun 
858*4882a593Smuzhiyun static inline struct nfs_page *
pnfs_search_commit_reqs(struct inode * inode,struct nfs_commit_info * cinfo,struct page * page)859*4882a593Smuzhiyun pnfs_search_commit_reqs(struct inode *inode, struct nfs_commit_info *cinfo,
860*4882a593Smuzhiyun 			struct page *page)
861*4882a593Smuzhiyun {
862*4882a593Smuzhiyun 	return NULL;
863*4882a593Smuzhiyun }
864*4882a593Smuzhiyun 
pnfs_layoutcommit_inode(struct inode * inode,bool sync)865*4882a593Smuzhiyun static inline int pnfs_layoutcommit_inode(struct inode *inode, bool sync)
866*4882a593Smuzhiyun {
867*4882a593Smuzhiyun 	return 0;
868*4882a593Smuzhiyun }
869*4882a593Smuzhiyun 
870*4882a593Smuzhiyun static inline bool
pnfs_use_threshold(struct nfs4_threshold ** dst,struct nfs4_threshold * src,struct nfs_server * nfss)871*4882a593Smuzhiyun pnfs_use_threshold(struct nfs4_threshold **dst, struct nfs4_threshold *src,
872*4882a593Smuzhiyun 		   struct nfs_server *nfss)
873*4882a593Smuzhiyun {
874*4882a593Smuzhiyun 	return false;
875*4882a593Smuzhiyun }
876*4882a593Smuzhiyun 
pnfs_mdsthreshold_alloc(void)877*4882a593Smuzhiyun static inline struct nfs4_threshold *pnfs_mdsthreshold_alloc(void)
878*4882a593Smuzhiyun {
879*4882a593Smuzhiyun 	return NULL;
880*4882a593Smuzhiyun }
881*4882a593Smuzhiyun 
nfs4_pnfs_v3_ds_connect_unload(void)882*4882a593Smuzhiyun static inline void nfs4_pnfs_v3_ds_connect_unload(void)
883*4882a593Smuzhiyun {
884*4882a593Smuzhiyun }
885*4882a593Smuzhiyun 
nfs4_layout_refresh_old_stateid(nfs4_stateid * dst,struct pnfs_layout_range * dst_range,struct inode * inode)886*4882a593Smuzhiyun static inline bool nfs4_layout_refresh_old_stateid(nfs4_stateid *dst,
887*4882a593Smuzhiyun 		struct pnfs_layout_range *dst_range,
888*4882a593Smuzhiyun 		struct inode *inode)
889*4882a593Smuzhiyun {
890*4882a593Smuzhiyun 	return false;
891*4882a593Smuzhiyun }
892*4882a593Smuzhiyun 
pnfs_lgopen_prepare(struct nfs4_opendata * data,struct nfs_open_context * ctx)893*4882a593Smuzhiyun static inline void pnfs_lgopen_prepare(struct nfs4_opendata *data,
894*4882a593Smuzhiyun 		struct nfs_open_context *ctx)
895*4882a593Smuzhiyun {
896*4882a593Smuzhiyun }
897*4882a593Smuzhiyun 
pnfs_parse_lgopen(struct inode * ino,struct nfs4_layoutget * lgp,struct nfs_open_context * ctx)898*4882a593Smuzhiyun static inline void pnfs_parse_lgopen(struct inode *ino,
899*4882a593Smuzhiyun 		struct nfs4_layoutget *lgp,
900*4882a593Smuzhiyun 		struct nfs_open_context *ctx)
901*4882a593Smuzhiyun {
902*4882a593Smuzhiyun }
903*4882a593Smuzhiyun 
nfs4_lgopen_release(struct nfs4_layoutget * lgp)904*4882a593Smuzhiyun static inline void nfs4_lgopen_release(struct nfs4_layoutget *lgp)
905*4882a593Smuzhiyun {
906*4882a593Smuzhiyun }
907*4882a593Smuzhiyun 
pnfs_layout_is_valid(const struct pnfs_layout_hdr * lo)908*4882a593Smuzhiyun static inline bool pnfs_layout_is_valid(const struct pnfs_layout_hdr *lo)
909*4882a593Smuzhiyun {
910*4882a593Smuzhiyun 	return false;
911*4882a593Smuzhiyun }
912*4882a593Smuzhiyun 
913*4882a593Smuzhiyun #endif /* CONFIG_NFS_V4_1 */
914*4882a593Smuzhiyun 
915*4882a593Smuzhiyun #if IS_ENABLED(CONFIG_NFS_V4_2)
916*4882a593Smuzhiyun int pnfs_report_layoutstat(struct inode *inode, gfp_t gfp_flags);
917*4882a593Smuzhiyun #else
918*4882a593Smuzhiyun static inline int
pnfs_report_layoutstat(struct inode * inode,gfp_t gfp_flags)919*4882a593Smuzhiyun pnfs_report_layoutstat(struct inode *inode, gfp_t gfp_flags)
920*4882a593Smuzhiyun {
921*4882a593Smuzhiyun 	return 0;
922*4882a593Smuzhiyun }
923*4882a593Smuzhiyun #endif
924*4882a593Smuzhiyun 
925*4882a593Smuzhiyun #endif /* FS_NFS_PNFS_H */
926