cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

pnfs.h (28150B)


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