^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /* NFS filesystem cache interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (C) 2008 Red Hat, Inc. All Rights Reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Written by David Howells (dhowells@redhat.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/nfs_fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/nfs_fs_sb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/in6.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/seq_file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/iversion.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include "internal.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include "iostat.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include "fscache.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define NFSDBG_FACILITY NFSDBG_FSCACHE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) static struct rb_root nfs_fscache_keys = RB_ROOT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) static DEFINE_SPINLOCK(nfs_fscache_keys_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * Layout of the key for an NFS server cache object.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) struct nfs_server_key {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) uint16_t nfsversion; /* NFS protocol version */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) uint32_t minorversion; /* NFSv4 minor version */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) uint16_t family; /* address family */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) __be16 port; /* IP port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) } hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) union {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) struct in_addr ipv4_addr; /* IPv4 address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) struct in6_addr ipv6_addr; /* IPv6 address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) * Get the per-client index cookie for an NFS client if the appropriate mount
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * flag was set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) * - We always try and get an index cookie for the client, but get filehandle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) * cookies on a per-superblock basis, depending on the mount flags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) void nfs_fscache_get_client_cookie(struct nfs_client *clp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) const struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) &clp->cl_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) const struct sockaddr_in *sin = (struct sockaddr_in *) &clp->cl_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) struct nfs_server_key key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) uint16_t len = sizeof(key.hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) memset(&key, 0, sizeof(key));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) key.hdr.nfsversion = clp->rpc_ops->version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) key.hdr.minorversion = clp->cl_minorversion;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) key.hdr.family = clp->cl_addr.ss_family;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) switch (clp->cl_addr.ss_family) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) case AF_INET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) key.hdr.port = sin->sin_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) key.ipv4_addr = sin->sin_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) len += sizeof(key.ipv4_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) case AF_INET6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) key.hdr.port = sin6->sin6_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) key.ipv6_addr = sin6->sin6_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) len += sizeof(key.ipv6_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) printk(KERN_WARNING "NFS: Unknown network family '%d'\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) clp->cl_addr.ss_family);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) clp->fscache = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) /* create a cache index for looking up filehandles */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) clp->fscache = fscache_acquire_cookie(nfs_fscache_netfs.primary_index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) &nfs_fscache_server_index_def,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) &key, len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) NULL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) clp, 0, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) dfprintk(FSCACHE, "NFS: get client cookie (0x%p/0x%p)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) clp, clp->fscache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) * Dispose of a per-client cookie
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) void nfs_fscache_release_client_cookie(struct nfs_client *clp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) dfprintk(FSCACHE, "NFS: releasing client cookie (0x%p/0x%p)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) clp, clp->fscache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) fscache_relinquish_cookie(clp->fscache, NULL, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) clp->fscache = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) * Get the cache cookie for an NFS superblock. We have to handle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) * uniquification here because the cache doesn't do it for us.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) * The default uniquifier is just an empty string, but it may be overridden
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) * either by the 'fsc=xxx' option to mount, or by inheriting it from the parent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) * superblock across an automount point of some nature.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) void nfs_fscache_get_super_cookie(struct super_block *sb, const char *uniq, int ulen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) struct nfs_fscache_key *key, *xkey;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) struct nfs_server *nfss = NFS_SB(sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) struct rb_node **p, *parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) int diff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) nfss->fscache_key = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) nfss->fscache = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) if (!uniq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) uniq = "";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) ulen = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) key = kzalloc(sizeof(*key) + ulen, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) if (!key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) key->nfs_client = nfss->nfs_client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) key->key.super.s_flags = sb->s_flags & NFS_SB_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) key->key.nfs_server.flags = nfss->flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) key->key.nfs_server.rsize = nfss->rsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) key->key.nfs_server.wsize = nfss->wsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) key->key.nfs_server.acregmin = nfss->acregmin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) key->key.nfs_server.acregmax = nfss->acregmax;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) key->key.nfs_server.acdirmin = nfss->acdirmin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) key->key.nfs_server.acdirmax = nfss->acdirmax;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) key->key.nfs_server.fsid = nfss->fsid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) key->key.rpc_auth.au_flavor = nfss->client->cl_auth->au_flavor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) key->key.uniq_len = ulen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) memcpy(key->key.uniquifier, uniq, ulen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) spin_lock(&nfs_fscache_keys_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) p = &nfs_fscache_keys.rb_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) parent = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) while (*p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) parent = *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) xkey = rb_entry(parent, struct nfs_fscache_key, node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) if (key->nfs_client < xkey->nfs_client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) goto go_left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) if (key->nfs_client > xkey->nfs_client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) goto go_right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) diff = memcmp(&key->key, &xkey->key, sizeof(key->key));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) if (diff < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) goto go_left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) if (diff > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) goto go_right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) if (key->key.uniq_len == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) goto non_unique;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) diff = memcmp(key->key.uniquifier,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) xkey->key.uniquifier,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) key->key.uniq_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) if (diff < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) goto go_left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) if (diff > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) goto go_right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) goto non_unique;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) go_left:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) p = &(*p)->rb_left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) go_right:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) p = &(*p)->rb_right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) rb_link_node(&key->node, parent, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) rb_insert_color(&key->node, &nfs_fscache_keys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) spin_unlock(&nfs_fscache_keys_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) nfss->fscache_key = key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) /* create a cache index for looking up filehandles */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) nfss->fscache = fscache_acquire_cookie(nfss->nfs_client->fscache,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) &nfs_fscache_super_index_def,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) &key->key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) sizeof(key->key) + ulen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) NULL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) nfss, 0, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) dfprintk(FSCACHE, "NFS: get superblock cookie (0x%p/0x%p)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) nfss, nfss->fscache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) non_unique:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) spin_unlock(&nfs_fscache_keys_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) kfree(key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) nfss->fscache_key = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) nfss->fscache = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) printk(KERN_WARNING "NFS:"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) " Cache request denied due to non-unique superblock keys\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) * release a per-superblock cookie
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) void nfs_fscache_release_super_cookie(struct super_block *sb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) struct nfs_server *nfss = NFS_SB(sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) dfprintk(FSCACHE, "NFS: releasing superblock cookie (0x%p/0x%p)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) nfss, nfss->fscache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) fscache_relinquish_cookie(nfss->fscache, NULL, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) nfss->fscache = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) if (nfss->fscache_key) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) spin_lock(&nfs_fscache_keys_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) rb_erase(&nfss->fscache_key->node, &nfs_fscache_keys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) spin_unlock(&nfs_fscache_keys_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) kfree(nfss->fscache_key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) nfss->fscache_key = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) static void nfs_fscache_update_auxdata(struct nfs_fscache_inode_auxdata *auxdata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) struct nfs_inode *nfsi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) memset(auxdata, 0, sizeof(*auxdata));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) auxdata->mtime_sec = nfsi->vfs_inode.i_mtime.tv_sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) auxdata->mtime_nsec = nfsi->vfs_inode.i_mtime.tv_nsec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) auxdata->ctime_sec = nfsi->vfs_inode.i_ctime.tv_sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) auxdata->ctime_nsec = nfsi->vfs_inode.i_ctime.tv_nsec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) if (NFS_SERVER(&nfsi->vfs_inode)->nfs_client->rpc_ops->version == 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) auxdata->change_attr = inode_peek_iversion_raw(&nfsi->vfs_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) * Initialise the per-inode cache cookie pointer for an NFS inode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) void nfs_fscache_init_inode(struct inode *inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) struct nfs_fscache_inode_auxdata auxdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) struct nfs_server *nfss = NFS_SERVER(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) struct nfs_inode *nfsi = NFS_I(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) nfsi->fscache = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) if (!(nfss->fscache && S_ISREG(inode->i_mode)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) nfs_fscache_update_auxdata(&auxdata, nfsi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) nfsi->fscache = fscache_acquire_cookie(NFS_SB(inode->i_sb)->fscache,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) &nfs_fscache_inode_object_def,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) nfsi->fh.data, nfsi->fh.size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) &auxdata, sizeof(auxdata),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) nfsi, nfsi->vfs_inode.i_size, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) * Release a per-inode cookie.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) void nfs_fscache_clear_inode(struct inode *inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) struct nfs_fscache_inode_auxdata auxdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) struct nfs_inode *nfsi = NFS_I(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) struct fscache_cookie *cookie = nfs_i_fscache(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) dfprintk(FSCACHE, "NFS: clear cookie (0x%p/0x%p)\n", nfsi, cookie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) nfs_fscache_update_auxdata(&auxdata, nfsi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) fscache_relinquish_cookie(cookie, &auxdata, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) nfsi->fscache = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) static bool nfs_fscache_can_enable(void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) struct inode *inode = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) return !inode_is_open_for_write(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) * Enable or disable caching for a file that is being opened as appropriate.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) * The cookie is allocated when the inode is initialised, but is not enabled at
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) * that time. Enablement is deferred to file-open time to avoid stat() and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) * access() thrashing the cache.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) * For now, with NFS, only regular files that are open read-only will be able
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) * to use the cache.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) * We enable the cache for an inode if we open it read-only and it isn't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) * currently open for writing. We disable the cache if the inode is open
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) * write-only.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) * The caller uses the file struct to pin i_writecount on the inode before
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) * calling us when a file is opened for writing, so we can make use of that.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) * Note that this may be invoked multiple times in parallel by parallel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) * nfs_open() functions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) void nfs_fscache_open_file(struct inode *inode, struct file *filp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) struct nfs_fscache_inode_auxdata auxdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) struct nfs_inode *nfsi = NFS_I(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) struct fscache_cookie *cookie = nfs_i_fscache(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) if (!fscache_cookie_valid(cookie))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) nfs_fscache_update_auxdata(&auxdata, nfsi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) if (inode_is_open_for_write(inode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) dfprintk(FSCACHE, "NFS: nfsi 0x%p disabling cache\n", nfsi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) clear_bit(NFS_INO_FSCACHE, &nfsi->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) fscache_disable_cookie(cookie, &auxdata, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) fscache_uncache_all_inode_pages(cookie, inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) dfprintk(FSCACHE, "NFS: nfsi 0x%p enabling cache\n", nfsi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) fscache_enable_cookie(cookie, &auxdata, nfsi->vfs_inode.i_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) nfs_fscache_can_enable, inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) if (fscache_cookie_enabled(cookie))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) set_bit(NFS_INO_FSCACHE, &NFS_I(inode)->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) EXPORT_SYMBOL_GPL(nfs_fscache_open_file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) * Release the caching state associated with a page, if the page isn't busy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) * interacting with the cache.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) * - Returns true (can release page) or false (page busy).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) int nfs_fscache_release_page(struct page *page, gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) if (PageFsCache(page)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) struct fscache_cookie *cookie = nfs_i_fscache(page->mapping->host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) BUG_ON(!cookie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) dfprintk(FSCACHE, "NFS: fscache releasepage (0x%p/0x%p/0x%p)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) cookie, page, NFS_I(page->mapping->host));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) if (!fscache_maybe_release_page(cookie, page, gfp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) nfs_inc_fscache_stats(page->mapping->host,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) NFSIOS_FSCACHE_PAGES_UNCACHED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) * Release the caching state associated with a page if undergoing complete page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) * invalidation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) void __nfs_fscache_invalidate_page(struct page *page, struct inode *inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) struct fscache_cookie *cookie = nfs_i_fscache(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) BUG_ON(!cookie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) dfprintk(FSCACHE, "NFS: fscache invalidatepage (0x%p/0x%p/0x%p)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) cookie, page, NFS_I(inode));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) fscache_wait_on_page_write(cookie, page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) BUG_ON(!PageLocked(page));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) fscache_uncache_page(cookie, page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) nfs_inc_fscache_stats(page->mapping->host,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) NFSIOS_FSCACHE_PAGES_UNCACHED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) * Handle completion of a page being read from the cache.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) * - Called in process (keventd) context.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) static void nfs_readpage_from_fscache_complete(struct page *page,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) void *context,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) int error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) dfprintk(FSCACHE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) "NFS: readpage_from_fscache_complete (0x%p/0x%p/%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) page, context, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) /* if the read completes with an error, we just unlock the page and let
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) * the VM reissue the readpage */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) if (!error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) SetPageUptodate(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) unlock_page(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) error = nfs_readpage_async(context, page->mapping->host, page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) unlock_page(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) * Retrieve a page from fscache
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) int __nfs_readpage_from_fscache(struct nfs_open_context *ctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) struct inode *inode, struct page *page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) dfprintk(FSCACHE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) "NFS: readpage_from_fscache(fsc:%p/p:%p(i:%lx f:%lx)/0x%p)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) nfs_i_fscache(inode), page, page->index, page->flags, inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) ret = fscache_read_or_alloc_page(nfs_i_fscache(inode),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) page,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) nfs_readpage_from_fscache_complete,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) ctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) switch (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) case 0: /* read BIO submitted (page in fscache) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) dfprintk(FSCACHE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) "NFS: readpage_from_fscache: BIO submitted\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) nfs_inc_fscache_stats(inode, NFSIOS_FSCACHE_PAGES_READ_OK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) case -ENOBUFS: /* inode not in cache */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) case -ENODATA: /* page not in cache */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) nfs_inc_fscache_stats(inode, NFSIOS_FSCACHE_PAGES_READ_FAIL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) dfprintk(FSCACHE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) "NFS: readpage_from_fscache %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) dfprintk(FSCACHE, "NFS: readpage_from_fscache %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) nfs_inc_fscache_stats(inode, NFSIOS_FSCACHE_PAGES_READ_FAIL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) * Retrieve a set of pages from fscache
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) int __nfs_readpages_from_fscache(struct nfs_open_context *ctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) struct inode *inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) struct address_space *mapping,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) struct list_head *pages,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) unsigned *nr_pages)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) unsigned npages = *nr_pages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) dfprintk(FSCACHE, "NFS: nfs_getpages_from_fscache (0x%p/%u/0x%p)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) nfs_i_fscache(inode), npages, inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) ret = fscache_read_or_alloc_pages(nfs_i_fscache(inode),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) mapping, pages, nr_pages,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) nfs_readpage_from_fscache_complete,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) ctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) mapping_gfp_mask(mapping));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) if (*nr_pages < npages)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) nfs_add_fscache_stats(inode, NFSIOS_FSCACHE_PAGES_READ_OK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) npages);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) if (*nr_pages > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) nfs_add_fscache_stats(inode, NFSIOS_FSCACHE_PAGES_READ_FAIL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) *nr_pages);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) switch (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) case 0: /* read submitted to the cache for all pages */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) BUG_ON(!list_empty(pages));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) BUG_ON(*nr_pages != 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) dfprintk(FSCACHE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) "NFS: nfs_getpages_from_fscache: submitted\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) case -ENOBUFS: /* some pages aren't cached and can't be */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) case -ENODATA: /* some pages aren't cached */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) dfprintk(FSCACHE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) "NFS: nfs_getpages_from_fscache: no page: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) dfprintk(FSCACHE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) "NFS: nfs_getpages_from_fscache: ret %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) * Store a newly fetched page in fscache
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) * - PG_fscache must be set on the page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) void __nfs_readpage_to_fscache(struct inode *inode, struct page *page, int sync)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) dfprintk(FSCACHE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) "NFS: readpage_to_fscache(fsc:%p/p:%p(i:%lx f:%lx)/%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) nfs_i_fscache(inode), page, page->index, page->flags, sync);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) ret = fscache_write_page(nfs_i_fscache(inode), page,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) inode->i_size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) dfprintk(FSCACHE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) "NFS: readpage_to_fscache: p:%p(i:%lu f:%lx) ret %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) page, page->index, page->flags, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) if (ret != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) fscache_uncache_page(nfs_i_fscache(inode), page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) nfs_inc_fscache_stats(inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) NFSIOS_FSCACHE_PAGES_WRITTEN_FAIL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) nfs_inc_fscache_stats(inode, NFSIOS_FSCACHE_PAGES_UNCACHED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) nfs_inc_fscache_stats(inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) NFSIOS_FSCACHE_PAGES_WRITTEN_OK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) }