aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cachefiles/interface.c
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2018-04-04 08:41:28 -0400
committerDavid Howells <dhowells@redhat.com>2018-04-04 08:41:28 -0400
commit402cb8dda949d9b8c0df20ad2527d139faad7ca1 (patch)
tree83cdb77f5490a0990eade886aa7f8dd087864996 /fs/cachefiles/interface.c
parent08c2e3d087840cd1e7141b62d92f3dc897147984 (diff)
fscache: Attach the index key and aux data to the cookie
Attach copies of the index key and auxiliary data to the fscache cookie so that: (1) The callbacks to the netfs for this stuff can be eliminated. This can simplify things in the cache as the information is still available, even after the cache has relinquished the cookie. (2) Simplifies the locking requirements of accessing the information as we don't have to worry about the netfs object going away on us. (3) The cache can do lazy updating of the coherency information on disk. As long as the cache is flushed before reboot/poweroff, there's no need to update the coherency info on disk every time it changes. (4) Cookies can be hashed or put in a tree as the index key is easily available. This allows: (a) Checks for duplicate cookies can be made at the top fscache layer rather than down in the bowels of the cache backend. (b) Caching can be added to a netfs object that has a cookie if the cache is brought online after the netfs object is allocated. A certain amount of space is made in the cookie for inline copies of the data, but if it won't fit there, extra memory will be allocated for it. The downside of this is that live cache operation requires more memory. Signed-off-by: David Howells <dhowells@redhat.com> Acked-by: Anna Schumaker <anna.schumaker@netapp.com> Tested-by: Steve Dickson <steved@redhat.com>
Diffstat (limited to 'fs/cachefiles/interface.c')
-rw-r--r--fs/cachefiles/interface.c38
1 files changed, 24 insertions, 14 deletions
diff --git a/fs/cachefiles/interface.c b/fs/cachefiles/interface.c
index 405ebc3932c2..3264dcfdc92a 100644
--- a/fs/cachefiles/interface.c
+++ b/fs/cachefiles/interface.c
@@ -32,7 +32,7 @@ static struct fscache_object *cachefiles_alloc_object(
32 struct cachefiles_cache *cache; 32 struct cachefiles_cache *cache;
33 struct cachefiles_xattr *auxdata; 33 struct cachefiles_xattr *auxdata;
34 unsigned keylen, auxlen; 34 unsigned keylen, auxlen;
35 void *buffer; 35 void *buffer, *p;
36 char *key; 36 char *key;
37 37
38 cache = container_of(_cache, struct cachefiles_cache, cache); 38 cache = container_of(_cache, struct cachefiles_cache, cache);
@@ -65,8 +65,12 @@ static struct fscache_object *cachefiles_alloc_object(
65 if (!buffer) 65 if (!buffer)
66 goto nomem_buffer; 66 goto nomem_buffer;
67 67
68 keylen = cookie->def->get_key(cookie->netfs_data, buffer + 2, 512); 68 keylen = cookie->key_len;
69 ASSERTCMP(keylen, <, 512); 69 if (keylen <= sizeof(cookie->inline_key))
70 p = cookie->inline_key;
71 else
72 p = cookie->key;
73 memcpy(buffer + 2, p, keylen);
70 74
71 *(uint16_t *)buffer = keylen; 75 *(uint16_t *)buffer = keylen;
72 ((char *)buffer)[keylen + 2] = 0; 76 ((char *)buffer)[keylen + 2] = 0;
@@ -80,15 +84,17 @@ static struct fscache_object *cachefiles_alloc_object(
80 84
81 /* get hold of the auxiliary data and prepend the object type */ 85 /* get hold of the auxiliary data and prepend the object type */
82 auxdata = buffer; 86 auxdata = buffer;
83 auxlen = 0; 87 auxlen = cookie->aux_len;
84 if (cookie->def->get_aux) { 88 if (auxlen) {
85 auxlen = cookie->def->get_aux(cookie->netfs_data, 89 if (auxlen <= sizeof(cookie->inline_aux))
86 auxdata->data, 511); 90 p = cookie->inline_aux;
87 ASSERTCMP(auxlen, <, 511); 91 else
92 p = cookie->aux;
93 memcpy(auxdata->data, p, auxlen);
88 } 94 }
89 95
90 auxdata->len = auxlen + 1; 96 auxdata->len = auxlen + 1;
91 auxdata->type = cookie->def->type; 97 auxdata->type = cookie->type;
92 98
93 lookup_data->auxdata = auxdata; 99 lookup_data->auxdata = auxdata;
94 lookup_data->key = key; 100 lookup_data->key = key;
@@ -206,6 +212,7 @@ static void cachefiles_update_object(struct fscache_object *_object)
206 struct cachefiles_cache *cache; 212 struct cachefiles_cache *cache;
207 struct fscache_cookie *cookie; 213 struct fscache_cookie *cookie;
208 const struct cred *saved_cred; 214 const struct cred *saved_cred;
215 const void *aux;
209 unsigned auxlen; 216 unsigned auxlen;
210 217
211 _enter("{OBJ%x}", _object->debug_id); 218 _enter("{OBJ%x}", _object->debug_id);
@@ -220,26 +227,29 @@ static void cachefiles_update_object(struct fscache_object *_object)
220 } 227 }
221 228
222 cookie = object->fscache.cookie; 229 cookie = object->fscache.cookie;
230 auxlen = cookie->aux_len;
223 231
224 if (!cookie->def->get_aux) { 232 if (!auxlen) {
225 fscache_unuse_cookie(_object); 233 fscache_unuse_cookie(_object);
226 _leave(" [no aux]"); 234 _leave(" [no aux]");
227 return; 235 return;
228 } 236 }
229 237
230 auxdata = kmalloc(2 + 512 + 3, cachefiles_gfp); 238 auxdata = kmalloc(2 + auxlen + 3, cachefiles_gfp);
231 if (!auxdata) { 239 if (!auxdata) {
232 fscache_unuse_cookie(_object); 240 fscache_unuse_cookie(_object);
233 _leave(" [nomem]"); 241 _leave(" [nomem]");
234 return; 242 return;
235 } 243 }
236 244
237 auxlen = cookie->def->get_aux(cookie->netfs_data, auxdata->data, 511); 245 aux = (auxlen <= sizeof(cookie->inline_aux)) ?
246 cookie->inline_aux : cookie->aux;
247
248 memcpy(auxdata->data, aux, auxlen);
238 fscache_unuse_cookie(_object); 249 fscache_unuse_cookie(_object);
239 ASSERTCMP(auxlen, <, 511);
240 250
241 auxdata->len = auxlen + 1; 251 auxdata->len = auxlen + 1;
242 auxdata->type = cookie->def->type; 252 auxdata->type = cookie->type;
243 253
244 cachefiles_begin_secure(cache, &saved_cred); 254 cachefiles_begin_secure(cache, &saved_cred);
245 cachefiles_update_object_xattr(object, auxdata); 255 cachefiles_update_object_xattr(object, auxdata);