3 * Copyright (C) 2008 Red Hat, Inc. All Rights Reserved.
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.
12 #include <linux/sched.h>
15 static uint16_t afs_cell_cache_get_key(const void *cookie_netfs_data,
16 void *buffer, uint16_t buflen);
17 static uint16_t afs_cell_cache_get_aux(const void *cookie_netfs_data,
18 void *buffer, uint16_t buflen);
19 static enum fscache_checkaux afs_cell_cache_check_aux(void *cookie_netfs_data,
23 static uint16_t afs_vlocation_cache_get_key(const void *cookie_netfs_data,
24 void *buffer, uint16_t buflen);
25 static uint16_t afs_vlocation_cache_get_aux(const void *cookie_netfs_data,
26 void *buffer, uint16_t buflen);
27 static enum fscache_checkaux afs_vlocation_cache_check_aux(
28 void *cookie_netfs_data, const void *buffer, uint16_t buflen);
30 static uint16_t afs_volume_cache_get_key(const void *cookie_netfs_data,
31 void *buffer, uint16_t buflen);
33 static uint16_t afs_vnode_cache_get_key(const void *cookie_netfs_data,
34 void *buffer, uint16_t buflen);
35 static void afs_vnode_cache_get_attr(const void *cookie_netfs_data,
37 static uint16_t afs_vnode_cache_get_aux(const void *cookie_netfs_data,
38 void *buffer, uint16_t buflen);
39 static enum fscache_checkaux afs_vnode_cache_check_aux(void *cookie_netfs_data,
43 struct fscache_netfs afs_cache_netfs = {
48 struct fscache_cookie_def afs_cell_cache_index_def = {
50 .type = FSCACHE_COOKIE_TYPE_INDEX,
51 .get_key = afs_cell_cache_get_key,
52 .get_aux = afs_cell_cache_get_aux,
53 .check_aux = afs_cell_cache_check_aux,
56 struct fscache_cookie_def afs_vlocation_cache_index_def = {
58 .type = FSCACHE_COOKIE_TYPE_INDEX,
59 .get_key = afs_vlocation_cache_get_key,
60 .get_aux = afs_vlocation_cache_get_aux,
61 .check_aux = afs_vlocation_cache_check_aux,
64 struct fscache_cookie_def afs_volume_cache_index_def = {
66 .type = FSCACHE_COOKIE_TYPE_INDEX,
67 .get_key = afs_volume_cache_get_key,
70 struct fscache_cookie_def afs_vnode_cache_index_def = {
72 .type = FSCACHE_COOKIE_TYPE_DATAFILE,
73 .get_key = afs_vnode_cache_get_key,
74 .get_attr = afs_vnode_cache_get_attr,
75 .get_aux = afs_vnode_cache_get_aux,
76 .check_aux = afs_vnode_cache_check_aux,
80 * set the key for the index entry
82 static uint16_t afs_cell_cache_get_key(const void *cookie_netfs_data,
83 void *buffer, uint16_t bufmax)
85 const struct afs_cell *cell = cookie_netfs_data;
88 _enter("%p,%p,%u", cell, buffer, bufmax);
90 klen = strlen(cell->name);
94 memcpy(buffer, cell->name, klen);
99 * provide new auxiliary cache data
101 static uint16_t afs_cell_cache_get_aux(const void *cookie_netfs_data,
102 void *buffer, uint16_t bufmax)
104 const struct afs_cell *cell = cookie_netfs_data;
107 _enter("%p,%p,%u", cell, buffer, bufmax);
109 dlen = cell->vl_naddrs * sizeof(cell->vl_addrs[0]);
110 dlen = min(dlen, bufmax);
111 dlen &= ~(sizeof(cell->vl_addrs[0]) - 1);
113 memcpy(buffer, cell->vl_addrs, dlen);
118 * check that the auxiliary data indicates that the entry is still valid
120 static enum fscache_checkaux afs_cell_cache_check_aux(void *cookie_netfs_data,
125 return FSCACHE_CHECKAUX_OKAY;
128 /*****************************************************************************/
130 * set the key for the index entry
132 static uint16_t afs_vlocation_cache_get_key(const void *cookie_netfs_data,
133 void *buffer, uint16_t bufmax)
135 const struct afs_vlocation *vlocation = cookie_netfs_data;
138 _enter("{%s},%p,%u", vlocation->vldb.name, buffer, bufmax);
140 klen = strnlen(vlocation->vldb.name, sizeof(vlocation->vldb.name));
144 memcpy(buffer, vlocation->vldb.name, klen);
146 _leave(" = %u", klen);
151 * provide new auxiliary cache data
153 static uint16_t afs_vlocation_cache_get_aux(const void *cookie_netfs_data,
154 void *buffer, uint16_t bufmax)
156 const struct afs_vlocation *vlocation = cookie_netfs_data;
159 _enter("{%s},%p,%u", vlocation->vldb.name, buffer, bufmax);
161 dlen = sizeof(struct afs_cache_vlocation);
162 dlen -= offsetof(struct afs_cache_vlocation, nservers);
166 memcpy(buffer, (uint8_t *)&vlocation->vldb.nservers, dlen);
168 _leave(" = %u", dlen);
173 * check that the auxiliary data indicates that the entry is still valid
176 enum fscache_checkaux afs_vlocation_cache_check_aux(void *cookie_netfs_data,
180 const struct afs_cache_vlocation *cvldb;
181 struct afs_vlocation *vlocation = cookie_netfs_data;
184 _enter("{%s},%p,%u", vlocation->vldb.name, buffer, buflen);
186 /* check the size of the data is what we're expecting */
187 dlen = sizeof(struct afs_cache_vlocation);
188 dlen -= offsetof(struct afs_cache_vlocation, nservers);
190 return FSCACHE_CHECKAUX_OBSOLETE;
192 cvldb = container_of(buffer, struct afs_cache_vlocation, nservers);
194 /* if what's on disk is more valid than what's in memory, then use the
195 * VL record from the cache */
196 if (!vlocation->valid || vlocation->vldb.rtime == cvldb->rtime) {
197 memcpy((uint8_t *)&vlocation->vldb.nservers, buffer, dlen);
198 vlocation->valid = 1;
199 _leave(" = SUCCESS [c->m]");
200 return FSCACHE_CHECKAUX_OKAY;
203 /* need to update the cache if the cached info differs */
204 if (memcmp(&vlocation->vldb, buffer, dlen) != 0) {
205 /* delete if the volume IDs for this name differ */
206 if (memcmp(&vlocation->vldb.vid, &cvldb->vid,
207 sizeof(cvldb->vid)) != 0
209 _leave(" = OBSOLETE");
210 return FSCACHE_CHECKAUX_OBSOLETE;
214 return FSCACHE_CHECKAUX_NEEDS_UPDATE;
218 return FSCACHE_CHECKAUX_OKAY;
221 /*****************************************************************************/
223 * set the key for the volume index entry
225 static uint16_t afs_volume_cache_get_key(const void *cookie_netfs_data,
226 void *buffer, uint16_t bufmax)
228 const struct afs_volume *volume = cookie_netfs_data;
231 _enter("{%u},%p,%u", volume->type, buffer, bufmax);
233 klen = sizeof(volume->type);
237 memcpy(buffer, &volume->type, sizeof(volume->type));
239 _leave(" = %u", klen);
244 /*****************************************************************************/
246 * set the key for the index entry
248 static uint16_t afs_vnode_cache_get_key(const void *cookie_netfs_data,
249 void *buffer, uint16_t bufmax)
251 const struct afs_vnode *vnode = cookie_netfs_data;
254 _enter("{%x,%x,%llx},%p,%u",
255 vnode->fid.vnode, vnode->fid.unique, vnode->status.data_version,
258 klen = sizeof(vnode->fid.vnode);
262 memcpy(buffer, &vnode->fid.vnode, sizeof(vnode->fid.vnode));
264 _leave(" = %u", klen);
269 * provide updated file attributes
271 static void afs_vnode_cache_get_attr(const void *cookie_netfs_data,
274 const struct afs_vnode *vnode = cookie_netfs_data;
276 _enter("{%x,%x,%llx},",
277 vnode->fid.vnode, vnode->fid.unique,
278 vnode->status.data_version);
280 *size = vnode->status.size;
284 * provide new auxiliary cache data
286 static uint16_t afs_vnode_cache_get_aux(const void *cookie_netfs_data,
287 void *buffer, uint16_t bufmax)
289 const struct afs_vnode *vnode = cookie_netfs_data;
292 _enter("{%x,%x,%Lx},%p,%u",
293 vnode->fid.vnode, vnode->fid.unique, vnode->status.data_version,
296 dlen = sizeof(vnode->fid.unique) + sizeof(vnode->status.data_version);
300 memcpy(buffer, &vnode->fid.unique, sizeof(vnode->fid.unique));
301 buffer += sizeof(vnode->fid.unique);
302 memcpy(buffer, &vnode->status.data_version,
303 sizeof(vnode->status.data_version));
305 _leave(" = %u", dlen);
310 * check that the auxiliary data indicates that the entry is still valid
312 static enum fscache_checkaux afs_vnode_cache_check_aux(void *cookie_netfs_data,
316 struct afs_vnode *vnode = cookie_netfs_data;
319 _enter("{%x,%x,%llx},%p,%u",
320 vnode->fid.vnode, vnode->fid.unique, vnode->status.data_version,
323 /* check the size of the data is what we're expecting */
324 dlen = sizeof(vnode->fid.unique) + sizeof(vnode->status.data_version);
325 if (dlen != buflen) {
326 _leave(" = OBSOLETE [len %hx != %hx]", dlen, buflen);
327 return FSCACHE_CHECKAUX_OBSOLETE;
332 sizeof(vnode->fid.unique)
336 memcpy(&unique, buffer, sizeof(unique));
338 _leave(" = OBSOLETE [uniq %x != %x]",
339 unique, vnode->fid.unique);
340 return FSCACHE_CHECKAUX_OBSOLETE;
343 if (memcmp(buffer + sizeof(vnode->fid.unique),
344 &vnode->status.data_version,
345 sizeof(vnode->status.data_version)
347 afs_dataversion_t version;
349 memcpy(&version, buffer + sizeof(vnode->fid.unique),
352 _leave(" = OBSOLETE [vers %llx != %llx]",
353 version, vnode->status.data_version);
354 return FSCACHE_CHECKAUX_OBSOLETE;
357 _leave(" = SUCCESS");
358 return FSCACHE_CHECKAUX_OKAY;