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