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