Merge tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
[cris-mirror.git] / fs / afs / cache.c
blobf62ff71d28c9914e3c681db96969163191132c48
1 /* AFS caching stuff
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>
13 #include "internal.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_volume_cache_get_key(const void *cookie_netfs_data,
18 void *buffer, uint16_t buflen);
20 static uint16_t afs_vnode_cache_get_key(const void *cookie_netfs_data,
21 void *buffer, uint16_t buflen);
22 static void afs_vnode_cache_get_attr(const void *cookie_netfs_data,
23 uint64_t *size);
24 static uint16_t afs_vnode_cache_get_aux(const void *cookie_netfs_data,
25 void *buffer, uint16_t buflen);
26 static enum fscache_checkaux afs_vnode_cache_check_aux(void *cookie_netfs_data,
27 const void *buffer,
28 uint16_t buflen);
30 struct fscache_netfs afs_cache_netfs = {
31 .name = "afs",
32 .version = 1,
35 struct 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,
41 struct 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,
47 struct 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,
57 * set the key for the index entry
59 static uint16_t afs_cell_cache_get_key(const void *cookie_netfs_data,
60 void *buffer, uint16_t bufmax)
62 const struct afs_cell *cell = cookie_netfs_data;
63 uint16_t klen;
65 _enter("%p,%p,%u", cell, buffer, bufmax);
67 klen = strlen(cell->name);
68 if (klen > bufmax)
69 return 0;
71 memcpy(buffer, cell->name, klen);
72 return klen;
75 /*****************************************************************************/
77 * set the key for the volume index entry
79 static uint16_t afs_volume_cache_get_key(const void *cookie_netfs_data,
80 void *buffer, uint16_t bufmax)
82 const struct afs_volume *volume = cookie_netfs_data;
83 struct {
84 u64 volid;
85 } __packed key;
87 _enter("{%u},%p,%u", volume->type, buffer, bufmax);
89 if (bufmax < sizeof(key))
90 return 0;
92 key.volid = volume->vid;
93 memcpy(buffer, &key, sizeof(key));
94 return sizeof(key);
97 /*****************************************************************************/
99 * set the key for the index entry
101 static uint16_t afs_vnode_cache_get_key(const void *cookie_netfs_data,
102 void *buffer, uint16_t bufmax)
104 const struct afs_vnode *vnode = cookie_netfs_data;
105 struct {
106 u32 vnode_id[3];
107 } __packed key;
109 _enter("{%x,%x,%llx},%p,%u",
110 vnode->fid.vnode, vnode->fid.unique, vnode->status.data_version,
111 buffer, bufmax);
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;
119 if (sizeof(key) > bufmax)
120 return 0;
122 memcpy(buffer, &key, sizeof(key));
123 return sizeof(key);
127 * provide updated file attributes
129 static void afs_vnode_cache_get_attr(const void *cookie_netfs_data,
130 uint64_t *size)
132 const struct afs_vnode *vnode = cookie_netfs_data;
134 _enter("{%x,%x,%llx},",
135 vnode->fid.vnode, vnode->fid.unique,
136 vnode->status.data_version);
138 *size = vnode->status.size;
141 struct afs_vnode_cache_aux {
142 u64 data_version;
143 u32 fid_unique;
144 } __packed;
147 * provide new auxiliary cache data
149 static uint16_t afs_vnode_cache_get_aux(const void *cookie_netfs_data,
150 void *buffer, uint16_t bufmax)
152 const struct afs_vnode *vnode = cookie_netfs_data;
153 struct afs_vnode_cache_aux aux;
155 _enter("{%x,%x,%Lx},%p,%u",
156 vnode->fid.vnode, vnode->fid.unique, vnode->status.data_version,
157 buffer, bufmax);
159 memset(&aux, 0, sizeof(aux));
160 aux.data_version = vnode->status.data_version;
161 aux.fid_unique = vnode->fid.unique;
163 if (bufmax < sizeof(aux))
164 return 0;
166 memcpy(buffer, &aux, sizeof(aux));
167 return sizeof(aux);
171 * check that the auxiliary data indicates that the entry is still valid
173 static enum fscache_checkaux afs_vnode_cache_check_aux(void *cookie_netfs_data,
174 const void *buffer,
175 uint16_t buflen)
177 struct afs_vnode *vnode = cookie_netfs_data;
178 struct afs_vnode_cache_aux aux;
180 _enter("{%x,%x,%llx},%p,%u",
181 vnode->fid.vnode, vnode->fid.unique, vnode->status.data_version,
182 buffer, buflen);
184 memcpy(&aux, buffer, sizeof(aux));
186 /* check the size of the data is what we're expecting */
187 if (buflen != sizeof(aux)) {
188 _leave(" = OBSOLETE [len %hx != %zx]", buflen, sizeof(aux));
189 return FSCACHE_CHECKAUX_OBSOLETE;
192 if (vnode->fid.unique != aux.fid_unique) {
193 _leave(" = OBSOLETE [uniq %x != %x]",
194 aux.fid_unique, vnode->fid.unique);
195 return FSCACHE_CHECKAUX_OBSOLETE;
198 if (vnode->status.data_version != aux.data_version) {
199 _leave(" = OBSOLETE [vers %llx != %llx]",
200 aux.data_version, vnode->status.data_version);
201 return FSCACHE_CHECKAUX_OBSOLETE;
204 _leave(" = SUCCESS");
205 return FSCACHE_CHECKAUX_OKAY;