18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */
28c2ecf20Sopenharmony_ci/* NFS filesystem cache interface definitions
38c2ecf20Sopenharmony_ci *
48c2ecf20Sopenharmony_ci * Copyright (C) 2008 Red Hat, Inc. All Rights Reserved.
58c2ecf20Sopenharmony_ci * Written by David Howells (dhowells@redhat.com)
68c2ecf20Sopenharmony_ci */
78c2ecf20Sopenharmony_ci
88c2ecf20Sopenharmony_ci#ifndef _NFS_FSCACHE_H
98c2ecf20Sopenharmony_ci#define _NFS_FSCACHE_H
108c2ecf20Sopenharmony_ci
118c2ecf20Sopenharmony_ci#include <linux/nfs_fs.h>
128c2ecf20Sopenharmony_ci#include <linux/nfs_mount.h>
138c2ecf20Sopenharmony_ci#include <linux/nfs4_mount.h>
148c2ecf20Sopenharmony_ci#include <linux/fscache.h>
158c2ecf20Sopenharmony_ci
168c2ecf20Sopenharmony_ci#ifdef CONFIG_NFS_FSCACHE
178c2ecf20Sopenharmony_ci
188c2ecf20Sopenharmony_ci/*
198c2ecf20Sopenharmony_ci * set of NFS FS-Cache objects that form a superblock key
208c2ecf20Sopenharmony_ci */
218c2ecf20Sopenharmony_cistruct nfs_fscache_key {
228c2ecf20Sopenharmony_ci	struct rb_node		node;
238c2ecf20Sopenharmony_ci	struct nfs_client	*nfs_client;	/* the server */
248c2ecf20Sopenharmony_ci
258c2ecf20Sopenharmony_ci	/* the elements of the unique key - as used by nfs_compare_super() and
268c2ecf20Sopenharmony_ci	 * nfs_compare_mount_options() to distinguish superblocks */
278c2ecf20Sopenharmony_ci	struct {
288c2ecf20Sopenharmony_ci		struct {
298c2ecf20Sopenharmony_ci			unsigned long	s_flags;	/* various flags
308c2ecf20Sopenharmony_ci							 * (& NFS_MS_MASK) */
318c2ecf20Sopenharmony_ci		} super;
328c2ecf20Sopenharmony_ci
338c2ecf20Sopenharmony_ci		struct {
348c2ecf20Sopenharmony_ci			struct nfs_fsid fsid;
358c2ecf20Sopenharmony_ci			int		flags;
368c2ecf20Sopenharmony_ci			unsigned int	rsize;		/* read size */
378c2ecf20Sopenharmony_ci			unsigned int	wsize;		/* write size */
388c2ecf20Sopenharmony_ci			unsigned int	acregmin;	/* attr cache timeouts */
398c2ecf20Sopenharmony_ci			unsigned int	acregmax;
408c2ecf20Sopenharmony_ci			unsigned int	acdirmin;
418c2ecf20Sopenharmony_ci			unsigned int	acdirmax;
428c2ecf20Sopenharmony_ci		} nfs_server;
438c2ecf20Sopenharmony_ci
448c2ecf20Sopenharmony_ci		struct {
458c2ecf20Sopenharmony_ci			rpc_authflavor_t au_flavor;
468c2ecf20Sopenharmony_ci		} rpc_auth;
478c2ecf20Sopenharmony_ci
488c2ecf20Sopenharmony_ci		/* uniquifier - can be used if nfs_server.flags includes
498c2ecf20Sopenharmony_ci		 * NFS_MOUNT_UNSHARED  */
508c2ecf20Sopenharmony_ci		u8 uniq_len;
518c2ecf20Sopenharmony_ci		char uniquifier[0];
528c2ecf20Sopenharmony_ci	} key;
538c2ecf20Sopenharmony_ci};
548c2ecf20Sopenharmony_ci
558c2ecf20Sopenharmony_ci/*
568c2ecf20Sopenharmony_ci * Definition of the auxiliary data attached to NFS inode storage objects
578c2ecf20Sopenharmony_ci * within the cache.
588c2ecf20Sopenharmony_ci *
598c2ecf20Sopenharmony_ci * The contents of this struct are recorded in the on-disk local cache in the
608c2ecf20Sopenharmony_ci * auxiliary data attached to the data storage object backing an inode.  This
618c2ecf20Sopenharmony_ci * permits coherency to be managed when a new inode binds to an already extant
628c2ecf20Sopenharmony_ci * cache object.
638c2ecf20Sopenharmony_ci */
648c2ecf20Sopenharmony_cistruct nfs_fscache_inode_auxdata {
658c2ecf20Sopenharmony_ci	s64	mtime_sec;
668c2ecf20Sopenharmony_ci	s64	mtime_nsec;
678c2ecf20Sopenharmony_ci	s64	ctime_sec;
688c2ecf20Sopenharmony_ci	s64	ctime_nsec;
698c2ecf20Sopenharmony_ci	u64	change_attr;
708c2ecf20Sopenharmony_ci};
718c2ecf20Sopenharmony_ci
728c2ecf20Sopenharmony_ci/*
738c2ecf20Sopenharmony_ci * fscache-index.c
748c2ecf20Sopenharmony_ci */
758c2ecf20Sopenharmony_ciextern struct fscache_netfs nfs_fscache_netfs;
768c2ecf20Sopenharmony_ciextern const struct fscache_cookie_def nfs_fscache_server_index_def;
778c2ecf20Sopenharmony_ciextern const struct fscache_cookie_def nfs_fscache_super_index_def;
788c2ecf20Sopenharmony_ciextern const struct fscache_cookie_def nfs_fscache_inode_object_def;
798c2ecf20Sopenharmony_ci
808c2ecf20Sopenharmony_ciextern int nfs_fscache_register(void);
818c2ecf20Sopenharmony_ciextern void nfs_fscache_unregister(void);
828c2ecf20Sopenharmony_ci
838c2ecf20Sopenharmony_ci/*
848c2ecf20Sopenharmony_ci * fscache.c
858c2ecf20Sopenharmony_ci */
868c2ecf20Sopenharmony_ciextern void nfs_fscache_get_client_cookie(struct nfs_client *);
878c2ecf20Sopenharmony_ciextern void nfs_fscache_release_client_cookie(struct nfs_client *);
888c2ecf20Sopenharmony_ci
898c2ecf20Sopenharmony_ciextern void nfs_fscache_get_super_cookie(struct super_block *, const char *, int);
908c2ecf20Sopenharmony_ciextern void nfs_fscache_release_super_cookie(struct super_block *);
918c2ecf20Sopenharmony_ci
928c2ecf20Sopenharmony_ciextern void nfs_fscache_init_inode(struct inode *);
938c2ecf20Sopenharmony_ciextern void nfs_fscache_clear_inode(struct inode *);
948c2ecf20Sopenharmony_ciextern void nfs_fscache_open_file(struct inode *, struct file *);
958c2ecf20Sopenharmony_ci
968c2ecf20Sopenharmony_ciextern void __nfs_fscache_invalidate_page(struct page *, struct inode *);
978c2ecf20Sopenharmony_ciextern int nfs_fscache_release_page(struct page *, gfp_t);
988c2ecf20Sopenharmony_ci
998c2ecf20Sopenharmony_ciextern int __nfs_readpage_from_fscache(struct nfs_open_context *,
1008c2ecf20Sopenharmony_ci				       struct inode *, struct page *);
1018c2ecf20Sopenharmony_ciextern int __nfs_readpages_from_fscache(struct nfs_open_context *,
1028c2ecf20Sopenharmony_ci					struct inode *, struct address_space *,
1038c2ecf20Sopenharmony_ci					struct list_head *, unsigned *);
1048c2ecf20Sopenharmony_ciextern void __nfs_readpage_to_fscache(struct inode *, struct page *, int);
1058c2ecf20Sopenharmony_ci
1068c2ecf20Sopenharmony_ci/*
1078c2ecf20Sopenharmony_ci * wait for a page to complete writing to the cache
1088c2ecf20Sopenharmony_ci */
1098c2ecf20Sopenharmony_cistatic inline void nfs_fscache_wait_on_page_write(struct nfs_inode *nfsi,
1108c2ecf20Sopenharmony_ci						  struct page *page)
1118c2ecf20Sopenharmony_ci{
1128c2ecf20Sopenharmony_ci	if (PageFsCache(page))
1138c2ecf20Sopenharmony_ci		fscache_wait_on_page_write(nfsi->fscache, page);
1148c2ecf20Sopenharmony_ci}
1158c2ecf20Sopenharmony_ci
1168c2ecf20Sopenharmony_ci/*
1178c2ecf20Sopenharmony_ci * release the caching state associated with a page if undergoing complete page
1188c2ecf20Sopenharmony_ci * invalidation
1198c2ecf20Sopenharmony_ci */
1208c2ecf20Sopenharmony_cistatic inline void nfs_fscache_invalidate_page(struct page *page,
1218c2ecf20Sopenharmony_ci					       struct inode *inode)
1228c2ecf20Sopenharmony_ci{
1238c2ecf20Sopenharmony_ci	if (PageFsCache(page))
1248c2ecf20Sopenharmony_ci		__nfs_fscache_invalidate_page(page, inode);
1258c2ecf20Sopenharmony_ci}
1268c2ecf20Sopenharmony_ci
1278c2ecf20Sopenharmony_ci/*
1288c2ecf20Sopenharmony_ci * Retrieve a page from an inode data storage object.
1298c2ecf20Sopenharmony_ci */
1308c2ecf20Sopenharmony_cistatic inline int nfs_readpage_from_fscache(struct nfs_open_context *ctx,
1318c2ecf20Sopenharmony_ci					    struct inode *inode,
1328c2ecf20Sopenharmony_ci					    struct page *page)
1338c2ecf20Sopenharmony_ci{
1348c2ecf20Sopenharmony_ci	if (NFS_I(inode)->fscache)
1358c2ecf20Sopenharmony_ci		return __nfs_readpage_from_fscache(ctx, inode, page);
1368c2ecf20Sopenharmony_ci	return -ENOBUFS;
1378c2ecf20Sopenharmony_ci}
1388c2ecf20Sopenharmony_ci
1398c2ecf20Sopenharmony_ci/*
1408c2ecf20Sopenharmony_ci * Retrieve a set of pages from an inode data storage object.
1418c2ecf20Sopenharmony_ci */
1428c2ecf20Sopenharmony_cistatic inline int nfs_readpages_from_fscache(struct nfs_open_context *ctx,
1438c2ecf20Sopenharmony_ci					     struct inode *inode,
1448c2ecf20Sopenharmony_ci					     struct address_space *mapping,
1458c2ecf20Sopenharmony_ci					     struct list_head *pages,
1468c2ecf20Sopenharmony_ci					     unsigned *nr_pages)
1478c2ecf20Sopenharmony_ci{
1488c2ecf20Sopenharmony_ci	if (NFS_I(inode)->fscache)
1498c2ecf20Sopenharmony_ci		return __nfs_readpages_from_fscache(ctx, inode, mapping, pages,
1508c2ecf20Sopenharmony_ci						    nr_pages);
1518c2ecf20Sopenharmony_ci	return -ENOBUFS;
1528c2ecf20Sopenharmony_ci}
1538c2ecf20Sopenharmony_ci
1548c2ecf20Sopenharmony_ci/*
1558c2ecf20Sopenharmony_ci * Store a page newly fetched from the server in an inode data storage object
1568c2ecf20Sopenharmony_ci * in the cache.
1578c2ecf20Sopenharmony_ci */
1588c2ecf20Sopenharmony_cistatic inline void nfs_readpage_to_fscache(struct inode *inode,
1598c2ecf20Sopenharmony_ci					   struct page *page,
1608c2ecf20Sopenharmony_ci					   int sync)
1618c2ecf20Sopenharmony_ci{
1628c2ecf20Sopenharmony_ci	if (PageFsCache(page))
1638c2ecf20Sopenharmony_ci		__nfs_readpage_to_fscache(inode, page, sync);
1648c2ecf20Sopenharmony_ci}
1658c2ecf20Sopenharmony_ci
1668c2ecf20Sopenharmony_ci/*
1678c2ecf20Sopenharmony_ci * Invalidate the contents of fscache for this inode.  This will not sleep.
1688c2ecf20Sopenharmony_ci */
1698c2ecf20Sopenharmony_cistatic inline void nfs_fscache_invalidate(struct inode *inode)
1708c2ecf20Sopenharmony_ci{
1718c2ecf20Sopenharmony_ci	fscache_invalidate(NFS_I(inode)->fscache);
1728c2ecf20Sopenharmony_ci}
1738c2ecf20Sopenharmony_ci
1748c2ecf20Sopenharmony_ci/*
1758c2ecf20Sopenharmony_ci * Wait for an object to finish being invalidated.
1768c2ecf20Sopenharmony_ci */
1778c2ecf20Sopenharmony_cistatic inline void nfs_fscache_wait_on_invalidate(struct inode *inode)
1788c2ecf20Sopenharmony_ci{
1798c2ecf20Sopenharmony_ci	fscache_wait_on_invalidate(NFS_I(inode)->fscache);
1808c2ecf20Sopenharmony_ci}
1818c2ecf20Sopenharmony_ci
1828c2ecf20Sopenharmony_ci/*
1838c2ecf20Sopenharmony_ci * indicate the client caching state as readable text
1848c2ecf20Sopenharmony_ci */
1858c2ecf20Sopenharmony_cistatic inline const char *nfs_server_fscache_state(struct nfs_server *server)
1868c2ecf20Sopenharmony_ci{
1878c2ecf20Sopenharmony_ci	if (server->fscache)
1888c2ecf20Sopenharmony_ci		return "yes";
1898c2ecf20Sopenharmony_ci	return "no ";
1908c2ecf20Sopenharmony_ci}
1918c2ecf20Sopenharmony_ci
1928c2ecf20Sopenharmony_ci#else /* CONFIG_NFS_FSCACHE */
1938c2ecf20Sopenharmony_cistatic inline int nfs_fscache_register(void) { return 0; }
1948c2ecf20Sopenharmony_cistatic inline void nfs_fscache_unregister(void) {}
1958c2ecf20Sopenharmony_ci
1968c2ecf20Sopenharmony_cistatic inline void nfs_fscache_get_client_cookie(struct nfs_client *clp) {}
1978c2ecf20Sopenharmony_cistatic inline void nfs_fscache_release_client_cookie(struct nfs_client *clp) {}
1988c2ecf20Sopenharmony_ci
1998c2ecf20Sopenharmony_cistatic inline void nfs_fscache_release_super_cookie(struct super_block *sb) {}
2008c2ecf20Sopenharmony_ci
2018c2ecf20Sopenharmony_cistatic inline void nfs_fscache_init_inode(struct inode *inode) {}
2028c2ecf20Sopenharmony_cistatic inline void nfs_fscache_clear_inode(struct inode *inode) {}
2038c2ecf20Sopenharmony_cistatic inline void nfs_fscache_open_file(struct inode *inode,
2048c2ecf20Sopenharmony_ci					 struct file *filp) {}
2058c2ecf20Sopenharmony_ci
2068c2ecf20Sopenharmony_cistatic inline int nfs_fscache_release_page(struct page *page, gfp_t gfp)
2078c2ecf20Sopenharmony_ci{
2088c2ecf20Sopenharmony_ci	return 1; /* True: may release page */
2098c2ecf20Sopenharmony_ci}
2108c2ecf20Sopenharmony_cistatic inline void nfs_fscache_invalidate_page(struct page *page,
2118c2ecf20Sopenharmony_ci					       struct inode *inode) {}
2128c2ecf20Sopenharmony_cistatic inline void nfs_fscache_wait_on_page_write(struct nfs_inode *nfsi,
2138c2ecf20Sopenharmony_ci						  struct page *page) {}
2148c2ecf20Sopenharmony_ci
2158c2ecf20Sopenharmony_cistatic inline int nfs_readpage_from_fscache(struct nfs_open_context *ctx,
2168c2ecf20Sopenharmony_ci					    struct inode *inode,
2178c2ecf20Sopenharmony_ci					    struct page *page)
2188c2ecf20Sopenharmony_ci{
2198c2ecf20Sopenharmony_ci	return -ENOBUFS;
2208c2ecf20Sopenharmony_ci}
2218c2ecf20Sopenharmony_cistatic inline int nfs_readpages_from_fscache(struct nfs_open_context *ctx,
2228c2ecf20Sopenharmony_ci					     struct inode *inode,
2238c2ecf20Sopenharmony_ci					     struct address_space *mapping,
2248c2ecf20Sopenharmony_ci					     struct list_head *pages,
2258c2ecf20Sopenharmony_ci					     unsigned *nr_pages)
2268c2ecf20Sopenharmony_ci{
2278c2ecf20Sopenharmony_ci	return -ENOBUFS;
2288c2ecf20Sopenharmony_ci}
2298c2ecf20Sopenharmony_cistatic inline void nfs_readpage_to_fscache(struct inode *inode,
2308c2ecf20Sopenharmony_ci					   struct page *page, int sync) {}
2318c2ecf20Sopenharmony_ci
2328c2ecf20Sopenharmony_ci
2338c2ecf20Sopenharmony_cistatic inline void nfs_fscache_invalidate(struct inode *inode) {}
2348c2ecf20Sopenharmony_cistatic inline void nfs_fscache_wait_on_invalidate(struct inode *inode) {}
2358c2ecf20Sopenharmony_ci
2368c2ecf20Sopenharmony_cistatic inline const char *nfs_server_fscache_state(struct nfs_server *server)
2378c2ecf20Sopenharmony_ci{
2388c2ecf20Sopenharmony_ci	return "no ";
2398c2ecf20Sopenharmony_ci}
2408c2ecf20Sopenharmony_ci
2418c2ecf20Sopenharmony_ci#endif /* CONFIG_NFS_FSCACHE */
2428c2ecf20Sopenharmony_ci#endif /* _NFS_FSCACHE_H */
243