xref: /OK3568_Linux_fs/kernel/fs/nfs/fscache-index.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-or-later
2*4882a593Smuzhiyun /* NFS FS-Cache index structure definition
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  * Copyright (C) 2008 Red Hat, Inc. All Rights Reserved.
5*4882a593Smuzhiyun  * Written by David Howells (dhowells@redhat.com)
6*4882a593Smuzhiyun  */
7*4882a593Smuzhiyun 
8*4882a593Smuzhiyun #include <linux/init.h>
9*4882a593Smuzhiyun #include <linux/kernel.h>
10*4882a593Smuzhiyun #include <linux/sched.h>
11*4882a593Smuzhiyun #include <linux/mm.h>
12*4882a593Smuzhiyun #include <linux/nfs_fs.h>
13*4882a593Smuzhiyun #include <linux/nfs_fs_sb.h>
14*4882a593Smuzhiyun #include <linux/in6.h>
15*4882a593Smuzhiyun #include <linux/iversion.h>
16*4882a593Smuzhiyun 
17*4882a593Smuzhiyun #include "internal.h"
18*4882a593Smuzhiyun #include "fscache.h"
19*4882a593Smuzhiyun 
20*4882a593Smuzhiyun #define NFSDBG_FACILITY		NFSDBG_FSCACHE
21*4882a593Smuzhiyun 
22*4882a593Smuzhiyun /*
23*4882a593Smuzhiyun  * Define the NFS filesystem for FS-Cache.  Upon registration FS-Cache sticks
24*4882a593Smuzhiyun  * the cookie for the top-level index object for NFS into here.  The top-level
25*4882a593Smuzhiyun  * index can than have other cache objects inserted into it.
26*4882a593Smuzhiyun  */
27*4882a593Smuzhiyun struct fscache_netfs nfs_fscache_netfs = {
28*4882a593Smuzhiyun 	.name		= "nfs",
29*4882a593Smuzhiyun 	.version	= 0,
30*4882a593Smuzhiyun };
31*4882a593Smuzhiyun 
32*4882a593Smuzhiyun /*
33*4882a593Smuzhiyun  * Register NFS for caching
34*4882a593Smuzhiyun  */
nfs_fscache_register(void)35*4882a593Smuzhiyun int nfs_fscache_register(void)
36*4882a593Smuzhiyun {
37*4882a593Smuzhiyun 	return fscache_register_netfs(&nfs_fscache_netfs);
38*4882a593Smuzhiyun }
39*4882a593Smuzhiyun 
40*4882a593Smuzhiyun /*
41*4882a593Smuzhiyun  * Unregister NFS for caching
42*4882a593Smuzhiyun  */
nfs_fscache_unregister(void)43*4882a593Smuzhiyun void nfs_fscache_unregister(void)
44*4882a593Smuzhiyun {
45*4882a593Smuzhiyun 	fscache_unregister_netfs(&nfs_fscache_netfs);
46*4882a593Smuzhiyun }
47*4882a593Smuzhiyun 
48*4882a593Smuzhiyun /*
49*4882a593Smuzhiyun  * Define the server object for FS-Cache.  This is used to describe a server
50*4882a593Smuzhiyun  * object to fscache_acquire_cookie().  It is keyed by the NFS protocol and
51*4882a593Smuzhiyun  * server address parameters.
52*4882a593Smuzhiyun  */
53*4882a593Smuzhiyun const struct fscache_cookie_def nfs_fscache_server_index_def = {
54*4882a593Smuzhiyun 	.name		= "NFS.server",
55*4882a593Smuzhiyun 	.type 		= FSCACHE_COOKIE_TYPE_INDEX,
56*4882a593Smuzhiyun };
57*4882a593Smuzhiyun 
58*4882a593Smuzhiyun /*
59*4882a593Smuzhiyun  * Define the superblock object for FS-Cache.  This is used to describe a
60*4882a593Smuzhiyun  * superblock object to fscache_acquire_cookie().  It is keyed by all the NFS
61*4882a593Smuzhiyun  * parameters that might cause a separate superblock.
62*4882a593Smuzhiyun  */
63*4882a593Smuzhiyun const struct fscache_cookie_def nfs_fscache_super_index_def = {
64*4882a593Smuzhiyun 	.name		= "NFS.super",
65*4882a593Smuzhiyun 	.type 		= FSCACHE_COOKIE_TYPE_INDEX,
66*4882a593Smuzhiyun };
67*4882a593Smuzhiyun 
68*4882a593Smuzhiyun /*
69*4882a593Smuzhiyun  * Consult the netfs about the state of an object
70*4882a593Smuzhiyun  * - This function can be absent if the index carries no state data
71*4882a593Smuzhiyun  * - The netfs data from the cookie being used as the target is
72*4882a593Smuzhiyun  *   presented, as is the auxiliary data
73*4882a593Smuzhiyun  */
74*4882a593Smuzhiyun static
nfs_fscache_inode_check_aux(void * cookie_netfs_data,const void * data,uint16_t datalen,loff_t object_size)75*4882a593Smuzhiyun enum fscache_checkaux nfs_fscache_inode_check_aux(void *cookie_netfs_data,
76*4882a593Smuzhiyun 						  const void *data,
77*4882a593Smuzhiyun 						  uint16_t datalen,
78*4882a593Smuzhiyun 						  loff_t object_size)
79*4882a593Smuzhiyun {
80*4882a593Smuzhiyun 	struct nfs_fscache_inode_auxdata auxdata;
81*4882a593Smuzhiyun 	struct nfs_inode *nfsi = cookie_netfs_data;
82*4882a593Smuzhiyun 
83*4882a593Smuzhiyun 	if (datalen != sizeof(auxdata))
84*4882a593Smuzhiyun 		return FSCACHE_CHECKAUX_OBSOLETE;
85*4882a593Smuzhiyun 
86*4882a593Smuzhiyun 	memset(&auxdata, 0, sizeof(auxdata));
87*4882a593Smuzhiyun 	auxdata.mtime_sec  = nfsi->vfs_inode.i_mtime.tv_sec;
88*4882a593Smuzhiyun 	auxdata.mtime_nsec = nfsi->vfs_inode.i_mtime.tv_nsec;
89*4882a593Smuzhiyun 	auxdata.ctime_sec  = nfsi->vfs_inode.i_ctime.tv_sec;
90*4882a593Smuzhiyun 	auxdata.ctime_nsec = nfsi->vfs_inode.i_ctime.tv_nsec;
91*4882a593Smuzhiyun 
92*4882a593Smuzhiyun 	if (NFS_SERVER(&nfsi->vfs_inode)->nfs_client->rpc_ops->version == 4)
93*4882a593Smuzhiyun 		auxdata.change_attr = inode_peek_iversion_raw(&nfsi->vfs_inode);
94*4882a593Smuzhiyun 
95*4882a593Smuzhiyun 	if (memcmp(data, &auxdata, datalen) != 0)
96*4882a593Smuzhiyun 		return FSCACHE_CHECKAUX_OBSOLETE;
97*4882a593Smuzhiyun 
98*4882a593Smuzhiyun 	return FSCACHE_CHECKAUX_OKAY;
99*4882a593Smuzhiyun }
100*4882a593Smuzhiyun 
101*4882a593Smuzhiyun /*
102*4882a593Smuzhiyun  * Get an extra reference on a read context.
103*4882a593Smuzhiyun  * - This function can be absent if the completion function doesn't require a
104*4882a593Smuzhiyun  *   context.
105*4882a593Smuzhiyun  * - The read context is passed back to NFS in the event that a data read on the
106*4882a593Smuzhiyun  *   cache fails with EIO - in which case the server must be contacted to
107*4882a593Smuzhiyun  *   retrieve the data, which requires the read context for security.
108*4882a593Smuzhiyun  */
nfs_fh_get_context(void * cookie_netfs_data,void * context)109*4882a593Smuzhiyun static void nfs_fh_get_context(void *cookie_netfs_data, void *context)
110*4882a593Smuzhiyun {
111*4882a593Smuzhiyun 	get_nfs_open_context(context);
112*4882a593Smuzhiyun }
113*4882a593Smuzhiyun 
114*4882a593Smuzhiyun /*
115*4882a593Smuzhiyun  * Release an extra reference on a read context.
116*4882a593Smuzhiyun  * - This function can be absent if the completion function doesn't require a
117*4882a593Smuzhiyun  *   context.
118*4882a593Smuzhiyun  */
nfs_fh_put_context(void * cookie_netfs_data,void * context)119*4882a593Smuzhiyun static void nfs_fh_put_context(void *cookie_netfs_data, void *context)
120*4882a593Smuzhiyun {
121*4882a593Smuzhiyun 	if (context)
122*4882a593Smuzhiyun 		put_nfs_open_context(context);
123*4882a593Smuzhiyun }
124*4882a593Smuzhiyun 
125*4882a593Smuzhiyun /*
126*4882a593Smuzhiyun  * Define the inode object for FS-Cache.  This is used to describe an inode
127*4882a593Smuzhiyun  * object to fscache_acquire_cookie().  It is keyed by the NFS file handle for
128*4882a593Smuzhiyun  * an inode.
129*4882a593Smuzhiyun  *
130*4882a593Smuzhiyun  * Coherency is managed by comparing the copies of i_size, i_mtime and i_ctime
131*4882a593Smuzhiyun  * held in the cache auxiliary data for the data storage object with those in
132*4882a593Smuzhiyun  * the inode struct in memory.
133*4882a593Smuzhiyun  */
134*4882a593Smuzhiyun const struct fscache_cookie_def nfs_fscache_inode_object_def = {
135*4882a593Smuzhiyun 	.name		= "NFS.fh",
136*4882a593Smuzhiyun 	.type		= FSCACHE_COOKIE_TYPE_DATAFILE,
137*4882a593Smuzhiyun 	.check_aux	= nfs_fscache_inode_check_aux,
138*4882a593Smuzhiyun 	.get_context	= nfs_fh_get_context,
139*4882a593Smuzhiyun 	.put_context	= nfs_fh_put_context,
140*4882a593Smuzhiyun };
141