3 * Copyright (C) 2008 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
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
;