]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - fs/afs/cache.c
Merge tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma
[mirror_ubuntu-bionic-kernel.git] / fs / afs / cache.c
CommitLineData
08e0e7c8
DH
1/* AFS caching stuff
2 *
9b3f26c9 3 * Copyright (C) 2008 Red Hat, Inc. All Rights Reserved.
08e0e7c8
DH
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11
9b3f26c9
DH
12#include <linux/sched.h>
13#include "internal.h"
14
15static uint16_t afs_cell_cache_get_key(const void *cookie_netfs_data,
16 void *buffer, uint16_t buflen);
9b3f26c9
DH
17static uint16_t afs_volume_cache_get_key(const void *cookie_netfs_data,
18 void *buffer, uint16_t buflen);
19
20static uint16_t afs_vnode_cache_get_key(const void *cookie_netfs_data,
21 void *buffer, uint16_t buflen);
22static void afs_vnode_cache_get_attr(const void *cookie_netfs_data,
23 uint64_t *size);
24static uint16_t afs_vnode_cache_get_aux(const void *cookie_netfs_data,
25 void *buffer, uint16_t buflen);
26static enum fscache_checkaux afs_vnode_cache_check_aux(void *cookie_netfs_data,
27 const void *buffer,
28 uint16_t buflen);
9b3f26c9
DH
29
30struct fscache_netfs afs_cache_netfs = {
31 .name = "afs",
ad6a942a 32 .version = 1,
9b3f26c9
DH
33};
34
35struct fscache_cookie_def afs_cell_cache_index_def = {
36 .name = "AFS.cell",
37 .type = FSCACHE_COOKIE_TYPE_INDEX,
38 .get_key = afs_cell_cache_get_key,
9b3f26c9
DH
39};
40
41struct fscache_cookie_def afs_volume_cache_index_def = {
42 .name = "AFS.volume",
43 .type = FSCACHE_COOKIE_TYPE_INDEX,
44 .get_key = afs_volume_cache_get_key,
45};
46
47struct fscache_cookie_def afs_vnode_cache_index_def = {
48 .name = "AFS.vnode",
49 .type = FSCACHE_COOKIE_TYPE_DATAFILE,
50 .get_key = afs_vnode_cache_get_key,
51 .get_attr = afs_vnode_cache_get_attr,
52 .get_aux = afs_vnode_cache_get_aux,
53 .check_aux = afs_vnode_cache_check_aux,
08e0e7c8 54};
08e0e7c8
DH
55
56/*
9b3f26c9 57 * set the key for the index entry
08e0e7c8 58 */
9b3f26c9
DH
59static uint16_t afs_cell_cache_get_key(const void *cookie_netfs_data,
60 void *buffer, uint16_t bufmax)
08e0e7c8 61{
9b3f26c9
DH
62 const struct afs_cell *cell = cookie_netfs_data;
63 uint16_t klen;
08e0e7c8 64
9b3f26c9 65 _enter("%p,%p,%u", cell, buffer, bufmax);
08e0e7c8 66
9b3f26c9
DH
67 klen = strlen(cell->name);
68 if (klen > bufmax)
69 return 0;
08e0e7c8 70
9b3f26c9
DH
71 memcpy(buffer, cell->name, klen);
72 return klen;
08e0e7c8 73}
08e0e7c8 74
9b3f26c9 75/*****************************************************************************/
08e0e7c8 76/*
9b3f26c9 77 * set the key for the volume index entry
08e0e7c8 78 */
9b3f26c9 79static uint16_t afs_volume_cache_get_key(const void *cookie_netfs_data,
ad6a942a 80 void *buffer, uint16_t bufmax)
08e0e7c8 81{
9b3f26c9 82 const struct afs_volume *volume = cookie_netfs_data;
ad6a942a
DH
83 struct {
84 u64 volid;
85 } __packed key;
9b3f26c9
DH
86
87 _enter("{%u},%p,%u", volume->type, buffer, bufmax);
88
ad6a942a 89 if (bufmax < sizeof(key))
9b3f26c9 90 return 0;
08e0e7c8 91
ad6a942a
DH
92 key.volid = volume->vid;
93 memcpy(buffer, &key, sizeof(key));
94 return sizeof(key);
08e0e7c8 95}
08e0e7c8 96
9b3f26c9 97/*****************************************************************************/
08e0e7c8 98/*
9b3f26c9 99 * set the key for the index entry
08e0e7c8 100 */
9b3f26c9
DH
101static uint16_t afs_vnode_cache_get_key(const void *cookie_netfs_data,
102 void *buffer, uint16_t bufmax)
08e0e7c8 103{
9b3f26c9 104 const struct afs_vnode *vnode = cookie_netfs_data;
ad6a942a
DH
105 struct {
106 u32 vnode_id[3];
107 } __packed key;
08e0e7c8 108
9b3f26c9
DH
109 _enter("{%x,%x,%llx},%p,%u",
110 vnode->fid.vnode, vnode->fid.unique, vnode->status.data_version,
111 buffer, bufmax);
08e0e7c8 112
ad6a942a
DH
113 /* Allow for a 96-bit key */
114 memset(&key, 0, sizeof(key));
115 key.vnode_id[0] = vnode->fid.vnode;
116 key.vnode_id[1] = 0;
117 key.vnode_id[2] = 0;
9b3f26c9 118
ad6a942a
DH
119 if (sizeof(key) > bufmax)
120 return 0;
08e0e7c8 121
ad6a942a
DH
122 memcpy(buffer, &key, sizeof(key));
123 return sizeof(key);
08e0e7c8 124}
08e0e7c8
DH
125
126/*
9b3f26c9 127 * provide updated file attributes
08e0e7c8 128 */
9b3f26c9
DH
129static void afs_vnode_cache_get_attr(const void *cookie_netfs_data,
130 uint64_t *size)
08e0e7c8 131{
9b3f26c9 132 const struct afs_vnode *vnode = cookie_netfs_data;
08e0e7c8 133
9b3f26c9
DH
134 _enter("{%x,%x,%llx},",
135 vnode->fid.vnode, vnode->fid.unique,
136 vnode->status.data_version);
08e0e7c8 137
9b3f26c9 138 *size = vnode->status.size;
08e0e7c8 139}
08e0e7c8 140
ad6a942a
DH
141struct afs_vnode_cache_aux {
142 u64 data_version;
143 u32 fid_unique;
144} __packed;
145
08e0e7c8 146/*
25985edc 147 * provide new auxiliary cache data
9b3f26c9
DH
148 */
149static uint16_t afs_vnode_cache_get_aux(const void *cookie_netfs_data,
150 void *buffer, uint16_t bufmax)
151{
152 const struct afs_vnode *vnode = cookie_netfs_data;
ad6a942a 153 struct afs_vnode_cache_aux aux;
9b3f26c9
DH
154
155 _enter("{%x,%x,%Lx},%p,%u",
156 vnode->fid.vnode, vnode->fid.unique, vnode->status.data_version,
157 buffer, bufmax);
158
ad6a942a
DH
159 memset(&aux, 0, sizeof(aux));
160 aux.data_version = vnode->status.data_version;
161 aux.fid_unique = vnode->fid.unique;
9b3f26c9 162
ad6a942a
DH
163 if (bufmax < sizeof(aux))
164 return 0;
9b3f26c9 165
ad6a942a
DH
166 memcpy(buffer, &aux, sizeof(aux));
167 return sizeof(aux);
9b3f26c9
DH
168}
169
170/*
25985edc 171 * check that the auxiliary data indicates that the entry is still valid
08e0e7c8 172 */
9b3f26c9
DH
173static enum fscache_checkaux afs_vnode_cache_check_aux(void *cookie_netfs_data,
174 const void *buffer,
175 uint16_t buflen)
08e0e7c8 176{
9b3f26c9 177 struct afs_vnode *vnode = cookie_netfs_data;
ad6a942a 178 struct afs_vnode_cache_aux aux;
9b3f26c9
DH
179
180 _enter("{%x,%x,%llx},%p,%u",
181 vnode->fid.vnode, vnode->fid.unique, vnode->status.data_version,
182 buffer, buflen);
183
ad6a942a
DH
184 memcpy(&aux, buffer, sizeof(aux));
185
9b3f26c9 186 /* check the size of the data is what we're expecting */
ad6a942a
DH
187 if (buflen != sizeof(aux)) {
188 _leave(" = OBSOLETE [len %hx != %zx]", buflen, sizeof(aux));
9b3f26c9 189 return FSCACHE_CHECKAUX_OBSOLETE;
08e0e7c8
DH
190 }
191
ad6a942a 192 if (vnode->fid.unique != aux.fid_unique) {
9b3f26c9 193 _leave(" = OBSOLETE [uniq %x != %x]",
ad6a942a 194 aux.fid_unique, vnode->fid.unique);
9b3f26c9
DH
195 return FSCACHE_CHECKAUX_OBSOLETE;
196 }
197
ad6a942a 198 if (vnode->status.data_version != aux.data_version) {
9b3f26c9 199 _leave(" = OBSOLETE [vers %llx != %llx]",
ad6a942a 200 aux.data_version, vnode->status.data_version);
9b3f26c9 201 return FSCACHE_CHECKAUX_OBSOLETE;
08e0e7c8
DH
202 }
203
204 _leave(" = SUCCESS");
9b3f26c9 205 return FSCACHE_CHECKAUX_OKAY;
08e0e7c8 206}