]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blob - fs/afs/cache.c
drm/i915: Force 2*96 MHz cdclk on glk/cnl when audio power is enabled
[mirror_ubuntu-bionic-kernel.git] / fs / afs / cache.c
1 /* AFS caching stuff
2 *
3 * Copyright (C) 2008 Red Hat, Inc. All Rights Reserved.
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
12 #include <linux/sched.h>
13 #include "internal.h"
14
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);
19
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);
29
30 struct fscache_netfs afs_cache_netfs = {
31 .name = "afs",
32 .version = 1,
33 };
34
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,
39 };
40
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,
45 };
46
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,
54 };
55
56 /*
57 * set the key for the index entry
58 */
59 static uint16_t afs_cell_cache_get_key(const void *cookie_netfs_data,
60 void *buffer, uint16_t bufmax)
61 {
62 const struct afs_cell *cell = cookie_netfs_data;
63 uint16_t klen;
64
65 _enter("%p,%p,%u", cell, buffer, bufmax);
66
67 klen = strlen(cell->name);
68 if (klen > bufmax)
69 return 0;
70
71 memcpy(buffer, cell->name, klen);
72 return klen;
73 }
74
75 /*****************************************************************************/
76 /*
77 * set the key for the volume index entry
78 */
79 static uint16_t afs_volume_cache_get_key(const void *cookie_netfs_data,
80 void *buffer, uint16_t bufmax)
81 {
82 const struct afs_volume *volume = cookie_netfs_data;
83 struct {
84 u64 volid;
85 } __packed key;
86
87 _enter("{%u},%p,%u", volume->type, buffer, bufmax);
88
89 if (bufmax < sizeof(key))
90 return 0;
91
92 key.volid = volume->vid;
93 memcpy(buffer, &key, sizeof(key));
94 return sizeof(key);
95 }
96
97 /*****************************************************************************/
98 /*
99 * set the key for the index entry
100 */
101 static uint16_t afs_vnode_cache_get_key(const void *cookie_netfs_data,
102 void *buffer, uint16_t bufmax)
103 {
104 const struct afs_vnode *vnode = cookie_netfs_data;
105 struct {
106 u32 vnode_id[3];
107 } __packed key;
108
109 _enter("{%x,%x,%llx},%p,%u",
110 vnode->fid.vnode, vnode->fid.unique, vnode->status.data_version,
111 buffer, bufmax);
112
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;
118
119 if (sizeof(key) > bufmax)
120 return 0;
121
122 memcpy(buffer, &key, sizeof(key));
123 return sizeof(key);
124 }
125
126 /*
127 * provide updated file attributes
128 */
129 static void afs_vnode_cache_get_attr(const void *cookie_netfs_data,
130 uint64_t *size)
131 {
132 const struct afs_vnode *vnode = cookie_netfs_data;
133
134 _enter("{%x,%x,%llx},",
135 vnode->fid.vnode, vnode->fid.unique,
136 vnode->status.data_version);
137
138 *size = vnode->status.size;
139 }
140
141 struct afs_vnode_cache_aux {
142 u64 data_version;
143 u32 fid_unique;
144 } __packed;
145
146 /*
147 * provide new auxiliary cache data
148 */
149 static 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;
153 struct afs_vnode_cache_aux aux;
154
155 _enter("{%x,%x,%Lx},%p,%u",
156 vnode->fid.vnode, vnode->fid.unique, vnode->status.data_version,
157 buffer, bufmax);
158
159 memset(&aux, 0, sizeof(aux));
160 aux.data_version = vnode->status.data_version;
161 aux.fid_unique = vnode->fid.unique;
162
163 if (bufmax < sizeof(aux))
164 return 0;
165
166 memcpy(buffer, &aux, sizeof(aux));
167 return sizeof(aux);
168 }
169
170 /*
171 * check that the auxiliary data indicates that the entry is still valid
172 */
173 static enum fscache_checkaux afs_vnode_cache_check_aux(void *cookie_netfs_data,
174 const void *buffer,
175 uint16_t buflen)
176 {
177 struct afs_vnode *vnode = cookie_netfs_data;
178 struct afs_vnode_cache_aux aux;
179
180 _enter("{%x,%x,%llx},%p,%u",
181 vnode->fid.vnode, vnode->fid.unique, vnode->status.data_version,
182 buffer, buflen);
183
184 memcpy(&aux, buffer, sizeof(aux));
185
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;
190 }
191
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;
196 }
197
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;
202 }
203
204 _leave(" = SUCCESS");
205 return FSCACHE_CHECKAUX_OKAY;
206 }