18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * NFS internal definitions
48c2ecf20Sopenharmony_ci */
58c2ecf20Sopenharmony_ci
68c2ecf20Sopenharmony_ci#include "nfs4_fs.h"
78c2ecf20Sopenharmony_ci#include <linux/fs_context.h>
88c2ecf20Sopenharmony_ci#include <linux/security.h>
98c2ecf20Sopenharmony_ci#include <linux/crc32.h>
108c2ecf20Sopenharmony_ci#include <linux/sunrpc/addr.h>
118c2ecf20Sopenharmony_ci#include <linux/nfs_page.h>
128c2ecf20Sopenharmony_ci#include <linux/wait_bit.h>
138c2ecf20Sopenharmony_ci
148c2ecf20Sopenharmony_ci#define NFS_SB_MASK (SB_RDONLY|SB_NOSUID|SB_NODEV|SB_NOEXEC|SB_SYNCHRONOUS)
158c2ecf20Sopenharmony_ci
168c2ecf20Sopenharmony_ciextern const struct export_operations nfs_export_ops;
178c2ecf20Sopenharmony_ci
188c2ecf20Sopenharmony_cistruct nfs_string;
198c2ecf20Sopenharmony_cistruct nfs_pageio_descriptor;
208c2ecf20Sopenharmony_ci
218c2ecf20Sopenharmony_cistatic inline void nfs_attr_check_mountpoint(struct super_block *parent, struct nfs_fattr *fattr)
228c2ecf20Sopenharmony_ci{
238c2ecf20Sopenharmony_ci	if (!nfs_fsid_equal(&NFS_SB(parent)->fsid, &fattr->fsid))
248c2ecf20Sopenharmony_ci		fattr->valid |= NFS_ATTR_FATTR_MOUNTPOINT;
258c2ecf20Sopenharmony_ci}
268c2ecf20Sopenharmony_ci
278c2ecf20Sopenharmony_cistatic inline int nfs_attr_use_mounted_on_fileid(struct nfs_fattr *fattr)
288c2ecf20Sopenharmony_ci{
298c2ecf20Sopenharmony_ci	if (((fattr->valid & NFS_ATTR_FATTR_MOUNTED_ON_FILEID) == 0) ||
308c2ecf20Sopenharmony_ci	    (((fattr->valid & NFS_ATTR_FATTR_MOUNTPOINT) == 0) &&
318c2ecf20Sopenharmony_ci	     ((fattr->valid & NFS_ATTR_FATTR_V4_REFERRAL) == 0)))
328c2ecf20Sopenharmony_ci		return 0;
338c2ecf20Sopenharmony_ci	return 1;
348c2ecf20Sopenharmony_ci}
358c2ecf20Sopenharmony_ci
368c2ecf20Sopenharmony_cistatic inline bool nfs_lookup_is_soft_revalidate(const struct dentry *dentry)
378c2ecf20Sopenharmony_ci{
388c2ecf20Sopenharmony_ci	if (!(NFS_SB(dentry->d_sb)->flags & NFS_MOUNT_SOFTREVAL))
398c2ecf20Sopenharmony_ci		return false;
408c2ecf20Sopenharmony_ci	if (!d_is_positive(dentry) || !NFS_FH(d_inode(dentry))->size)
418c2ecf20Sopenharmony_ci		return false;
428c2ecf20Sopenharmony_ci	return true;
438c2ecf20Sopenharmony_ci}
448c2ecf20Sopenharmony_ci
458c2ecf20Sopenharmony_cistatic inline fmode_t flags_to_mode(int flags)
468c2ecf20Sopenharmony_ci{
478c2ecf20Sopenharmony_ci	fmode_t res = (__force fmode_t)flags & FMODE_EXEC;
488c2ecf20Sopenharmony_ci	if ((flags & O_ACCMODE) != O_WRONLY)
498c2ecf20Sopenharmony_ci		res |= FMODE_READ;
508c2ecf20Sopenharmony_ci	if ((flags & O_ACCMODE) != O_RDONLY)
518c2ecf20Sopenharmony_ci		res |= FMODE_WRITE;
528c2ecf20Sopenharmony_ci	return res;
538c2ecf20Sopenharmony_ci}
548c2ecf20Sopenharmony_ci
558c2ecf20Sopenharmony_ci/*
568c2ecf20Sopenharmony_ci * Note: RFC 1813 doesn't limit the number of auth flavors that
578c2ecf20Sopenharmony_ci * a server can return, so make something up.
588c2ecf20Sopenharmony_ci */
598c2ecf20Sopenharmony_ci#define NFS_MAX_SECFLAVORS	(12)
608c2ecf20Sopenharmony_ci
618c2ecf20Sopenharmony_ci/*
628c2ecf20Sopenharmony_ci * Value used if the user did not specify a port value.
638c2ecf20Sopenharmony_ci */
648c2ecf20Sopenharmony_ci#define NFS_UNSPEC_PORT		(-1)
658c2ecf20Sopenharmony_ci
668c2ecf20Sopenharmony_ci#define NFS_UNSPEC_RETRANS	(UINT_MAX)
678c2ecf20Sopenharmony_ci#define NFS_UNSPEC_TIMEO	(UINT_MAX)
688c2ecf20Sopenharmony_ci
698c2ecf20Sopenharmony_ci/*
708c2ecf20Sopenharmony_ci * Maximum number of pages that readdir can use for creating
718c2ecf20Sopenharmony_ci * a vmapped array of pages.
728c2ecf20Sopenharmony_ci */
738c2ecf20Sopenharmony_ci#define NFS_MAX_READDIR_PAGES 8
748c2ecf20Sopenharmony_ci
758c2ecf20Sopenharmony_cistruct nfs_client_initdata {
768c2ecf20Sopenharmony_ci	unsigned long init_flags;
778c2ecf20Sopenharmony_ci	const char *hostname;			/* Hostname of the server */
788c2ecf20Sopenharmony_ci	const struct sockaddr *addr;		/* Address of the server */
798c2ecf20Sopenharmony_ci	const char *nodename;			/* Hostname of the client */
808c2ecf20Sopenharmony_ci	const char *ip_addr;			/* IP address of the client */
818c2ecf20Sopenharmony_ci	size_t addrlen;
828c2ecf20Sopenharmony_ci	struct nfs_subversion *nfs_mod;
838c2ecf20Sopenharmony_ci	int proto;
848c2ecf20Sopenharmony_ci	u32 minorversion;
858c2ecf20Sopenharmony_ci	unsigned int nconnect;
868c2ecf20Sopenharmony_ci	struct net *net;
878c2ecf20Sopenharmony_ci	const struct rpc_timeout *timeparms;
888c2ecf20Sopenharmony_ci	const struct cred *cred;
898c2ecf20Sopenharmony_ci};
908c2ecf20Sopenharmony_ci
918c2ecf20Sopenharmony_ci/*
928c2ecf20Sopenharmony_ci * In-kernel mount arguments
938c2ecf20Sopenharmony_ci */
948c2ecf20Sopenharmony_cistruct nfs_fs_context {
958c2ecf20Sopenharmony_ci	bool			internal;
968c2ecf20Sopenharmony_ci	bool			skip_reconfig_option_check;
978c2ecf20Sopenharmony_ci	bool			need_mount;
988c2ecf20Sopenharmony_ci	bool			sloppy;
998c2ecf20Sopenharmony_ci	unsigned int		flags;		/* NFS{,4}_MOUNT_* flags */
1008c2ecf20Sopenharmony_ci	unsigned int		rsize, wsize;
1018c2ecf20Sopenharmony_ci	unsigned int		timeo, retrans;
1028c2ecf20Sopenharmony_ci	unsigned int		acregmin, acregmax;
1038c2ecf20Sopenharmony_ci	unsigned int		acdirmin, acdirmax;
1048c2ecf20Sopenharmony_ci	unsigned int		namlen;
1058c2ecf20Sopenharmony_ci	unsigned int		options;
1068c2ecf20Sopenharmony_ci	unsigned int		bsize;
1078c2ecf20Sopenharmony_ci	struct nfs_auth_info	auth_info;
1088c2ecf20Sopenharmony_ci	rpc_authflavor_t	selected_flavor;
1098c2ecf20Sopenharmony_ci	char			*client_address;
1108c2ecf20Sopenharmony_ci	unsigned int		version;
1118c2ecf20Sopenharmony_ci	unsigned int		minorversion;
1128c2ecf20Sopenharmony_ci	char			*fscache_uniq;
1138c2ecf20Sopenharmony_ci	unsigned short		protofamily;
1148c2ecf20Sopenharmony_ci	unsigned short		mountfamily;
1158c2ecf20Sopenharmony_ci
1168c2ecf20Sopenharmony_ci	struct {
1178c2ecf20Sopenharmony_ci		union {
1188c2ecf20Sopenharmony_ci			struct sockaddr	address;
1198c2ecf20Sopenharmony_ci			struct sockaddr_storage	_address;
1208c2ecf20Sopenharmony_ci		};
1218c2ecf20Sopenharmony_ci		size_t			addrlen;
1228c2ecf20Sopenharmony_ci		char			*hostname;
1238c2ecf20Sopenharmony_ci		u32			version;
1248c2ecf20Sopenharmony_ci		int			port;
1258c2ecf20Sopenharmony_ci		unsigned short		protocol;
1268c2ecf20Sopenharmony_ci	} mount_server;
1278c2ecf20Sopenharmony_ci
1288c2ecf20Sopenharmony_ci	struct {
1298c2ecf20Sopenharmony_ci		union {
1308c2ecf20Sopenharmony_ci			struct sockaddr	address;
1318c2ecf20Sopenharmony_ci			struct sockaddr_storage	_address;
1328c2ecf20Sopenharmony_ci		};
1338c2ecf20Sopenharmony_ci		size_t			addrlen;
1348c2ecf20Sopenharmony_ci		char			*hostname;
1358c2ecf20Sopenharmony_ci		char			*export_path;
1368c2ecf20Sopenharmony_ci		int			port;
1378c2ecf20Sopenharmony_ci		unsigned short		protocol;
1388c2ecf20Sopenharmony_ci		unsigned short		nconnect;
1398c2ecf20Sopenharmony_ci		unsigned short		export_path_len;
1408c2ecf20Sopenharmony_ci	} nfs_server;
1418c2ecf20Sopenharmony_ci
1428c2ecf20Sopenharmony_ci	struct nfs_fh		*mntfh;
1438c2ecf20Sopenharmony_ci	struct nfs_server	*server;
1448c2ecf20Sopenharmony_ci	struct nfs_subversion	*nfs_mod;
1458c2ecf20Sopenharmony_ci
1468c2ecf20Sopenharmony_ci	/* Information for a cloned mount. */
1478c2ecf20Sopenharmony_ci	struct nfs_clone_mount {
1488c2ecf20Sopenharmony_ci		struct super_block	*sb;
1498c2ecf20Sopenharmony_ci		struct dentry		*dentry;
1508c2ecf20Sopenharmony_ci		struct nfs_fattr	*fattr;
1518c2ecf20Sopenharmony_ci		unsigned int		inherited_bsize;
1528c2ecf20Sopenharmony_ci	} clone_data;
1538c2ecf20Sopenharmony_ci};
1548c2ecf20Sopenharmony_ci
1558c2ecf20Sopenharmony_ci#define nfs_errorf(fc, fmt, ...) ((fc)->log.log ?		\
1568c2ecf20Sopenharmony_ci	errorf(fc, fmt, ## __VA_ARGS__) :			\
1578c2ecf20Sopenharmony_ci	({ dprintk(fmt "\n", ## __VA_ARGS__); }))
1588c2ecf20Sopenharmony_ci
1598c2ecf20Sopenharmony_ci#define nfs_ferrorf(fc, fac, fmt, ...) ((fc)->log.log ?		\
1608c2ecf20Sopenharmony_ci	errorf(fc, fmt, ## __VA_ARGS__) :			\
1618c2ecf20Sopenharmony_ci	({ dfprintk(fac, fmt "\n", ## __VA_ARGS__); }))
1628c2ecf20Sopenharmony_ci
1638c2ecf20Sopenharmony_ci#define nfs_invalf(fc, fmt, ...) ((fc)->log.log ?		\
1648c2ecf20Sopenharmony_ci	invalf(fc, fmt, ## __VA_ARGS__) :			\
1658c2ecf20Sopenharmony_ci	({ dprintk(fmt "\n", ## __VA_ARGS__);  -EINVAL; }))
1668c2ecf20Sopenharmony_ci
1678c2ecf20Sopenharmony_ci#define nfs_finvalf(fc, fac, fmt, ...) ((fc)->log.log ?		\
1688c2ecf20Sopenharmony_ci	invalf(fc, fmt, ## __VA_ARGS__) :			\
1698c2ecf20Sopenharmony_ci	({ dfprintk(fac, fmt "\n", ## __VA_ARGS__);  -EINVAL; }))
1708c2ecf20Sopenharmony_ci
1718c2ecf20Sopenharmony_ci#define nfs_warnf(fc, fmt, ...) ((fc)->log.log ?		\
1728c2ecf20Sopenharmony_ci	warnf(fc, fmt, ## __VA_ARGS__) :			\
1738c2ecf20Sopenharmony_ci	({ dprintk(fmt "\n", ## __VA_ARGS__); }))
1748c2ecf20Sopenharmony_ci
1758c2ecf20Sopenharmony_ci#define nfs_fwarnf(fc, fac, fmt, ...) ((fc)->log.log ?		\
1768c2ecf20Sopenharmony_ci	warnf(fc, fmt, ## __VA_ARGS__) :			\
1778c2ecf20Sopenharmony_ci	({ dfprintk(fac, fmt "\n", ## __VA_ARGS__); }))
1788c2ecf20Sopenharmony_ci
1798c2ecf20Sopenharmony_cistatic inline struct nfs_fs_context *nfs_fc2context(const struct fs_context *fc)
1808c2ecf20Sopenharmony_ci{
1818c2ecf20Sopenharmony_ci	return fc->fs_private;
1828c2ecf20Sopenharmony_ci}
1838c2ecf20Sopenharmony_ci
1848c2ecf20Sopenharmony_ci/* mount_clnt.c */
1858c2ecf20Sopenharmony_cistruct nfs_mount_request {
1868c2ecf20Sopenharmony_ci	struct sockaddr		*sap;
1878c2ecf20Sopenharmony_ci	size_t			salen;
1888c2ecf20Sopenharmony_ci	char			*hostname;
1898c2ecf20Sopenharmony_ci	char			*dirpath;
1908c2ecf20Sopenharmony_ci	u32			version;
1918c2ecf20Sopenharmony_ci	unsigned short		protocol;
1928c2ecf20Sopenharmony_ci	struct nfs_fh		*fh;
1938c2ecf20Sopenharmony_ci	int			noresvport;
1948c2ecf20Sopenharmony_ci	unsigned int		*auth_flav_len;
1958c2ecf20Sopenharmony_ci	rpc_authflavor_t	*auth_flavs;
1968c2ecf20Sopenharmony_ci	struct net		*net;
1978c2ecf20Sopenharmony_ci};
1988c2ecf20Sopenharmony_ci
1998c2ecf20Sopenharmony_ciextern int nfs_mount(struct nfs_mount_request *info);
2008c2ecf20Sopenharmony_ciextern void nfs_umount(const struct nfs_mount_request *info);
2018c2ecf20Sopenharmony_ci
2028c2ecf20Sopenharmony_ci/* client.c */
2038c2ecf20Sopenharmony_ciextern const struct rpc_program nfs_program;
2048c2ecf20Sopenharmony_ciextern void nfs_clients_init(struct net *net);
2058c2ecf20Sopenharmony_ciextern void nfs_clients_exit(struct net *net);
2068c2ecf20Sopenharmony_ciextern struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *);
2078c2ecf20Sopenharmony_ciint nfs_create_rpc_client(struct nfs_client *, const struct nfs_client_initdata *, rpc_authflavor_t);
2088c2ecf20Sopenharmony_cistruct nfs_client *nfs_get_client(const struct nfs_client_initdata *);
2098c2ecf20Sopenharmony_ciint nfs_probe_fsinfo(struct nfs_server *server, struct nfs_fh *, struct nfs_fattr *);
2108c2ecf20Sopenharmony_civoid nfs_server_insert_lists(struct nfs_server *);
2118c2ecf20Sopenharmony_civoid nfs_server_remove_lists(struct nfs_server *);
2128c2ecf20Sopenharmony_civoid nfs_init_timeout_values(struct rpc_timeout *to, int proto, int timeo, int retrans);
2138c2ecf20Sopenharmony_ciint nfs_init_server_rpcclient(struct nfs_server *, const struct rpc_timeout *t,
2148c2ecf20Sopenharmony_ci		rpc_authflavor_t);
2158c2ecf20Sopenharmony_cistruct nfs_server *nfs_alloc_server(void);
2168c2ecf20Sopenharmony_civoid nfs_server_copy_userdata(struct nfs_server *, struct nfs_server *);
2178c2ecf20Sopenharmony_ci
2188c2ecf20Sopenharmony_ciextern void nfs_put_client(struct nfs_client *);
2198c2ecf20Sopenharmony_ciextern void nfs_free_client(struct nfs_client *);
2208c2ecf20Sopenharmony_ciextern struct nfs_client *nfs4_find_client_ident(struct net *, int);
2218c2ecf20Sopenharmony_ciextern struct nfs_client *
2228c2ecf20Sopenharmony_cinfs4_find_client_sessionid(struct net *, const struct sockaddr *,
2238c2ecf20Sopenharmony_ci				struct nfs4_sessionid *, u32);
2248c2ecf20Sopenharmony_ciextern struct nfs_server *nfs_create_server(struct fs_context *);
2258c2ecf20Sopenharmony_ciextern struct nfs_server *nfs4_create_server(struct fs_context *);
2268c2ecf20Sopenharmony_ciextern struct nfs_server *nfs4_create_referral_server(struct fs_context *);
2278c2ecf20Sopenharmony_ciextern int nfs4_update_server(struct nfs_server *server, const char *hostname,
2288c2ecf20Sopenharmony_ci					struct sockaddr *sap, size_t salen,
2298c2ecf20Sopenharmony_ci					struct net *net);
2308c2ecf20Sopenharmony_ciextern void nfs_free_server(struct nfs_server *server);
2318c2ecf20Sopenharmony_ciextern struct nfs_server *nfs_clone_server(struct nfs_server *,
2328c2ecf20Sopenharmony_ci					   struct nfs_fh *,
2338c2ecf20Sopenharmony_ci					   struct nfs_fattr *,
2348c2ecf20Sopenharmony_ci					   rpc_authflavor_t);
2358c2ecf20Sopenharmony_ciextern bool nfs_client_init_is_complete(const struct nfs_client *clp);
2368c2ecf20Sopenharmony_ciextern int nfs_client_init_status(const struct nfs_client *clp);
2378c2ecf20Sopenharmony_ciextern int nfs_wait_client_init_complete(const struct nfs_client *clp);
2388c2ecf20Sopenharmony_ciextern void nfs_mark_client_ready(struct nfs_client *clp, int state);
2398c2ecf20Sopenharmony_ciextern struct nfs_client *nfs4_set_ds_client(struct nfs_server *mds_srv,
2408c2ecf20Sopenharmony_ci					     const struct sockaddr *ds_addr,
2418c2ecf20Sopenharmony_ci					     int ds_addrlen, int ds_proto,
2428c2ecf20Sopenharmony_ci					     unsigned int ds_timeo,
2438c2ecf20Sopenharmony_ci					     unsigned int ds_retrans,
2448c2ecf20Sopenharmony_ci					     u32 minor_version);
2458c2ecf20Sopenharmony_ciextern struct rpc_clnt *nfs4_find_or_create_ds_client(struct nfs_client *,
2468c2ecf20Sopenharmony_ci						struct inode *);
2478c2ecf20Sopenharmony_ciextern struct nfs_client *nfs3_set_ds_client(struct nfs_server *mds_srv,
2488c2ecf20Sopenharmony_ci			const struct sockaddr *ds_addr, int ds_addrlen,
2498c2ecf20Sopenharmony_ci			int ds_proto, unsigned int ds_timeo,
2508c2ecf20Sopenharmony_ci			unsigned int ds_retrans);
2518c2ecf20Sopenharmony_ci#ifdef CONFIG_PROC_FS
2528c2ecf20Sopenharmony_ciextern int __init nfs_fs_proc_init(void);
2538c2ecf20Sopenharmony_ciextern void nfs_fs_proc_exit(void);
2548c2ecf20Sopenharmony_ciextern int nfs_fs_proc_net_init(struct net *net);
2558c2ecf20Sopenharmony_ciextern void nfs_fs_proc_net_exit(struct net *net);
2568c2ecf20Sopenharmony_ci#else
2578c2ecf20Sopenharmony_cistatic inline int nfs_fs_proc_net_init(struct net *net)
2588c2ecf20Sopenharmony_ci{
2598c2ecf20Sopenharmony_ci	return 0;
2608c2ecf20Sopenharmony_ci}
2618c2ecf20Sopenharmony_cistatic inline void nfs_fs_proc_net_exit(struct net *net)
2628c2ecf20Sopenharmony_ci{
2638c2ecf20Sopenharmony_ci}
2648c2ecf20Sopenharmony_cistatic inline int nfs_fs_proc_init(void)
2658c2ecf20Sopenharmony_ci{
2668c2ecf20Sopenharmony_ci	return 0;
2678c2ecf20Sopenharmony_ci}
2688c2ecf20Sopenharmony_cistatic inline void nfs_fs_proc_exit(void)
2698c2ecf20Sopenharmony_ci{
2708c2ecf20Sopenharmony_ci}
2718c2ecf20Sopenharmony_ci#endif
2728c2ecf20Sopenharmony_ci
2738c2ecf20Sopenharmony_ci/* callback_xdr.c */
2748c2ecf20Sopenharmony_ciextern const struct svc_version nfs4_callback_version1;
2758c2ecf20Sopenharmony_ciextern const struct svc_version nfs4_callback_version4;
2768c2ecf20Sopenharmony_ci
2778c2ecf20Sopenharmony_ci/* fs_context.c */
2788c2ecf20Sopenharmony_ciextern struct file_system_type nfs_fs_type;
2798c2ecf20Sopenharmony_ci
2808c2ecf20Sopenharmony_ci/* pagelist.c */
2818c2ecf20Sopenharmony_ciextern int __init nfs_init_nfspagecache(void);
2828c2ecf20Sopenharmony_ciextern void nfs_destroy_nfspagecache(void);
2838c2ecf20Sopenharmony_ciextern int __init nfs_init_readpagecache(void);
2848c2ecf20Sopenharmony_ciextern void nfs_destroy_readpagecache(void);
2858c2ecf20Sopenharmony_ciextern int __init nfs_init_writepagecache(void);
2868c2ecf20Sopenharmony_ciextern void nfs_destroy_writepagecache(void);
2878c2ecf20Sopenharmony_ci
2888c2ecf20Sopenharmony_ciextern int __init nfs_init_directcache(void);
2898c2ecf20Sopenharmony_ciextern void nfs_destroy_directcache(void);
2908c2ecf20Sopenharmony_ciextern void nfs_pgheader_init(struct nfs_pageio_descriptor *desc,
2918c2ecf20Sopenharmony_ci			      struct nfs_pgio_header *hdr,
2928c2ecf20Sopenharmony_ci			      void (*release)(struct nfs_pgio_header *hdr));
2938c2ecf20Sopenharmony_civoid nfs_set_pgio_error(struct nfs_pgio_header *hdr, int error, loff_t pos);
2948c2ecf20Sopenharmony_ciint nfs_iocounter_wait(struct nfs_lock_context *l_ctx);
2958c2ecf20Sopenharmony_ci
2968c2ecf20Sopenharmony_ciextern const struct nfs_pageio_ops nfs_pgio_rw_ops;
2978c2ecf20Sopenharmony_cistruct nfs_pgio_header *nfs_pgio_header_alloc(const struct nfs_rw_ops *);
2988c2ecf20Sopenharmony_civoid nfs_pgio_header_free(struct nfs_pgio_header *);
2998c2ecf20Sopenharmony_ciint nfs_generic_pgio(struct nfs_pageio_descriptor *, struct nfs_pgio_header *);
3008c2ecf20Sopenharmony_ciint nfs_initiate_pgio(struct rpc_clnt *clnt, struct nfs_pgio_header *hdr,
3018c2ecf20Sopenharmony_ci		      const struct cred *cred, const struct nfs_rpc_ops *rpc_ops,
3028c2ecf20Sopenharmony_ci		      const struct rpc_call_ops *call_ops, int how, int flags);
3038c2ecf20Sopenharmony_civoid nfs_free_request(struct nfs_page *req);
3048c2ecf20Sopenharmony_cistruct nfs_pgio_mirror *
3058c2ecf20Sopenharmony_cinfs_pgio_current_mirror(struct nfs_pageio_descriptor *desc);
3068c2ecf20Sopenharmony_ci
3078c2ecf20Sopenharmony_cistatic inline bool nfs_match_open_context(const struct nfs_open_context *ctx1,
3088c2ecf20Sopenharmony_ci		const struct nfs_open_context *ctx2)
3098c2ecf20Sopenharmony_ci{
3108c2ecf20Sopenharmony_ci	return cred_fscmp(ctx1->cred, ctx2->cred) == 0 && ctx1->state == ctx2->state;
3118c2ecf20Sopenharmony_ci}
3128c2ecf20Sopenharmony_ci
3138c2ecf20Sopenharmony_ci/* nfs2xdr.c */
3148c2ecf20Sopenharmony_ciextern const struct rpc_procinfo nfs_procedures[];
3158c2ecf20Sopenharmony_ciextern int nfs2_decode_dirent(struct xdr_stream *,
3168c2ecf20Sopenharmony_ci				struct nfs_entry *, bool);
3178c2ecf20Sopenharmony_ci
3188c2ecf20Sopenharmony_ci/* nfs3xdr.c */
3198c2ecf20Sopenharmony_ciextern const struct rpc_procinfo nfs3_procedures[];
3208c2ecf20Sopenharmony_ciextern int nfs3_decode_dirent(struct xdr_stream *,
3218c2ecf20Sopenharmony_ci				struct nfs_entry *, bool);
3228c2ecf20Sopenharmony_ci
3238c2ecf20Sopenharmony_ci/* nfs4xdr.c */
3248c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_NFS_V4)
3258c2ecf20Sopenharmony_ciextern int nfs4_decode_dirent(struct xdr_stream *,
3268c2ecf20Sopenharmony_ci				struct nfs_entry *, bool);
3278c2ecf20Sopenharmony_ci#endif
3288c2ecf20Sopenharmony_ci#ifdef CONFIG_NFS_V4_1
3298c2ecf20Sopenharmony_ciextern const u32 nfs41_maxread_overhead;
3308c2ecf20Sopenharmony_ciextern const u32 nfs41_maxwrite_overhead;
3318c2ecf20Sopenharmony_ciextern const u32 nfs41_maxgetdevinfo_overhead;
3328c2ecf20Sopenharmony_ci#endif
3338c2ecf20Sopenharmony_ci
3348c2ecf20Sopenharmony_ci/* nfs4proc.c */
3358c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_NFS_V4)
3368c2ecf20Sopenharmony_ciextern const struct rpc_procinfo nfs4_procedures[];
3378c2ecf20Sopenharmony_ci#endif
3388c2ecf20Sopenharmony_ci
3398c2ecf20Sopenharmony_ci#ifdef CONFIG_NFS_V4_SECURITY_LABEL
3408c2ecf20Sopenharmony_ciextern struct nfs4_label *nfs4_label_alloc(struct nfs_server *server, gfp_t flags);
3418c2ecf20Sopenharmony_cistatic inline struct nfs4_label *
3428c2ecf20Sopenharmony_cinfs4_label_copy(struct nfs4_label *dst, struct nfs4_label *src)
3438c2ecf20Sopenharmony_ci{
3448c2ecf20Sopenharmony_ci	if (!dst || !src)
3458c2ecf20Sopenharmony_ci		return NULL;
3468c2ecf20Sopenharmony_ci
3478c2ecf20Sopenharmony_ci	if (src->len > NFS4_MAXLABELLEN)
3488c2ecf20Sopenharmony_ci		return NULL;
3498c2ecf20Sopenharmony_ci
3508c2ecf20Sopenharmony_ci	dst->lfs = src->lfs;
3518c2ecf20Sopenharmony_ci	dst->pi = src->pi;
3528c2ecf20Sopenharmony_ci	dst->len = src->len;
3538c2ecf20Sopenharmony_ci	memcpy(dst->label, src->label, src->len);
3548c2ecf20Sopenharmony_ci
3558c2ecf20Sopenharmony_ci	return dst;
3568c2ecf20Sopenharmony_ci}
3578c2ecf20Sopenharmony_cistatic inline void nfs4_label_free(struct nfs4_label *label)
3588c2ecf20Sopenharmony_ci{
3598c2ecf20Sopenharmony_ci	if (label) {
3608c2ecf20Sopenharmony_ci		kfree(label->label);
3618c2ecf20Sopenharmony_ci		kfree(label);
3628c2ecf20Sopenharmony_ci	}
3638c2ecf20Sopenharmony_ci	return;
3648c2ecf20Sopenharmony_ci}
3658c2ecf20Sopenharmony_ci
3668c2ecf20Sopenharmony_cistatic inline void nfs_zap_label_cache_locked(struct nfs_inode *nfsi)
3678c2ecf20Sopenharmony_ci{
3688c2ecf20Sopenharmony_ci	if (nfs_server_capable(&nfsi->vfs_inode, NFS_CAP_SECURITY_LABEL))
3698c2ecf20Sopenharmony_ci		nfsi->cache_validity |= NFS_INO_INVALID_LABEL;
3708c2ecf20Sopenharmony_ci}
3718c2ecf20Sopenharmony_ci#else
3728c2ecf20Sopenharmony_cistatic inline struct nfs4_label *nfs4_label_alloc(struct nfs_server *server, gfp_t flags) { return NULL; }
3738c2ecf20Sopenharmony_cistatic inline void nfs4_label_free(void *label) {}
3748c2ecf20Sopenharmony_cistatic inline void nfs_zap_label_cache_locked(struct nfs_inode *nfsi)
3758c2ecf20Sopenharmony_ci{
3768c2ecf20Sopenharmony_ci}
3778c2ecf20Sopenharmony_cistatic inline struct nfs4_label *
3788c2ecf20Sopenharmony_cinfs4_label_copy(struct nfs4_label *dst, struct nfs4_label *src)
3798c2ecf20Sopenharmony_ci{
3808c2ecf20Sopenharmony_ci	return NULL;
3818c2ecf20Sopenharmony_ci}
3828c2ecf20Sopenharmony_ci#endif /* CONFIG_NFS_V4_SECURITY_LABEL */
3838c2ecf20Sopenharmony_ci
3848c2ecf20Sopenharmony_ci/* proc.c */
3858c2ecf20Sopenharmony_civoid nfs_close_context(struct nfs_open_context *ctx, int is_sync);
3868c2ecf20Sopenharmony_ciextern struct nfs_client *nfs_init_client(struct nfs_client *clp,
3878c2ecf20Sopenharmony_ci			   const struct nfs_client_initdata *);
3888c2ecf20Sopenharmony_ci
3898c2ecf20Sopenharmony_ci/* dir.c */
3908c2ecf20Sopenharmony_ciextern void nfs_advise_use_readdirplus(struct inode *dir);
3918c2ecf20Sopenharmony_ciextern void nfs_force_use_readdirplus(struct inode *dir);
3928c2ecf20Sopenharmony_ciextern unsigned long nfs_access_cache_count(struct shrinker *shrink,
3938c2ecf20Sopenharmony_ci					    struct shrink_control *sc);
3948c2ecf20Sopenharmony_ciextern unsigned long nfs_access_cache_scan(struct shrinker *shrink,
3958c2ecf20Sopenharmony_ci					   struct shrink_control *sc);
3968c2ecf20Sopenharmony_cistruct dentry *nfs_lookup(struct inode *, struct dentry *, unsigned int);
3978c2ecf20Sopenharmony_ciint nfs_create(struct inode *, struct dentry *, umode_t, bool);
3988c2ecf20Sopenharmony_ciint nfs_mkdir(struct inode *, struct dentry *, umode_t);
3998c2ecf20Sopenharmony_ciint nfs_rmdir(struct inode *, struct dentry *);
4008c2ecf20Sopenharmony_ciint nfs_unlink(struct inode *, struct dentry *);
4018c2ecf20Sopenharmony_ciint nfs_symlink(struct inode *, struct dentry *, const char *);
4028c2ecf20Sopenharmony_ciint nfs_link(struct dentry *, struct inode *, struct dentry *);
4038c2ecf20Sopenharmony_ciint nfs_mknod(struct inode *, struct dentry *, umode_t, dev_t);
4048c2ecf20Sopenharmony_ciint nfs_rename(struct inode *, struct dentry *,
4058c2ecf20Sopenharmony_ci	       struct inode *, struct dentry *, unsigned int);
4068c2ecf20Sopenharmony_ci
4078c2ecf20Sopenharmony_ci/* file.c */
4088c2ecf20Sopenharmony_ciint nfs_file_fsync(struct file *file, loff_t start, loff_t end, int datasync);
4098c2ecf20Sopenharmony_ciloff_t nfs_file_llseek(struct file *, loff_t, int);
4108c2ecf20Sopenharmony_cissize_t nfs_file_read(struct kiocb *, struct iov_iter *);
4118c2ecf20Sopenharmony_ciint nfs_file_mmap(struct file *, struct vm_area_struct *);
4128c2ecf20Sopenharmony_cissize_t nfs_file_write(struct kiocb *, struct iov_iter *);
4138c2ecf20Sopenharmony_ciint nfs_file_release(struct inode *, struct file *);
4148c2ecf20Sopenharmony_ciint nfs_lock(struct file *, int, struct file_lock *);
4158c2ecf20Sopenharmony_ciint nfs_flock(struct file *, int, struct file_lock *);
4168c2ecf20Sopenharmony_ciint nfs_check_flags(int);
4178c2ecf20Sopenharmony_ci
4188c2ecf20Sopenharmony_ci/* inode.c */
4198c2ecf20Sopenharmony_ciextern struct workqueue_struct *nfsiod_workqueue;
4208c2ecf20Sopenharmony_ciextern struct inode *nfs_alloc_inode(struct super_block *sb);
4218c2ecf20Sopenharmony_ciextern void nfs_free_inode(struct inode *);
4228c2ecf20Sopenharmony_ciextern int nfs_write_inode(struct inode *, struct writeback_control *);
4238c2ecf20Sopenharmony_ciextern int nfs_drop_inode(struct inode *);
4248c2ecf20Sopenharmony_ciextern void nfs_clear_inode(struct inode *);
4258c2ecf20Sopenharmony_ciextern void nfs_evict_inode(struct inode *);
4268c2ecf20Sopenharmony_civoid nfs_zap_acl_cache(struct inode *inode);
4278c2ecf20Sopenharmony_ciextern bool nfs_check_cache_invalid(struct inode *, unsigned long);
4288c2ecf20Sopenharmony_ciextern int nfs_wait_bit_killable(struct wait_bit_key *key, int mode);
4298c2ecf20Sopenharmony_ciextern int nfs_wait_atomic_killable(atomic_t *p, unsigned int mode);
4308c2ecf20Sopenharmony_ci
4318c2ecf20Sopenharmony_ci/* super.c */
4328c2ecf20Sopenharmony_ciextern const struct super_operations nfs_sops;
4338c2ecf20Sopenharmony_cibool nfs_auth_info_match(const struct nfs_auth_info *, rpc_authflavor_t);
4348c2ecf20Sopenharmony_ciint nfs_try_get_tree(struct fs_context *);
4358c2ecf20Sopenharmony_ciint nfs_get_tree_common(struct fs_context *);
4368c2ecf20Sopenharmony_civoid nfs_kill_super(struct super_block *);
4378c2ecf20Sopenharmony_ci
4388c2ecf20Sopenharmony_ciextern int __init register_nfs_fs(void);
4398c2ecf20Sopenharmony_ciextern void __exit unregister_nfs_fs(void);
4408c2ecf20Sopenharmony_ciextern bool nfs_sb_active(struct super_block *sb);
4418c2ecf20Sopenharmony_ciextern void nfs_sb_deactive(struct super_block *sb);
4428c2ecf20Sopenharmony_ciextern int nfs_client_for_each_server(struct nfs_client *clp,
4438c2ecf20Sopenharmony_ci				      int (*fn)(struct nfs_server *, void *),
4448c2ecf20Sopenharmony_ci				      void *data);
4458c2ecf20Sopenharmony_ci/* io.c */
4468c2ecf20Sopenharmony_ciextern void nfs_start_io_read(struct inode *inode);
4478c2ecf20Sopenharmony_ciextern void nfs_end_io_read(struct inode *inode);
4488c2ecf20Sopenharmony_ciextern void nfs_start_io_write(struct inode *inode);
4498c2ecf20Sopenharmony_ciextern void nfs_end_io_write(struct inode *inode);
4508c2ecf20Sopenharmony_ciextern void nfs_start_io_direct(struct inode *inode);
4518c2ecf20Sopenharmony_ciextern void nfs_end_io_direct(struct inode *inode);
4528c2ecf20Sopenharmony_ci
4538c2ecf20Sopenharmony_cistatic inline bool nfs_file_io_is_buffered(struct nfs_inode *nfsi)
4548c2ecf20Sopenharmony_ci{
4558c2ecf20Sopenharmony_ci	return test_bit(NFS_INO_ODIRECT, &nfsi->flags) == 0;
4568c2ecf20Sopenharmony_ci}
4578c2ecf20Sopenharmony_ci
4588c2ecf20Sopenharmony_ci/* namespace.c */
4598c2ecf20Sopenharmony_ci#define NFS_PATH_CANONICAL 1
4608c2ecf20Sopenharmony_ciextern char *nfs_path(char **p, struct dentry *dentry,
4618c2ecf20Sopenharmony_ci		      char *buffer, ssize_t buflen, unsigned flags);
4628c2ecf20Sopenharmony_ciextern struct vfsmount *nfs_d_automount(struct path *path);
4638c2ecf20Sopenharmony_ciint nfs_submount(struct fs_context *, struct nfs_server *);
4648c2ecf20Sopenharmony_ciint nfs_do_submount(struct fs_context *);
4658c2ecf20Sopenharmony_ci
4668c2ecf20Sopenharmony_ci/* getroot.c */
4678c2ecf20Sopenharmony_ciextern int nfs_get_root(struct super_block *s, struct fs_context *fc);
4688c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_NFS_V4)
4698c2ecf20Sopenharmony_ciextern int nfs4_get_rootfh(struct nfs_server *server, struct nfs_fh *mntfh, bool);
4708c2ecf20Sopenharmony_ci#endif
4718c2ecf20Sopenharmony_ci
4728c2ecf20Sopenharmony_cistruct nfs_pgio_completion_ops;
4738c2ecf20Sopenharmony_ci/* read.c */
4748c2ecf20Sopenharmony_ciextern void nfs_pageio_init_read(struct nfs_pageio_descriptor *pgio,
4758c2ecf20Sopenharmony_ci			struct inode *inode, bool force_mds,
4768c2ecf20Sopenharmony_ci			const struct nfs_pgio_completion_ops *compl_ops);
4778c2ecf20Sopenharmony_ciextern void nfs_read_prepare(struct rpc_task *task, void *calldata);
4788c2ecf20Sopenharmony_ciextern void nfs_pageio_reset_read_mds(struct nfs_pageio_descriptor *pgio);
4798c2ecf20Sopenharmony_ci
4808c2ecf20Sopenharmony_ci/* super.c */
4818c2ecf20Sopenharmony_civoid nfs_umount_begin(struct super_block *);
4828c2ecf20Sopenharmony_ciint  nfs_statfs(struct dentry *, struct kstatfs *);
4838c2ecf20Sopenharmony_ciint  nfs_show_options(struct seq_file *, struct dentry *);
4848c2ecf20Sopenharmony_ciint  nfs_show_devname(struct seq_file *, struct dentry *);
4858c2ecf20Sopenharmony_ciint  nfs_show_path(struct seq_file *, struct dentry *);
4868c2ecf20Sopenharmony_ciint  nfs_show_stats(struct seq_file *, struct dentry *);
4878c2ecf20Sopenharmony_ciint  nfs_reconfigure(struct fs_context *);
4888c2ecf20Sopenharmony_ci
4898c2ecf20Sopenharmony_ci/* write.c */
4908c2ecf20Sopenharmony_ciextern void nfs_pageio_init_write(struct nfs_pageio_descriptor *pgio,
4918c2ecf20Sopenharmony_ci			struct inode *inode, int ioflags, bool force_mds,
4928c2ecf20Sopenharmony_ci			const struct nfs_pgio_completion_ops *compl_ops);
4938c2ecf20Sopenharmony_ciextern void nfs_pageio_reset_write_mds(struct nfs_pageio_descriptor *pgio);
4948c2ecf20Sopenharmony_ciextern void nfs_commit_free(struct nfs_commit_data *p);
4958c2ecf20Sopenharmony_ciextern void nfs_write_prepare(struct rpc_task *task, void *calldata);
4968c2ecf20Sopenharmony_ciextern void nfs_commit_prepare(struct rpc_task *task, void *calldata);
4978c2ecf20Sopenharmony_ciextern int nfs_initiate_commit(struct rpc_clnt *clnt,
4988c2ecf20Sopenharmony_ci			       struct nfs_commit_data *data,
4998c2ecf20Sopenharmony_ci			       const struct nfs_rpc_ops *nfs_ops,
5008c2ecf20Sopenharmony_ci			       const struct rpc_call_ops *call_ops,
5018c2ecf20Sopenharmony_ci			       int how, int flags);
5028c2ecf20Sopenharmony_ciextern void nfs_init_commit(struct nfs_commit_data *data,
5038c2ecf20Sopenharmony_ci			    struct list_head *head,
5048c2ecf20Sopenharmony_ci			    struct pnfs_layout_segment *lseg,
5058c2ecf20Sopenharmony_ci			    struct nfs_commit_info *cinfo);
5068c2ecf20Sopenharmony_ciint nfs_scan_commit_list(struct list_head *src, struct list_head *dst,
5078c2ecf20Sopenharmony_ci			 struct nfs_commit_info *cinfo, int max);
5088c2ecf20Sopenharmony_ciunsigned long nfs_reqs_to_commit(struct nfs_commit_info *);
5098c2ecf20Sopenharmony_ciint nfs_scan_commit(struct inode *inode, struct list_head *dst,
5108c2ecf20Sopenharmony_ci		    struct nfs_commit_info *cinfo);
5118c2ecf20Sopenharmony_civoid nfs_mark_request_commit(struct nfs_page *req,
5128c2ecf20Sopenharmony_ci			     struct pnfs_layout_segment *lseg,
5138c2ecf20Sopenharmony_ci			     struct nfs_commit_info *cinfo,
5148c2ecf20Sopenharmony_ci			     u32 ds_commit_idx);
5158c2ecf20Sopenharmony_ciint nfs_write_need_commit(struct nfs_pgio_header *);
5168c2ecf20Sopenharmony_civoid nfs_writeback_update_inode(struct nfs_pgio_header *hdr);
5178c2ecf20Sopenharmony_ciint nfs_generic_commit_list(struct inode *inode, struct list_head *head,
5188c2ecf20Sopenharmony_ci			    int how, struct nfs_commit_info *cinfo);
5198c2ecf20Sopenharmony_civoid nfs_retry_commit(struct list_head *page_list,
5208c2ecf20Sopenharmony_ci		      struct pnfs_layout_segment *lseg,
5218c2ecf20Sopenharmony_ci		      struct nfs_commit_info *cinfo,
5228c2ecf20Sopenharmony_ci		      u32 ds_commit_idx);
5238c2ecf20Sopenharmony_civoid nfs_commitdata_release(struct nfs_commit_data *data);
5248c2ecf20Sopenharmony_civoid nfs_request_add_commit_list(struct nfs_page *req,
5258c2ecf20Sopenharmony_ci				 struct nfs_commit_info *cinfo);
5268c2ecf20Sopenharmony_civoid nfs_request_add_commit_list_locked(struct nfs_page *req,
5278c2ecf20Sopenharmony_ci		struct list_head *dst,
5288c2ecf20Sopenharmony_ci		struct nfs_commit_info *cinfo);
5298c2ecf20Sopenharmony_civoid nfs_request_remove_commit_list(struct nfs_page *req,
5308c2ecf20Sopenharmony_ci				    struct nfs_commit_info *cinfo);
5318c2ecf20Sopenharmony_civoid nfs_init_cinfo(struct nfs_commit_info *cinfo,
5328c2ecf20Sopenharmony_ci		    struct inode *inode,
5338c2ecf20Sopenharmony_ci		    struct nfs_direct_req *dreq);
5348c2ecf20Sopenharmony_ciint nfs_key_timeout_notify(struct file *filp, struct inode *inode);
5358c2ecf20Sopenharmony_cibool nfs_ctx_key_to_expire(struct nfs_open_context *ctx, struct inode *inode);
5368c2ecf20Sopenharmony_civoid nfs_pageio_stop_mirroring(struct nfs_pageio_descriptor *pgio);
5378c2ecf20Sopenharmony_ci
5388c2ecf20Sopenharmony_ciint nfs_filemap_write_and_wait_range(struct address_space *mapping,
5398c2ecf20Sopenharmony_ci		loff_t lstart, loff_t lend);
5408c2ecf20Sopenharmony_ci
5418c2ecf20Sopenharmony_ci#ifdef CONFIG_NFS_V4_1
5428c2ecf20Sopenharmony_cistatic inline void
5438c2ecf20Sopenharmony_cipnfs_bucket_clear_pnfs_ds_commit_verifiers(struct pnfs_commit_bucket *buckets,
5448c2ecf20Sopenharmony_ci		unsigned int nbuckets)
5458c2ecf20Sopenharmony_ci{
5468c2ecf20Sopenharmony_ci	unsigned int i;
5478c2ecf20Sopenharmony_ci
5488c2ecf20Sopenharmony_ci	for (i = 0; i < nbuckets; i++)
5498c2ecf20Sopenharmony_ci		buckets[i].direct_verf.committed = NFS_INVALID_STABLE_HOW;
5508c2ecf20Sopenharmony_ci}
5518c2ecf20Sopenharmony_cistatic inline
5528c2ecf20Sopenharmony_civoid nfs_clear_pnfs_ds_commit_verifiers(struct pnfs_ds_commit_info *cinfo)
5538c2ecf20Sopenharmony_ci{
5548c2ecf20Sopenharmony_ci	struct pnfs_commit_array *array;
5558c2ecf20Sopenharmony_ci
5568c2ecf20Sopenharmony_ci	rcu_read_lock();
5578c2ecf20Sopenharmony_ci	list_for_each_entry_rcu(array, &cinfo->commits, cinfo_list)
5588c2ecf20Sopenharmony_ci		pnfs_bucket_clear_pnfs_ds_commit_verifiers(array->buckets,
5598c2ecf20Sopenharmony_ci				array->nbuckets);
5608c2ecf20Sopenharmony_ci	rcu_read_unlock();
5618c2ecf20Sopenharmony_ci}
5628c2ecf20Sopenharmony_ci#else
5638c2ecf20Sopenharmony_cistatic inline
5648c2ecf20Sopenharmony_civoid nfs_clear_pnfs_ds_commit_verifiers(struct pnfs_ds_commit_info *cinfo)
5658c2ecf20Sopenharmony_ci{
5668c2ecf20Sopenharmony_ci}
5678c2ecf20Sopenharmony_ci#endif
5688c2ecf20Sopenharmony_ci
5698c2ecf20Sopenharmony_ci#ifdef CONFIG_MIGRATION
5708c2ecf20Sopenharmony_ciextern int nfs_migrate_page(struct address_space *,
5718c2ecf20Sopenharmony_ci		struct page *, struct page *, enum migrate_mode);
5728c2ecf20Sopenharmony_ci#endif
5738c2ecf20Sopenharmony_ci
5748c2ecf20Sopenharmony_cistatic inline int
5758c2ecf20Sopenharmony_cinfs_write_verifier_cmp(const struct nfs_write_verifier *v1,
5768c2ecf20Sopenharmony_ci		const struct nfs_write_verifier *v2)
5778c2ecf20Sopenharmony_ci{
5788c2ecf20Sopenharmony_ci	return memcmp(v1->data, v2->data, sizeof(v1->data));
5798c2ecf20Sopenharmony_ci}
5808c2ecf20Sopenharmony_ci
5818c2ecf20Sopenharmony_cistatic inline bool
5828c2ecf20Sopenharmony_cinfs_write_match_verf(const struct nfs_writeverf *verf,
5838c2ecf20Sopenharmony_ci		struct nfs_page *req)
5848c2ecf20Sopenharmony_ci{
5858c2ecf20Sopenharmony_ci	return verf->committed > NFS_UNSTABLE &&
5868c2ecf20Sopenharmony_ci		!nfs_write_verifier_cmp(&req->wb_verf, &verf->verifier);
5878c2ecf20Sopenharmony_ci}
5888c2ecf20Sopenharmony_ci
5898c2ecf20Sopenharmony_cistatic inline gfp_t nfs_io_gfp_mask(void)
5908c2ecf20Sopenharmony_ci{
5918c2ecf20Sopenharmony_ci	if (current->flags & PF_WQ_WORKER)
5928c2ecf20Sopenharmony_ci		return GFP_KERNEL | __GFP_NORETRY | __GFP_NOWARN;
5938c2ecf20Sopenharmony_ci	return GFP_KERNEL;
5948c2ecf20Sopenharmony_ci}
5958c2ecf20Sopenharmony_ci
5968c2ecf20Sopenharmony_ci/* unlink.c */
5978c2ecf20Sopenharmony_ciextern struct rpc_task *
5988c2ecf20Sopenharmony_cinfs_async_rename(struct inode *old_dir, struct inode *new_dir,
5998c2ecf20Sopenharmony_ci		 struct dentry *old_dentry, struct dentry *new_dentry,
6008c2ecf20Sopenharmony_ci		 void (*complete)(struct rpc_task *, struct nfs_renamedata *));
6018c2ecf20Sopenharmony_ciextern int nfs_sillyrename(struct inode *dir, struct dentry *dentry);
6028c2ecf20Sopenharmony_ci
6038c2ecf20Sopenharmony_ci/* direct.c */
6048c2ecf20Sopenharmony_civoid nfs_init_cinfo_from_dreq(struct nfs_commit_info *cinfo,
6058c2ecf20Sopenharmony_ci			      struct nfs_direct_req *dreq);
6068c2ecf20Sopenharmony_ciextern ssize_t nfs_dreq_bytes_left(struct nfs_direct_req *dreq);
6078c2ecf20Sopenharmony_ci
6088c2ecf20Sopenharmony_ci/* nfs4proc.c */
6098c2ecf20Sopenharmony_ciextern struct nfs_client *nfs4_init_client(struct nfs_client *clp,
6108c2ecf20Sopenharmony_ci			    const struct nfs_client_initdata *);
6118c2ecf20Sopenharmony_ciextern int nfs40_walk_client_list(struct nfs_client *clp,
6128c2ecf20Sopenharmony_ci				struct nfs_client **result,
6138c2ecf20Sopenharmony_ci				const struct cred *cred);
6148c2ecf20Sopenharmony_ciextern int nfs41_walk_client_list(struct nfs_client *clp,
6158c2ecf20Sopenharmony_ci				struct nfs_client **result,
6168c2ecf20Sopenharmony_ci				const struct cred *cred);
6178c2ecf20Sopenharmony_ciextern void nfs4_test_session_trunk(struct rpc_clnt *clnt,
6188c2ecf20Sopenharmony_ci				struct rpc_xprt *xprt,
6198c2ecf20Sopenharmony_ci				void *data);
6208c2ecf20Sopenharmony_ci
6218c2ecf20Sopenharmony_cistatic inline struct inode *nfs_igrab_and_active(struct inode *inode)
6228c2ecf20Sopenharmony_ci{
6238c2ecf20Sopenharmony_ci	struct super_block *sb = inode->i_sb;
6248c2ecf20Sopenharmony_ci
6258c2ecf20Sopenharmony_ci	if (sb && nfs_sb_active(sb)) {
6268c2ecf20Sopenharmony_ci		if (igrab(inode))
6278c2ecf20Sopenharmony_ci			return inode;
6288c2ecf20Sopenharmony_ci		nfs_sb_deactive(sb);
6298c2ecf20Sopenharmony_ci	}
6308c2ecf20Sopenharmony_ci	return NULL;
6318c2ecf20Sopenharmony_ci}
6328c2ecf20Sopenharmony_ci
6338c2ecf20Sopenharmony_cistatic inline void nfs_iput_and_deactive(struct inode *inode)
6348c2ecf20Sopenharmony_ci{
6358c2ecf20Sopenharmony_ci	if (inode != NULL) {
6368c2ecf20Sopenharmony_ci		struct super_block *sb = inode->i_sb;
6378c2ecf20Sopenharmony_ci
6388c2ecf20Sopenharmony_ci		iput(inode);
6398c2ecf20Sopenharmony_ci		nfs_sb_deactive(sb);
6408c2ecf20Sopenharmony_ci	}
6418c2ecf20Sopenharmony_ci}
6428c2ecf20Sopenharmony_ci
6438c2ecf20Sopenharmony_ci/*
6448c2ecf20Sopenharmony_ci * Determine the device name as a string
6458c2ecf20Sopenharmony_ci */
6468c2ecf20Sopenharmony_cistatic inline char *nfs_devname(struct dentry *dentry,
6478c2ecf20Sopenharmony_ci				char *buffer, ssize_t buflen)
6488c2ecf20Sopenharmony_ci{
6498c2ecf20Sopenharmony_ci	char *dummy;
6508c2ecf20Sopenharmony_ci	return nfs_path(&dummy, dentry, buffer, buflen, NFS_PATH_CANONICAL);
6518c2ecf20Sopenharmony_ci}
6528c2ecf20Sopenharmony_ci
6538c2ecf20Sopenharmony_ci/*
6548c2ecf20Sopenharmony_ci * Determine the actual block size (and log2 thereof)
6558c2ecf20Sopenharmony_ci */
6568c2ecf20Sopenharmony_cistatic inline
6578c2ecf20Sopenharmony_ciunsigned long nfs_block_bits(unsigned long bsize, unsigned char *nrbitsp)
6588c2ecf20Sopenharmony_ci{
6598c2ecf20Sopenharmony_ci	/* make sure blocksize is a power of two */
6608c2ecf20Sopenharmony_ci	if ((bsize & (bsize - 1)) || nrbitsp) {
6618c2ecf20Sopenharmony_ci		unsigned char	nrbits;
6628c2ecf20Sopenharmony_ci
6638c2ecf20Sopenharmony_ci		for (nrbits = 31; nrbits && !(bsize & (1 << nrbits)); nrbits--)
6648c2ecf20Sopenharmony_ci			;
6658c2ecf20Sopenharmony_ci		bsize = 1 << nrbits;
6668c2ecf20Sopenharmony_ci		if (nrbitsp)
6678c2ecf20Sopenharmony_ci			*nrbitsp = nrbits;
6688c2ecf20Sopenharmony_ci	}
6698c2ecf20Sopenharmony_ci
6708c2ecf20Sopenharmony_ci	return bsize;
6718c2ecf20Sopenharmony_ci}
6728c2ecf20Sopenharmony_ci
6738c2ecf20Sopenharmony_ci/*
6748c2ecf20Sopenharmony_ci * Calculate the number of 512byte blocks used.
6758c2ecf20Sopenharmony_ci */
6768c2ecf20Sopenharmony_cistatic inline blkcnt_t nfs_calc_block_size(u64 tsize)
6778c2ecf20Sopenharmony_ci{
6788c2ecf20Sopenharmony_ci	blkcnt_t used = (tsize + 511) >> 9;
6798c2ecf20Sopenharmony_ci	return (used > ULONG_MAX) ? ULONG_MAX : used;
6808c2ecf20Sopenharmony_ci}
6818c2ecf20Sopenharmony_ci
6828c2ecf20Sopenharmony_ci/*
6838c2ecf20Sopenharmony_ci * Compute and set NFS server blocksize
6848c2ecf20Sopenharmony_ci */
6858c2ecf20Sopenharmony_cistatic inline
6868c2ecf20Sopenharmony_ciunsigned long nfs_block_size(unsigned long bsize, unsigned char *nrbitsp)
6878c2ecf20Sopenharmony_ci{
6888c2ecf20Sopenharmony_ci	if (bsize < NFS_MIN_FILE_IO_SIZE)
6898c2ecf20Sopenharmony_ci		bsize = NFS_DEF_FILE_IO_SIZE;
6908c2ecf20Sopenharmony_ci	else if (bsize >= NFS_MAX_FILE_IO_SIZE)
6918c2ecf20Sopenharmony_ci		bsize = NFS_MAX_FILE_IO_SIZE;
6928c2ecf20Sopenharmony_ci
6938c2ecf20Sopenharmony_ci	return nfs_block_bits(bsize, nrbitsp);
6948c2ecf20Sopenharmony_ci}
6958c2ecf20Sopenharmony_ci
6968c2ecf20Sopenharmony_ci/*
6978c2ecf20Sopenharmony_ci * Determine the maximum file size for a superblock
6988c2ecf20Sopenharmony_ci */
6998c2ecf20Sopenharmony_cistatic inline
7008c2ecf20Sopenharmony_civoid nfs_super_set_maxbytes(struct super_block *sb, __u64 maxfilesize)
7018c2ecf20Sopenharmony_ci{
7028c2ecf20Sopenharmony_ci	sb->s_maxbytes = (loff_t)maxfilesize;
7038c2ecf20Sopenharmony_ci	if (sb->s_maxbytes > MAX_LFS_FILESIZE || sb->s_maxbytes <= 0)
7048c2ecf20Sopenharmony_ci		sb->s_maxbytes = MAX_LFS_FILESIZE;
7058c2ecf20Sopenharmony_ci}
7068c2ecf20Sopenharmony_ci
7078c2ecf20Sopenharmony_ci/*
7088c2ecf20Sopenharmony_ci * Record the page as unstable (an extra writeback period) and mark its
7098c2ecf20Sopenharmony_ci * inode as dirty.
7108c2ecf20Sopenharmony_ci */
7118c2ecf20Sopenharmony_cistatic inline
7128c2ecf20Sopenharmony_civoid nfs_mark_page_unstable(struct page *page, struct nfs_commit_info *cinfo)
7138c2ecf20Sopenharmony_ci{
7148c2ecf20Sopenharmony_ci	if (!cinfo->dreq) {
7158c2ecf20Sopenharmony_ci		struct inode *inode = page_file_mapping(page)->host;
7168c2ecf20Sopenharmony_ci
7178c2ecf20Sopenharmony_ci		/* This page is really still in write-back - just that the
7188c2ecf20Sopenharmony_ci		 * writeback is happening on the server now.
7198c2ecf20Sopenharmony_ci		 */
7208c2ecf20Sopenharmony_ci		inc_node_page_state(page, NR_WRITEBACK);
7218c2ecf20Sopenharmony_ci		inc_wb_stat(&inode_to_bdi(inode)->wb, WB_WRITEBACK);
7228c2ecf20Sopenharmony_ci		__mark_inode_dirty(inode, I_DIRTY_DATASYNC);
7238c2ecf20Sopenharmony_ci	}
7248c2ecf20Sopenharmony_ci}
7258c2ecf20Sopenharmony_ci
7268c2ecf20Sopenharmony_ci/*
7278c2ecf20Sopenharmony_ci * Determine the number of bytes of data the page contains
7288c2ecf20Sopenharmony_ci */
7298c2ecf20Sopenharmony_cistatic inline
7308c2ecf20Sopenharmony_ciunsigned int nfs_page_length(struct page *page)
7318c2ecf20Sopenharmony_ci{
7328c2ecf20Sopenharmony_ci	loff_t i_size = i_size_read(page_file_mapping(page)->host);
7338c2ecf20Sopenharmony_ci
7348c2ecf20Sopenharmony_ci	if (i_size > 0) {
7358c2ecf20Sopenharmony_ci		pgoff_t index = page_index(page);
7368c2ecf20Sopenharmony_ci		pgoff_t end_index = (i_size - 1) >> PAGE_SHIFT;
7378c2ecf20Sopenharmony_ci		if (index < end_index)
7388c2ecf20Sopenharmony_ci			return PAGE_SIZE;
7398c2ecf20Sopenharmony_ci		if (index == end_index)
7408c2ecf20Sopenharmony_ci			return ((i_size - 1) & ~PAGE_MASK) + 1;
7418c2ecf20Sopenharmony_ci	}
7428c2ecf20Sopenharmony_ci	return 0;
7438c2ecf20Sopenharmony_ci}
7448c2ecf20Sopenharmony_ci
7458c2ecf20Sopenharmony_ci/*
7468c2ecf20Sopenharmony_ci * Convert a umode to a dirent->d_type
7478c2ecf20Sopenharmony_ci */
7488c2ecf20Sopenharmony_cistatic inline
7498c2ecf20Sopenharmony_ciunsigned char nfs_umode_to_dtype(umode_t mode)
7508c2ecf20Sopenharmony_ci{
7518c2ecf20Sopenharmony_ci	return (mode >> 12) & 15;
7528c2ecf20Sopenharmony_ci}
7538c2ecf20Sopenharmony_ci
7548c2ecf20Sopenharmony_ci/*
7558c2ecf20Sopenharmony_ci * Determine the number of pages in an array of length 'len' and
7568c2ecf20Sopenharmony_ci * with a base offset of 'base'
7578c2ecf20Sopenharmony_ci */
7588c2ecf20Sopenharmony_cistatic inline
7598c2ecf20Sopenharmony_ciunsigned int nfs_page_array_len(unsigned int base, size_t len)
7608c2ecf20Sopenharmony_ci{
7618c2ecf20Sopenharmony_ci	return ((unsigned long)len + (unsigned long)base +
7628c2ecf20Sopenharmony_ci		PAGE_SIZE - 1) >> PAGE_SHIFT;
7638c2ecf20Sopenharmony_ci}
7648c2ecf20Sopenharmony_ci
7658c2ecf20Sopenharmony_ci/*
7668c2ecf20Sopenharmony_ci * Convert a struct timespec64 into a 64-bit change attribute
7678c2ecf20Sopenharmony_ci *
7688c2ecf20Sopenharmony_ci * This does approximately the same thing as timespec64_to_ns(),
7698c2ecf20Sopenharmony_ci * but for calculation efficiency, we multiply the seconds by
7708c2ecf20Sopenharmony_ci * 1024*1024*1024.
7718c2ecf20Sopenharmony_ci */
7728c2ecf20Sopenharmony_cistatic inline
7738c2ecf20Sopenharmony_ciu64 nfs_timespec_to_change_attr(const struct timespec64 *ts)
7748c2ecf20Sopenharmony_ci{
7758c2ecf20Sopenharmony_ci	return ((u64)ts->tv_sec << 30) + ts->tv_nsec;
7768c2ecf20Sopenharmony_ci}
7778c2ecf20Sopenharmony_ci
7788c2ecf20Sopenharmony_ci#ifdef CONFIG_CRC32
7798c2ecf20Sopenharmony_ci/**
7808c2ecf20Sopenharmony_ci * nfs_fhandle_hash - calculate the crc32 hash for the filehandle
7818c2ecf20Sopenharmony_ci * @fh - pointer to filehandle
7828c2ecf20Sopenharmony_ci *
7838c2ecf20Sopenharmony_ci * returns a crc32 hash for the filehandle that is compatible with
7848c2ecf20Sopenharmony_ci * the one displayed by "wireshark".
7858c2ecf20Sopenharmony_ci */
7868c2ecf20Sopenharmony_cistatic inline u32 nfs_fhandle_hash(const struct nfs_fh *fh)
7878c2ecf20Sopenharmony_ci{
7888c2ecf20Sopenharmony_ci	return ~crc32_le(0xFFFFFFFF, &fh->data[0], fh->size);
7898c2ecf20Sopenharmony_ci}
7908c2ecf20Sopenharmony_cistatic inline u32 nfs_stateid_hash(const nfs4_stateid *stateid)
7918c2ecf20Sopenharmony_ci{
7928c2ecf20Sopenharmony_ci	return ~crc32_le(0xFFFFFFFF, &stateid->other[0],
7938c2ecf20Sopenharmony_ci				NFS4_STATEID_OTHER_SIZE);
7948c2ecf20Sopenharmony_ci}
7958c2ecf20Sopenharmony_ci#else
7968c2ecf20Sopenharmony_cistatic inline u32 nfs_fhandle_hash(const struct nfs_fh *fh)
7978c2ecf20Sopenharmony_ci{
7988c2ecf20Sopenharmony_ci	return 0;
7998c2ecf20Sopenharmony_ci}
8008c2ecf20Sopenharmony_cistatic inline u32 nfs_stateid_hash(nfs4_stateid *stateid)
8018c2ecf20Sopenharmony_ci{
8028c2ecf20Sopenharmony_ci	return 0;
8038c2ecf20Sopenharmony_ci}
8048c2ecf20Sopenharmony_ci#endif
8058c2ecf20Sopenharmony_ci
8068c2ecf20Sopenharmony_cistatic inline bool nfs_error_is_fatal(int err)
8078c2ecf20Sopenharmony_ci{
8088c2ecf20Sopenharmony_ci	switch (err) {
8098c2ecf20Sopenharmony_ci	case -ERESTARTSYS:
8108c2ecf20Sopenharmony_ci	case -EINTR:
8118c2ecf20Sopenharmony_ci	case -EACCES:
8128c2ecf20Sopenharmony_ci	case -EDQUOT:
8138c2ecf20Sopenharmony_ci	case -EFBIG:
8148c2ecf20Sopenharmony_ci	case -EIO:
8158c2ecf20Sopenharmony_ci	case -ENOSPC:
8168c2ecf20Sopenharmony_ci	case -EROFS:
8178c2ecf20Sopenharmony_ci	case -ESTALE:
8188c2ecf20Sopenharmony_ci	case -E2BIG:
8198c2ecf20Sopenharmony_ci	case -ENOMEM:
8208c2ecf20Sopenharmony_ci	case -ETIMEDOUT:
8218c2ecf20Sopenharmony_ci		return true;
8228c2ecf20Sopenharmony_ci	default:
8238c2ecf20Sopenharmony_ci		return false;
8248c2ecf20Sopenharmony_ci	}
8258c2ecf20Sopenharmony_ci}
8268c2ecf20Sopenharmony_ci
8278c2ecf20Sopenharmony_cistatic inline bool nfs_error_is_fatal_on_server(int err)
8288c2ecf20Sopenharmony_ci{
8298c2ecf20Sopenharmony_ci	switch (err) {
8308c2ecf20Sopenharmony_ci	case 0:
8318c2ecf20Sopenharmony_ci	case -ERESTARTSYS:
8328c2ecf20Sopenharmony_ci	case -EINTR:
8338c2ecf20Sopenharmony_ci	case -ENOMEM:
8348c2ecf20Sopenharmony_ci		return false;
8358c2ecf20Sopenharmony_ci	}
8368c2ecf20Sopenharmony_ci	return nfs_error_is_fatal(err);
8378c2ecf20Sopenharmony_ci}
8388c2ecf20Sopenharmony_ci
8398c2ecf20Sopenharmony_ci/*
8408c2ecf20Sopenharmony_ci * Select between a default port value and a user-specified port value.
8418c2ecf20Sopenharmony_ci * If a zero value is set, then autobind will be used.
8428c2ecf20Sopenharmony_ci */
8438c2ecf20Sopenharmony_cistatic inline void nfs_set_port(struct sockaddr *sap, int *port,
8448c2ecf20Sopenharmony_ci				const unsigned short default_port)
8458c2ecf20Sopenharmony_ci{
8468c2ecf20Sopenharmony_ci	if (*port == NFS_UNSPEC_PORT)
8478c2ecf20Sopenharmony_ci		*port = default_port;
8488c2ecf20Sopenharmony_ci
8498c2ecf20Sopenharmony_ci	rpc_set_port(sap, *port);
8508c2ecf20Sopenharmony_ci}
851