1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
21da177e4SLinus Torvalds /*
31da177e4SLinus Torvalds * linux/include/linux/nfs_fs.h
41da177e4SLinus Torvalds *
51da177e4SLinus Torvalds * Copyright (C) 1992 Rick Sladkey
61da177e4SLinus Torvalds *
71da177e4SLinus Torvalds * OS-specific nfs filesystem definitions and declarations
81da177e4SLinus Torvalds */
91da177e4SLinus Torvalds #ifndef _LINUX_NFS_FS_H
101da177e4SLinus Torvalds #define _LINUX_NFS_FS_H
111da177e4SLinus Torvalds
12607ca46eSDavid Howells #include <uapi/linux/nfs_fs.h>
13e18fa700SJeff Garzik
147f1cbe51SDavid Woodhouse
15e27d359eSTrond Myklebust /*
16e27d359eSTrond Myklebust * Enable dprintk() debugging support for nfs client.
17e27d359eSTrond Myklebust */
18e27d359eSTrond Myklebust #ifdef CONFIG_NFS_DEBUG
19e27d359eSTrond Myklebust # define NFS_DEBUG
20e27d359eSTrond Myklebust #endif
21e27d359eSTrond Myklebust
221da177e4SLinus Torvalds #include <linux/in.h>
231da177e4SLinus Torvalds #include <linux/mm.h>
241da177e4SLinus Torvalds #include <linux/pagemap.h>
251c3c07e9STrond Myklebust #include <linux/rbtree.h>
262f62b5aaSElena Reshetova #include <linux/refcount.h>
271da177e4SLinus Torvalds #include <linux/rwsem.h>
281da177e4SLinus Torvalds #include <linux/wait.h>
291da177e4SLinus Torvalds
301da177e4SLinus Torvalds #include <linux/sunrpc/debug.h>
311da177e4SLinus Torvalds #include <linux/sunrpc/auth.h>
321da177e4SLinus Torvalds #include <linux/sunrpc/clnt.h>
331da177e4SLinus Torvalds
3488a4d7bdSDave Wysochanski #ifdef CONFIG_NFS_FSCACHE
3588a4d7bdSDave Wysochanski #include <linux/netfs.h>
3688a4d7bdSDave Wysochanski #endif
3788a4d7bdSDave Wysochanski
381da177e4SLinus Torvalds #include <linux/nfs.h>
391da177e4SLinus Torvalds #include <linux/nfs2.h>
401da177e4SLinus Torvalds #include <linux/nfs3.h>
411da177e4SLinus Torvalds #include <linux/nfs4.h>
421da177e4SLinus Torvalds #include <linux/nfs_xdr.h>
438b4bdcf8STrond Myklebust #include <linux/nfs_fs_sb.h>
448b4bdcf8STrond Myklebust
451da177e4SLinus Torvalds #include <linux/mempool.h>
461da177e4SLinus Torvalds
471da177e4SLinus Torvalds /*
487e134205SOlga Kornievskaia * These are the default for number of transports to different server IPs
497e134205SOlga Kornievskaia */
507e134205SOlga Kornievskaia #define NFS_MAX_TRANSPORTS 16
517e134205SOlga Kornievskaia
527e134205SOlga Kornievskaia /*
53b593c09fSTrond Myklebust * Size of the NFS directory verifier
54b593c09fSTrond Myklebust */
55b593c09fSTrond Myklebust #define NFS_DIR_VERIFIER_SIZE 2
56b593c09fSTrond Myklebust
57b593c09fSTrond Myklebust /*
581da177e4SLinus Torvalds * NFSv3/v4 Access mode cache entry
591da177e4SLinus Torvalds */
601da177e4SLinus Torvalds struct nfs_access_entry {
611c3c07e9STrond Myklebust struct rb_node rb_node;
62cfcea3e8STrond Myklebust struct list_head lru;
636238aec8SNeilBrown kuid_t fsuid;
646238aec8SNeilBrown kgid_t fsgid;
656238aec8SNeilBrown struct group_info *group_info;
660eb43812STrond Myklebust u64 timestamp;
67bd8b2441STrond Myklebust __u32 mask;
68f682a398SNeilBrown struct rcu_head rcu_head;
691da177e4SLinus Torvalds };
701da177e4SLinus Torvalds
71f11ac8dbSTrond Myklebust struct nfs_lock_context {
722f62b5aaSElena Reshetova refcount_t count;
73f11ac8dbSTrond Myklebust struct list_head list;
74f11ac8dbSTrond Myklebust struct nfs_open_context *open_context;
75d51fdb87SNeilBrown fl_owner_t lockowner;
76210c7c17SBenjamin Coddington atomic_t io_count;
771db97eaaSTrond Myklebust struct rcu_head rcu_head;
78f11ac8dbSTrond Myklebust };
79f11ac8dbSTrond Myklebust
801da177e4SLinus Torvalds struct nfs4_state;
811da177e4SLinus Torvalds struct nfs_open_context {
82f11ac8dbSTrond Myklebust struct nfs_lock_context lock_context;
83532d4defSNeilBrown fl_owner_t flock_owner;
843d4ff43dSAl Viro struct dentry *dentry;
85a52458b4SNeilBrown const struct cred *cred;
86ca05cbaeSTrond Myklebust struct rpc_cred __rcu *ll_cred; /* low-level cred - use to check for expiry */
871da177e4SLinus Torvalds struct nfs4_state *state;
88dc0b027dSTrond Myklebust fmode_t mode;
897b159fc1STrond Myklebust
907b159fc1STrond Myklebust unsigned long flags;
91c58c8441STrond Myklebust #define NFS_CONTEXT_BAD (2)
927d6ddf88SBenjamin Coddington #define NFS_CONTEXT_UNLOCK (3)
93e97bc663STrond Myklebust #define NFS_CONTEXT_FILE_OPEN (4)
941da177e4SLinus Torvalds int error;
951da177e4SLinus Torvalds
961da177e4SLinus Torvalds struct list_head list;
9782be417aSAndy Adamson struct nfs4_threshold *mdsthreshold;
980de43976STrond Myklebust struct rcu_head rcu_head;
99480c2006SBryan Schumaker };
10000a92642SOlivier Galibert
101480c2006SBryan Schumaker struct nfs_open_dir_context {
102311324adSTrond Myklebust struct list_head list;
103230bc98fSTrond Myklebust atomic_t cache_hits;
104230bc98fSTrond Myklebust atomic_t cache_misses;
1050c030806STrond Myklebust unsigned long attr_gencount;
106b593c09fSTrond Myklebust __be32 verf[NFS_DIR_VERIFIER_SIZE];
10700a92642SOlivier Galibert __u64 dir_cookie;
108728dd0abSTrond Myklebust __u64 last_cookie;
109ff81dfb5STrond Myklebust pgoff_t page_index;
110580f2367STrond Myklebust unsigned int dtsize;
111b0365ccbSTrond Myklebust bool force_clear;
112e1d2699bSTrond Myklebust bool eof;
113230bc98fSTrond Myklebust struct rcu_head rcu_head;
1141da177e4SLinus Torvalds };
1151da177e4SLinus Torvalds
1161da177e4SLinus Torvalds /*
1171da177e4SLinus Torvalds * NFSv4 delegation
1181da177e4SLinus Torvalds */
1191da177e4SLinus Torvalds struct nfs_delegation;
1201da177e4SLinus Torvalds
1215c6a9f7dSAndreas Gruenbacher struct posix_acl;
1225c6a9f7dSAndreas Gruenbacher
12395ad37f9SFrank van der Linden struct nfs4_xattr_cache;
12495ad37f9SFrank van der Linden
1251da177e4SLinus Torvalds /*
1261da177e4SLinus Torvalds * nfs fs inode data in memory
1271da177e4SLinus Torvalds */
1281da177e4SLinus Torvalds struct nfs_inode {
1291da177e4SLinus Torvalds /*
1301da177e4SLinus Torvalds * The 64bit 'inode number'
1311da177e4SLinus Torvalds */
1321da177e4SLinus Torvalds __u64 fileid;
1331da177e4SLinus Torvalds
1341da177e4SLinus Torvalds /*
1351da177e4SLinus Torvalds * NFS file handle
1361da177e4SLinus Torvalds */
1371da177e4SLinus Torvalds struct nfs_fh fh;
1381da177e4SLinus Torvalds
1391da177e4SLinus Torvalds /*
1401da177e4SLinus Torvalds * Various flags
1411da177e4SLinus Torvalds */
142412d582eSChuck Lever unsigned long flags; /* atomic bit ops */
143412d582eSChuck Lever unsigned long cache_validity; /* bit mask */
1441da177e4SLinus Torvalds
1451da177e4SLinus Torvalds /*
14624bd68f4SGoldwyn Rodrigues * read_cache_jiffies is when we started read-caching this inode.
1471da177e4SLinus Torvalds * attrtimeo is for how long the cached information is assumed
1481da177e4SLinus Torvalds * to be valid. A successful attribute revalidation doubles
1491da177e4SLinus Torvalds * attrtimeo (up to acregmax/acdirmax), a failure resets it to
1501da177e4SLinus Torvalds * acregmin/acdirmin.
1511da177e4SLinus Torvalds *
1521da177e4SLinus Torvalds * We need to revalidate the cached attrs for this inode if
1531da177e4SLinus Torvalds *
15464672d55SPeter Staubach * jiffies - read_cache_jiffies >= attrtimeo
15564672d55SPeter Staubach *
15664672d55SPeter Staubach * Please note the comparison is greater than or equal
15764672d55SPeter Staubach * so that zero timeout values can be specified.
1581da177e4SLinus Torvalds */
1591da177e4SLinus Torvalds unsigned long read_cache_jiffies;
1601da177e4SLinus Torvalds unsigned long attrtimeo;
1611da177e4SLinus Torvalds unsigned long attrtimeo_timestamp;
1621da177e4SLinus Torvalds
1634704f0e2STrond Myklebust unsigned long attr_gencount;
1641da177e4SLinus Torvalds
1651c3c07e9STrond Myklebust struct rb_root access_cache;
166cfcea3e8STrond Myklebust struct list_head access_cache_entry_lru;
167cfcea3e8STrond Myklebust struct list_head access_cache_inode_lru;
1681da177e4SLinus Torvalds
169e591b298STrond Myklebust union {
170e591b298STrond Myklebust /* Directory */
171e591b298STrond Myklebust struct {
172e591b298STrond Myklebust /* "Generation counter" for the attribute cache.
173e591b298STrond Myklebust * This is bumped whenever we update the metadata
174e591b298STrond Myklebust * on the server.
175e591b298STrond Myklebust */
176e591b298STrond Myklebust unsigned long cache_change_attribute;
1771da177e4SLinus Torvalds /*
1781da177e4SLinus Torvalds * This is the cookie verifier used for NFSv3 readdir
1791da177e4SLinus Torvalds * operations
1801da177e4SLinus Torvalds */
181b593c09fSTrond Myklebust __be32 cookieverf[NFS_DIR_VERIFIER_SIZE];
182884be175SAl Viro /* Readers: in-flight sillydelete RPC calls */
183884be175SAl Viro /* Writers: rmdir */
184884be175SAl Viro struct rw_semaphore rmdir_sem;
185e591b298STrond Myklebust };
186e591b298STrond Myklebust /* Regular file */
187e591b298STrond Myklebust struct {
188e591b298STrond Myklebust atomic_long_t nrequests;
18967f4b5dcSTrond Myklebust atomic_long_t redirtied_pages;
190e591b298STrond Myklebust struct nfs_mds_commit_info commit_info;
191e824f99aSTrond Myklebust struct mutex commit_mutex;
192e591b298STrond Myklebust };
193e591b298STrond Myklebust };
194e591b298STrond Myklebust
195e591b298STrond Myklebust /* Open contexts for shared mmap writes */
196e591b298STrond Myklebust struct list_head open_files;
197565277f6STrond Myklebust
1983db63daaSNeilBrown /* Keep track of out-of-order replies.
1993db63daaSNeilBrown * The ooo array contains start/end pairs of
2003db63daaSNeilBrown * numbers from the changeid sequence when
2013db63daaSNeilBrown * the inode's iversion has been updated.
2023db63daaSNeilBrown * It also contains end/start pair (i.e. reverse order)
2033db63daaSNeilBrown * of sections of the changeid sequence that have
2043db63daaSNeilBrown * been seen in replies from the server.
2053db63daaSNeilBrown * Normally these should match and when both
2063db63daaSNeilBrown * A:B and B:A are found in ooo, they are both removed.
2073db63daaSNeilBrown * And if a reply with A:B causes an iversion update
2083db63daaSNeilBrown * of A:B, then neither are added.
2093db63daaSNeilBrown * When a reply has pre_change that doesn't match
2103db63daaSNeilBrown * iversion, then the changeid pair and any consequent
2113db63daaSNeilBrown * change in iversion ARE added. Later replies
2123db63daaSNeilBrown * might fill in the gaps, or possibly a gap is caused
2133db63daaSNeilBrown * by a change from another client.
2143db63daaSNeilBrown * When a file or directory is opened, if the ooo table
2153db63daaSNeilBrown * is not empty, then we assume the gaps were due to
2163db63daaSNeilBrown * another client and we invalidate the cached data.
2173db63daaSNeilBrown *
2183db63daaSNeilBrown * We can only track a limited number of concurrent gaps.
2193db63daaSNeilBrown * Currently that limit is 16.
2203db63daaSNeilBrown * We allocate the table on demand. If there is insufficient
2213db63daaSNeilBrown * memory, then we probably cannot cache the file anyway
2223db63daaSNeilBrown * so there is no loss.
2233db63daaSNeilBrown */
2243db63daaSNeilBrown struct {
2253db63daaSNeilBrown int cnt;
2263db63daaSNeilBrown struct {
2273db63daaSNeilBrown u64 start, end;
2283db63daaSNeilBrown } gap[16];
2293db63daaSNeilBrown } *ooo;
2303db63daaSNeilBrown
23189d77c8fSBryan Schumaker #if IS_ENABLED(CONFIG_NFS_V4)
232e50a1c2eSJ. Bruce Fields struct nfs4_cached_acl *nfs4_acl;
2331da177e4SLinus Torvalds /* NFSv4 state */
2341da177e4SLinus Torvalds struct list_head open_states;
2355b22216eSArnd Bergmann struct nfs_delegation __rcu *delegation;
2361da177e4SLinus Torvalds struct rw_semaphore rwsem;
237e5e94017SBenny Halevy
238e5e94017SBenny Halevy /* pNFS layout information */
239e5e94017SBenny Halevy struct pnfs_layout_hdr *layout;
2401da177e4SLinus Torvalds #endif /* CONFIG_NFS_V4*/
2412701d086SAndy Adamson /* how many bytes have been written/read and how many bytes queued up */
2422701d086SAndy Adamson __u64 write_io;
2432701d086SAndy Adamson __u64 read_io;
24495ad37f9SFrank van der Linden #ifdef CONFIG_NFS_V4_2
24595ad37f9SFrank van der Linden struct nfs4_xattr_cache *xattr_cache;
24695ad37f9SFrank van der Linden #endif
24788a4d7bdSDave Wysochanski union {
24888a4d7bdSDave Wysochanski struct inode vfs_inode;
24988a4d7bdSDave Wysochanski #ifdef CONFIG_NFS_FSCACHE
25088a4d7bdSDave Wysochanski struct netfs_inode netfs; /* netfs context and VFS inode */
25188a4d7bdSDave Wysochanski #endif
25288a4d7bdSDave Wysochanski };
2531da177e4SLinus Torvalds };
2541da177e4SLinus Torvalds
25562164f31SOlga Kornievskaia struct nfs4_copy_state {
25662164f31SOlga Kornievskaia struct list_head copies;
2570e65a32cSOlga Kornievskaia struct list_head src_copies;
25862164f31SOlga Kornievskaia nfs4_stateid stateid;
25962164f31SOlga Kornievskaia struct completion completion;
26062164f31SOlga Kornievskaia uint64_t count;
26162164f31SOlga Kornievskaia struct nfs_writeverf verf;
26262164f31SOlga Kornievskaia int error;
263e4648aa4SOlga Kornievskaia int flags;
2640e65a32cSOlga Kornievskaia struct nfs4_state *parent_src_state;
2650e65a32cSOlga Kornievskaia struct nfs4_state *parent_dst_state;
26662164f31SOlga Kornievskaia };
26762164f31SOlga Kornievskaia
2681da177e4SLinus Torvalds /*
2693c181827SAnna Schumaker * Access bit flags
2703c181827SAnna Schumaker */
2713c181827SAnna Schumaker #define NFS_ACCESS_READ 0x0001
2723c181827SAnna Schumaker #define NFS_ACCESS_LOOKUP 0x0002
2733c181827SAnna Schumaker #define NFS_ACCESS_MODIFY 0x0004
2743c181827SAnna Schumaker #define NFS_ACCESS_EXTEND 0x0008
2753c181827SAnna Schumaker #define NFS_ACCESS_DELETE 0x0010
2763c181827SAnna Schumaker #define NFS_ACCESS_EXECUTE 0x0020
2779a67fcc8SFrank van der Linden #define NFS_ACCESS_XAREAD 0x0040
2789a67fcc8SFrank van der Linden #define NFS_ACCESS_XAWRITE 0x0080
2799a67fcc8SFrank van der Linden #define NFS_ACCESS_XALIST 0x0100
2803c181827SAnna Schumaker
2813c181827SAnna Schumaker /*
28255296809SChuck Lever * Cache validity bit flags
2831da177e4SLinus Torvalds */
28490972882STrond Myklebust #define NFS_INO_INVALID_DATA BIT(1) /* cached data is invalid */
28590972882STrond Myklebust #define NFS_INO_INVALID_ATIME BIT(2) /* cached atime is invalid */
28690972882STrond Myklebust #define NFS_INO_INVALID_ACCESS BIT(3) /* cached access cred invalid */
28790972882STrond Myklebust #define NFS_INO_INVALID_ACL BIT(4) /* cached acls are invalid */
28890972882STrond Myklebust #define NFS_INO_REVAL_FORCED BIT(6) /* force revalidation ignoring a delegation */
28990972882STrond Myklebust #define NFS_INO_INVALID_LABEL BIT(7) /* cached label is invalid */
29016e14375STrond Myklebust #define NFS_INO_INVALID_CHANGE BIT(8) /* cached change is invalid */
29116e14375STrond Myklebust #define NFS_INO_INVALID_CTIME BIT(9) /* cached ctime is invalid */
29216e14375STrond Myklebust #define NFS_INO_INVALID_MTIME BIT(10) /* cached mtime is invalid */
29316e14375STrond Myklebust #define NFS_INO_INVALID_SIZE BIT(11) /* cached size is invalid */
29416e14375STrond Myklebust #define NFS_INO_INVALID_OTHER BIT(12) /* other attrs are invalid */
2951c341b77STrond Myklebust #define NFS_INO_DATA_INVAL_DEFER \
2961c341b77STrond Myklebust BIT(13) /* Deferred cache invalidation */
2973a39e778SZheng Bin #define NFS_INO_INVALID_BLOCKS BIT(14) /* cached blocks are invalid */
2980f44da51SFrank van der Linden #define NFS_INO_INVALID_XATTR BIT(15) /* xattrs are invalid */
299fabf2b34STrond Myklebust #define NFS_INO_INVALID_NLINK BIT(16) /* cached nlinks is invalid */
300720869ebSTrond Myklebust #define NFS_INO_INVALID_MODE BIT(17) /* cached mode is invalid */
30116e14375STrond Myklebust
30216e14375STrond Myklebust #define NFS_INO_INVALID_ATTR (NFS_INO_INVALID_CHANGE \
30316e14375STrond Myklebust | NFS_INO_INVALID_CTIME \
30416e14375STrond Myklebust | NFS_INO_INVALID_MTIME \
30516e14375STrond Myklebust | NFS_INO_INVALID_SIZE \
306fabf2b34STrond Myklebust | NFS_INO_INVALID_NLINK \
307720869ebSTrond Myklebust | NFS_INO_INVALID_MODE \
30816e14375STrond Myklebust | NFS_INO_INVALID_OTHER) /* inode metadata is invalid */
30955296809SChuck Lever
31055296809SChuck Lever /*
311412d582eSChuck Lever * Bit offsets in flags field
31255296809SChuck Lever */
313691beb13STrond Myklebust #define NFS_INO_STALE (1) /* possible stale inode */
314691beb13STrond Myklebust #define NFS_INO_ACL_LRU_SET (2) /* Inode is on the LRU list */
315d529ef83SJeff Layton #define NFS_INO_INVALIDATING (3) /* inode is being invalidated */
31643245ecaSOlga Kornievskaia #define NFS_INO_PRESERVE_UNLINKED (4) /* preserve file if removed while open */
317863a3c6cSAndy Adamson #define NFS_INO_LAYOUTCOMMIT (9) /* layoutcommit required */
31892407e75SPeng Tao #define NFS_INO_LAYOUTCOMMITTING (10) /* layoutcommit inflight */
3191bfe3b25SPeng Tao #define NFS_INO_LAYOUTSTATS (11) /* layoutstats inflight */
320a5864c99STrond Myklebust #define NFS_INO_ODIRECT (12) /* I/O setting is O_DIRECT */
3211da177e4SLinus Torvalds
NFS_I(const struct inode * inode)32299fadcd7SBenny Halevy static inline struct nfs_inode *NFS_I(const struct inode *inode)
3231da177e4SLinus Torvalds {
3241da177e4SLinus Torvalds return container_of(inode, struct nfs_inode, vfs_inode);
3251da177e4SLinus Torvalds }
3261da177e4SLinus Torvalds
NFS_SB(const struct super_block * s)32799fadcd7SBenny Halevy static inline struct nfs_server *NFS_SB(const struct super_block *s)
32899fadcd7SBenny Halevy {
32999fadcd7SBenny Halevy return (struct nfs_server *)(s->s_fs_info);
33099fadcd7SBenny Halevy }
3311da177e4SLinus Torvalds
NFS_FH(const struct inode * inode)33299fadcd7SBenny Halevy static inline struct nfs_fh *NFS_FH(const struct inode *inode)
33399fadcd7SBenny Halevy {
33499fadcd7SBenny Halevy return &NFS_I(inode)->fh;
33599fadcd7SBenny Halevy }
3361da177e4SLinus Torvalds
NFS_SERVER(const struct inode * inode)33799fadcd7SBenny Halevy static inline struct nfs_server *NFS_SERVER(const struct inode *inode)
33899fadcd7SBenny Halevy {
33999fadcd7SBenny Halevy return NFS_SB(inode->i_sb);
34099fadcd7SBenny Halevy }
34199fadcd7SBenny Halevy
NFS_CLIENT(const struct inode * inode)34299fadcd7SBenny Halevy static inline struct rpc_clnt *NFS_CLIENT(const struct inode *inode)
34399fadcd7SBenny Halevy {
34499fadcd7SBenny Halevy return NFS_SERVER(inode)->client;
34599fadcd7SBenny Halevy }
34699fadcd7SBenny Halevy
NFS_PROTO(const struct inode * inode)34799fadcd7SBenny Halevy static inline const struct nfs_rpc_ops *NFS_PROTO(const struct inode *inode)
34899fadcd7SBenny Halevy {
34999fadcd7SBenny Halevy return NFS_SERVER(inode)->nfs_client->rpc_ops;
35099fadcd7SBenny Halevy }
35199fadcd7SBenny Halevy
NFS_MINATTRTIMEO(const struct inode * inode)35299fadcd7SBenny Halevy static inline unsigned NFS_MINATTRTIMEO(const struct inode *inode)
35399fadcd7SBenny Halevy {
35499fadcd7SBenny Halevy struct nfs_server *nfss = NFS_SERVER(inode);
35599fadcd7SBenny Halevy return S_ISDIR(inode->i_mode) ? nfss->acdirmin : nfss->acregmin;
35699fadcd7SBenny Halevy }
35799fadcd7SBenny Halevy
NFS_MAXATTRTIMEO(const struct inode * inode)35899fadcd7SBenny Halevy static inline unsigned NFS_MAXATTRTIMEO(const struct inode *inode)
35999fadcd7SBenny Halevy {
36099fadcd7SBenny Halevy struct nfs_server *nfss = NFS_SERVER(inode);
36199fadcd7SBenny Halevy return S_ISDIR(inode->i_mode) ? nfss->acdirmax : nfss->acregmax;
36299fadcd7SBenny Halevy }
36399fadcd7SBenny Halevy
NFS_STALE(const struct inode * inode)36499fadcd7SBenny Halevy static inline int NFS_STALE(const struct inode *inode)
36599fadcd7SBenny Halevy {
36699fadcd7SBenny Halevy return test_bit(NFS_INO_STALE, &NFS_I(inode)->flags);
36799fadcd7SBenny Halevy }
36899fadcd7SBenny Halevy
NFS_FILEID(const struct inode * inode)36999fadcd7SBenny Halevy static inline __u64 NFS_FILEID(const struct inode *inode)
37099fadcd7SBenny Halevy {
37199fadcd7SBenny Halevy return NFS_I(inode)->fileid;
37299fadcd7SBenny Halevy }
37399fadcd7SBenny Halevy
set_nfs_fileid(struct inode * inode,__u64 fileid)37499fadcd7SBenny Halevy static inline void set_nfs_fileid(struct inode *inode, __u64 fileid)
37599fadcd7SBenny Halevy {
37699fadcd7SBenny Halevy NFS_I(inode)->fileid = fileid;
37799fadcd7SBenny Halevy }
3781da177e4SLinus Torvalds
nfs_mark_for_revalidate(struct inode * inode)379decf491fSTrond Myklebust static inline void nfs_mark_for_revalidate(struct inode *inode)
3801da177e4SLinus Torvalds {
38138478b24STrond Myklebust struct nfs_inode *nfsi = NFS_I(inode);
38238478b24STrond Myklebust
383dc59250cSChuck Lever spin_lock(&inode->i_lock);
38488a6099fSTrond Myklebust nfsi->cache_validity |= NFS_INO_INVALID_ACCESS | NFS_INO_INVALID_ACL |
38588a6099fSTrond Myklebust NFS_INO_INVALID_CHANGE | NFS_INO_INVALID_CTIME |
38688a6099fSTrond Myklebust NFS_INO_INVALID_SIZE;
387f3821110STrond Myklebust if (S_ISDIR(inode->i_mode))
388115c48d7STrond Myklebust nfsi->cache_validity |= NFS_INO_INVALID_DATA;
389dc59250cSChuck Lever spin_unlock(&inode->i_lock);
390dc59250cSChuck Lever }
391decf491fSTrond Myklebust
nfs_server_capable(const struct inode * inode,int cap)3921a93b82cSTrond Myklebust static inline int nfs_server_capable(const struct inode *inode, int cap)
3931da177e4SLinus Torvalds {
3941da177e4SLinus Torvalds return NFS_SERVER(inode)->caps & cap;
3951da177e4SLinus Torvalds }
3961da177e4SLinus Torvalds
3971da177e4SLinus Torvalds /**
3981da177e4SLinus Torvalds * nfs_save_change_attribute - Returns the inode attribute change cookie
3998edb0182STrond Myklebust * @dir - pointer to parent directory inode
400efeda80dSTrond Myklebust * The "cache change attribute" is updated when we need to revalidate
401efeda80dSTrond Myklebust * our dentry cache after a directory was seen to change on the server.
4021da177e4SLinus Torvalds */
nfs_save_change_attribute(struct inode * dir)4038edb0182STrond Myklebust static inline unsigned long nfs_save_change_attribute(struct inode *dir)
4041da177e4SLinus Torvalds {
4058edb0182STrond Myklebust return NFS_I(dir)->cache_change_attribute;
4061da177e4SLinus Torvalds }
4071da177e4SLinus Torvalds
4081da177e4SLinus Torvalds /*
4091da177e4SLinus Torvalds * linux/fs/nfs/inode.c
4101da177e4SLinus Torvalds */
41129884df0STrond Myklebust extern int nfs_sync_mapping(struct address_space *mapping);
412cd9ae2b6STrond Myklebust extern void nfs_zap_mapping(struct inode *inode, struct address_space *mapping);
4131da177e4SLinus Torvalds extern void nfs_zap_caches(struct inode *);
41493ce4af7STrond Myklebust extern void nfs_set_inode_stale(struct inode *inode);
415c4812998STrond Myklebust extern void nfs_invalidate_atime(struct inode *);
4161da177e4SLinus Torvalds extern struct inode *nfs_fhget(struct super_block *, struct nfs_fh *,
417cf7ab00aSAnna Schumaker struct nfs_fattr *);
418f174ff7aSPeng Tao struct inode *nfs_ilookup(struct super_block *sb, struct nfs_fattr *, struct nfs_fh *);
4191da177e4SLinus Torvalds extern int nfs_refresh_inode(struct inode *, struct nfs_fattr *);
420decf491fSTrond Myklebust extern int nfs_post_op_update_inode(struct inode *inode, struct nfs_fattr *fattr);
42170ca8852STrond Myklebust extern int nfs_post_op_update_inode_force_wcc(struct inode *inode, struct nfs_fattr *fattr);
422a08a8cd3STrond Myklebust extern int nfs_post_op_update_inode_force_wcc_locked(struct inode *inode, struct nfs_fattr *fattr);
423b74d24f7SChristian Brauner extern int nfs_getattr(struct mnt_idmap *, const struct path *,
424549c7297SChristian Brauner struct kstat *, u32, unsigned int);
42573fbb3faSNeilBrown extern void nfs_access_add_cache(struct inode *, struct nfs_access_entry *, const struct cred *);
4266168f62cSWeston Andros Adamson extern void nfs_access_set_mask(struct nfs_access_entry *, u32);
4274609e1f1SChristian Brauner extern int nfs_permission(struct mnt_idmap *, struct inode *, int);
4281da177e4SLinus Torvalds extern int nfs_open(struct inode *, struct file *);
42943f291cdSScott Mayhew extern int nfs_attribute_cache_expired(struct inode *inode);
4301f3208b2STrond Myklebust extern int nfs_revalidate_inode(struct inode *inode, unsigned long flags);
4311da177e4SLinus Torvalds extern int __nfs_revalidate_inode(struct nfs_server *, struct inode *);
43228aa2f9eSTrond Myklebust extern int nfs_clear_invalid_mapping(struct address_space *mapping);
4331cd9cb05STrond Myklebust extern bool nfs_mapping_need_revalidate_inode(struct inode *inode);
43444b11874STrond Myklebust extern int nfs_revalidate_mapping(struct inode *inode, struct address_space *mapping);
4350d0def49SAl Viro extern int nfs_revalidate_mapping_rcu(struct inode *inode);
436c1632a0fSChristian Brauner extern int nfs_setattr(struct mnt_idmap *, struct dentry *, struct iattr *);
437f044636dSTrond Myklebust extern void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr, struct nfs_fattr *);
438dd225cb3SAnna Schumaker extern void nfs_setsecurity(struct inode *inode, struct nfs_fattr *fattr);
4391da177e4SLinus Torvalds extern struct nfs_open_context *get_nfs_open_context(struct nfs_open_context *ctx);
4401da177e4SLinus Torvalds extern void put_nfs_open_context(struct nfs_open_context *ctx);
441a52458b4SNeilBrown extern struct nfs_open_context *nfs_find_open_context(struct inode *inode, const struct cred *cred, fmode_t mode);
442532d4defSNeilBrown extern struct nfs_open_context *alloc_nfs_open_context(struct dentry *dentry, fmode_t f_mode, struct file *filp);
443c45ffdd2STrond Myklebust extern void nfs_inode_attach_open_context(struct nfs_open_context *ctx);
444cd9a1c0eSTrond Myklebust extern void nfs_file_set_open_context(struct file *filp, struct nfs_open_context *ctx);
445aff8d8dcSAnna Schumaker extern void nfs_file_clear_open_context(struct file *flip);
446f11ac8dbSTrond Myklebust extern struct nfs_lock_context *nfs_get_lock_context(struct nfs_open_context *ctx);
447f11ac8dbSTrond Myklebust extern void nfs_put_lock_context(struct nfs_lock_context *l_ctx);
448f43bf0beSTrond Myklebust extern u64 nfs_compat_user_ino64(u64 fileid);
4494704f0e2STrond Myklebust extern void nfs_fattr_init(struct nfs_fattr *fattr);
450140e049cSTrond Myklebust extern void nfs_fattr_set_barrier(struct nfs_fattr *fattr);
45156463e50SChuck Lever extern unsigned long nfs_inc_attr_generation_counter(void);
4521da177e4SLinus Torvalds
4532d36bfdeSTrond Myklebust extern struct nfs_fattr *nfs_alloc_fattr(void);
454d755ad8dSAnna Schumaker extern struct nfs_fattr *nfs_alloc_fattr_with_label(struct nfs_server *server);
455d755ad8dSAnna Schumaker
nfs4_label_free(struct nfs4_label * label)456d755ad8dSAnna Schumaker static inline void nfs4_label_free(struct nfs4_label *label)
457d755ad8dSAnna Schumaker {
458d755ad8dSAnna Schumaker #ifdef CONFIG_NFS_V4_SECURITY_LABEL
459d755ad8dSAnna Schumaker if (label) {
460d755ad8dSAnna Schumaker kfree(label->label);
461d755ad8dSAnna Schumaker kfree(label);
462d755ad8dSAnna Schumaker }
463d755ad8dSAnna Schumaker #endif
464d755ad8dSAnna Schumaker }
4652d36bfdeSTrond Myklebust
nfs_free_fattr(const struct nfs_fattr * fattr)4662d36bfdeSTrond Myklebust static inline void nfs_free_fattr(const struct nfs_fattr *fattr)
4672d36bfdeSTrond Myklebust {
468d755ad8dSAnna Schumaker if (fattr)
469d755ad8dSAnna Schumaker nfs4_label_free(fattr->label);
4702d36bfdeSTrond Myklebust kfree(fattr);
4712d36bfdeSTrond Myklebust }
4722d36bfdeSTrond Myklebust
4732d36bfdeSTrond Myklebust extern struct nfs_fh *nfs_alloc_fhandle(void);
4742d36bfdeSTrond Myklebust
nfs_free_fhandle(const struct nfs_fh * fh)4752d36bfdeSTrond Myklebust static inline void nfs_free_fhandle(const struct nfs_fh *fh)
4762d36bfdeSTrond Myklebust {
4772d36bfdeSTrond Myklebust kfree(fh);
4782d36bfdeSTrond Myklebust }
4792d36bfdeSTrond Myklebust
480e27d359eSTrond Myklebust #ifdef NFS_DEBUG
481d8e0539eSWeston Andros Adamson extern u32 _nfs_display_fhandle_hash(const struct nfs_fh *fh);
nfs_display_fhandle_hash(const struct nfs_fh * fh)482d8e0539eSWeston Andros Adamson static inline u32 nfs_display_fhandle_hash(const struct nfs_fh *fh)
483d8e0539eSWeston Andros Adamson {
484d8e0539eSWeston Andros Adamson return _nfs_display_fhandle_hash(fh);
485d8e0539eSWeston Andros Adamson }
48620d27e92SChuck Lever extern void _nfs_display_fhandle(const struct nfs_fh *fh, const char *caption);
48720d27e92SChuck Lever #define nfs_display_fhandle(fh, caption) \
48820d27e92SChuck Lever do { \
48920d27e92SChuck Lever if (unlikely(nfs_debug & NFSDBG_FACILITY)) \
49020d27e92SChuck Lever _nfs_display_fhandle(fh, caption); \
49120d27e92SChuck Lever } while (0)
49220d27e92SChuck Lever #else
nfs_display_fhandle_hash(const struct nfs_fh * fh)493d8e0539eSWeston Andros Adamson static inline u32 nfs_display_fhandle_hash(const struct nfs_fh *fh)
494d8e0539eSWeston Andros Adamson {
4959304a812SStephen Rothwell return 0;
496d8e0539eSWeston Andros Adamson }
nfs_display_fhandle(const struct nfs_fh * fh,const char * caption)49720d27e92SChuck Lever static inline void nfs_display_fhandle(const struct nfs_fh *fh,
49820d27e92SChuck Lever const char *caption)
49920d27e92SChuck Lever {
50020d27e92SChuck Lever }
50120d27e92SChuck Lever #endif
50220d27e92SChuck Lever
50356463e50SChuck Lever /*
50456463e50SChuck Lever * linux/fs/nfs/nfsroot.c
50556463e50SChuck Lever */
50656463e50SChuck Lever extern int nfs_root_data(char **root_device, char **root_data); /*__init*/
5071da177e4SLinus Torvalds /* linux/net/ipv4/ipconfig.c: trims ip addr off front of name, too. */
5085a874db4SAl Viro extern __be32 root_nfs_parse_addr(char *name); /*__init*/
5090e574af1STrond Myklebust
5101da177e4SLinus Torvalds /*
5111da177e4SLinus Torvalds * linux/fs/nfs/file.c
5121da177e4SLinus Torvalds */
5134b6f5d20SArjan van de Ven extern const struct file_operations nfs_file_operations;
51489d77c8fSBryan Schumaker #if IS_ENABLED(CONFIG_NFS_V4)
5151788ea6eSJeff Layton extern const struct file_operations nfs4_file_operations;
5161788ea6eSJeff Layton #endif /* CONFIG_NFS_V4 */
517f5e54d6eSChristoph Hellwig extern const struct address_space_operations nfs_file_aops;
51811de3b11STrond Myklebust extern const struct address_space_operations nfs_dir_aops;
5191da177e4SLinus Torvalds
nfs_file_open_context(struct file * filp)520c03025d5STrond Myklebust static inline struct nfs_open_context *nfs_file_open_context(struct file *filp)
521c03025d5STrond Myklebust {
522c03025d5STrond Myklebust return filp->private_data;
523c03025d5STrond Myklebust }
524c03025d5STrond Myklebust
nfs_file_cred(struct file * file)525a52458b4SNeilBrown static inline const struct cred *nfs_file_cred(struct file *file)
5261da177e4SLinus Torvalds {
527504e5189SNeil Brown if (file != NULL) {
528504e5189SNeil Brown struct nfs_open_context *ctx =
529504e5189SNeil Brown nfs_file_open_context(file);
530504e5189SNeil Brown if (ctx)
531504e5189SNeil Brown return ctx->cred;
532504e5189SNeil Brown }
5331da177e4SLinus Torvalds return NULL;
5341da177e4SLinus Torvalds }
5351da177e4SLinus Torvalds
5361da177e4SLinus Torvalds /*
5371da177e4SLinus Torvalds * linux/fs/nfs/direct.c
5381da177e4SLinus Torvalds */
539eb79f3afSNeilBrown int nfs_swap_rw(struct kiocb *iocb, struct iov_iter *iter);
54064158668SNeilBrown ssize_t nfs_file_direct_read(struct kiocb *iocb,
54164158668SNeilBrown struct iov_iter *iter, bool swap);
54264158668SNeilBrown ssize_t nfs_file_direct_write(struct kiocb *iocb,
54364158668SNeilBrown struct iov_iter *iter, bool swap);
5441da177e4SLinus Torvalds
5451da177e4SLinus Torvalds /*
5461da177e4SLinus Torvalds * linux/fs/nfs/dir.c
5471da177e4SLinus Torvalds */
5484b6f5d20SArjan van de Ven extern const struct file_operations nfs_dir_operations;
549f786aa90SAl Viro extern const struct dentry_operations nfs_dentry_operations;
5501da177e4SLinus Torvalds
551bfc69a45STrond Myklebust extern void nfs_force_lookup_revalidate(struct inode *dir);
552efeda80dSTrond Myklebust extern void nfs_set_verifier(struct dentry * dentry, unsigned long verf);
553efeda80dSTrond Myklebust #if IS_ENABLED(CONFIG_NFS_V4)
554efeda80dSTrond Myklebust extern void nfs_clear_verifier_delegated(struct inode *inode);
555efeda80dSTrond Myklebust #endif /* IS_ENABLED(CONFIG_NFS_V4) */
556406cd915SBenjamin Coddington extern struct dentry *nfs_add_or_obtain(struct dentry *dentry,
557cc6f3298SAnna Schumaker struct nfs_fh *fh, struct nfs_fattr *fattr);
5581775fd3eSDavid Quigley extern int nfs_instantiate(struct dentry *dentry, struct nfs_fh *fh,
559d91bfc46SAnna Schumaker struct nfs_fattr *fattr);
560b68572e0SNeilBrown extern int nfs_may_open(struct inode *inode, const struct cred *cred, int openflags);
561af22f94aSTrond Myklebust extern void nfs_access_zap_cache(struct inode *inode);
562b5e7b59cSNeilBrown extern int nfs_access_get_cached(struct inode *inode, const struct cred *cred,
563b5e7b59cSNeilBrown u32 *mask, bool may_block);
5641da177e4SLinus Torvalds
5651da177e4SLinus Torvalds /*
5661da177e4SLinus Torvalds * linux/fs/nfs/symlink.c
5671da177e4SLinus Torvalds */
568c5ef1c42SArjan van de Ven extern const struct inode_operations nfs_symlink_inode_operations;
5691da177e4SLinus Torvalds
5701da177e4SLinus Torvalds /*
571a72b4422STrond Myklebust * linux/fs/nfs/sysctl.c
572a72b4422STrond Myklebust */
573a72b4422STrond Myklebust #ifdef CONFIG_SYSCTL
574a72b4422STrond Myklebust extern int nfs_register_sysctl(void);
575a72b4422STrond Myklebust extern void nfs_unregister_sysctl(void);
576a72b4422STrond Myklebust #else
5777fd105e7SStephen Rothwell #define nfs_register_sysctl() 0
578a72b4422STrond Myklebust #define nfs_unregister_sysctl() do { } while(0)
579a72b4422STrond Myklebust #endif
580a72b4422STrond Myklebust
581a72b4422STrond Myklebust /*
58255a97593STrond Myklebust * linux/fs/nfs/namespace.c
58355a97593STrond Myklebust */
584c5ef1c42SArjan van de Ven extern const struct inode_operations nfs_mountpoint_inode_operations;
585c5ef1c42SArjan van de Ven extern const struct inode_operations nfs_referral_inode_operations;
58651d8fa6aSTrond Myklebust extern int nfs_mountpoint_expiry_timeout;
58751d8fa6aSTrond Myklebust extern void nfs_release_automount_timer(void);
58855a97593STrond Myklebust
58955a97593STrond Myklebust /*
5901da177e4SLinus Torvalds * linux/fs/nfs/unlink.c
5911da177e4SLinus Torvalds */
592e4eff1a6STrond Myklebust extern void nfs_complete_unlink(struct dentry *dentry, struct inode *);
5931da177e4SLinus Torvalds
5941da177e4SLinus Torvalds /*
5951da177e4SLinus Torvalds * linux/fs/nfs/write.c
5961da177e4SLinus Torvalds */
59789a09141SPeter Zijlstra extern int nfs_congestion_kb;
5981da177e4SLinus Torvalds extern int nfs_writepage(struct page *page, struct writeback_control *wbc);
5991da177e4SLinus Torvalds extern int nfs_writepages(struct address_space *, struct writeback_control *);
6000c493b5cSTrond Myklebust extern int nfs_flush_incompatible(struct file *file, struct folio *folio);
6010c493b5cSTrond Myklebust extern int nfs_update_folio(struct file *file, struct folio *folio,
6020c493b5cSTrond Myklebust unsigned int offset, unsigned int count);
6031da177e4SLinus Torvalds
6041da177e4SLinus Torvalds /*
6051da177e4SLinus Torvalds * Try to write back everything synchronously (but check the
6061da177e4SLinus Torvalds * return value!)
6071da177e4SLinus Torvalds */
6089e1681c2STrond Myklebust extern int nfs_sync_inode(struct inode *inode);
6091c75950bSTrond Myklebust extern int nfs_wb_all(struct inode *inode);
6104b27232aSTrond Myklebust extern int nfs_wb_folio(struct inode *inode, struct folio *folio);
6116d740c76SMatthew Wilcox (Oracle) int nfs_wb_folio_cancel(struct inode *inode, struct folio *folio);
612b608b283STrond Myklebust extern int nfs_commit_inode(struct inode *, int);
613515dcdcdSTrond Myklebust extern struct nfs_commit_data *nfs_commitdata_alloc(void);
6140b7c0153SFred Isaman extern void nfs_commit_free(struct nfs_commit_data *data);
615e25447c3SJosef Bacik void nfs_commit_begin(struct nfs_mds_commit_info *cinfo);
616133a48abSTrond Myklebust bool nfs_commit_end(struct nfs_mds_commit_info *cinfo);
6171da177e4SLinus Torvalds
nfs_have_writebacks(const struct inode * inode)6181a93b82cSTrond Myklebust static inline bool nfs_have_writebacks(const struct inode *inode)
6191da177e4SLinus Torvalds {
6200ebeebcfSDave Wysochanski if (S_ISREG(inode->i_mode))
621a6b6d5b8STrond Myklebust return atomic_long_read(&NFS_I(inode)->nrequests) != 0;
6221a93b82cSTrond Myklebust return false;
6231da177e4SLinus Torvalds }
6241da177e4SLinus Torvalds
6251da177e4SLinus Torvalds /*
6261da177e4SLinus Torvalds * linux/fs/nfs/read.c
6271da177e4SLinus Torvalds */
62865d023afSMatthew Wilcox (Oracle) int nfs_read_folio(struct file *, struct folio *);
6298786fde8SMatthew Wilcox (Oracle) void nfs_readahead(struct readahead_control *);
630963d8fe5STrond Myklebust
6311da177e4SLinus Torvalds /*
6321da177e4SLinus Torvalds * inline functions
6331da177e4SLinus Torvalds */
6341da177e4SLinus Torvalds
nfs_size_to_loff_t(__u64 size)635433c9237SChuck Lever static inline loff_t nfs_size_to_loff_t(__u64 size)
6361da177e4SLinus Torvalds {
63750ab8ec7SChristoph Hellwig return min_t(u64, size, OFFSET_MAX);
6381da177e4SLinus Torvalds }
6391da177e4SLinus Torvalds
6401da177e4SLinus Torvalds static inline ino_t
nfs_fileid_to_ino_t(u64 fileid)6411da177e4SLinus Torvalds nfs_fileid_to_ino_t(u64 fileid)
6421da177e4SLinus Torvalds {
6431da177e4SLinus Torvalds ino_t ino = (ino_t) fileid;
6441da177e4SLinus Torvalds if (sizeof(ino_t) < sizeof(u64))
6451da177e4SLinus Torvalds ino ^= fileid >> (sizeof(u64)-sizeof(ino_t)) * 8;
6461da177e4SLinus Torvalds return ino;
6471da177e4SLinus Torvalds }
6481da177e4SLinus Torvalds
nfs_ooo_clear(struct nfs_inode * nfsi)6493db63daaSNeilBrown static inline void nfs_ooo_clear(struct nfs_inode *nfsi)
6503db63daaSNeilBrown {
6513db63daaSNeilBrown nfsi->cache_validity &= ~NFS_INO_DATA_INVAL_DEFER;
6523db63daaSNeilBrown kfree(nfsi->ooo);
6533db63daaSNeilBrown nfsi->ooo = NULL;
6543db63daaSNeilBrown }
6553db63daaSNeilBrown
nfs_ooo_test(struct nfs_inode * nfsi)6563db63daaSNeilBrown static inline bool nfs_ooo_test(struct nfs_inode *nfsi)
6573db63daaSNeilBrown {
6583db63daaSNeilBrown return (nfsi->cache_validity & NFS_INO_DATA_INVAL_DEFER) ||
6593db63daaSNeilBrown (nfsi->ooo && nfsi->ooo->cnt > 0);
6603db63daaSNeilBrown
6613db63daaSNeilBrown }
6623db63daaSNeilBrown
6631da177e4SLinus Torvalds #define NFS_JUKEBOX_RETRY_TIME (5 * HZ)
6641da177e4SLinus Torvalds
6653c59366cSNeilBrown /* We need to block new opens while a file is being unlinked.
6663c59366cSNeilBrown * If it is opened *before* we decide to unlink, we will silly-rename
6673c59366cSNeilBrown * instead. If it is opened *after*, then we need to create or will fail.
6683c59366cSNeilBrown * If we allow the two to race, we could end up with a file that is open
6693c59366cSNeilBrown * but deleted on the server resulting in ESTALE.
6703c59366cSNeilBrown * So use ->d_fsdata to record when the unlink is happening
6713c59366cSNeilBrown * and block dentry revalidation while it is set.
6723c59366cSNeilBrown */
6733c59366cSNeilBrown #define NFS_FSDATA_BLOCKED ((void*)1)
6744dc2eaecSBenny Halevy
6751da177e4SLinus Torvalds # undef ifdebug
6761da177e4SLinus Torvalds # ifdef NFS_DEBUG
6771da177e4SLinus Torvalds # define ifdebug(fac) if (unlikely(nfs_debug & NFSDBG_##fac))
6786f00866dSTrond Myklebust # define NFS_IFDEBUG(x) x
6791da177e4SLinus Torvalds # else
6801da177e4SLinus Torvalds # define ifdebug(fac) if (0)
6816f00866dSTrond Myklebust # define NFS_IFDEBUG(x)
6821da177e4SLinus Torvalds # endif
6831da177e4SLinus Torvalds #endif
684