1 /* FS-Cache interface to CacheFiles
3 * Copyright (C) 2007 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 Licence
8 * as published by the Free Software Foundation; either version
9 * 2 of the Licence, or (at your option) any later version.
12 #include <linux/slab.h>
13 #include <linux/mount.h>
16 struct cachefiles_lookup_data
{
17 struct cachefiles_xattr
*auxdata
; /* auxiliary data */
18 char *key
; /* key path */
21 static int cachefiles_attr_changed(struct fscache_object
*_object
);
24 * allocate an object record for a cookie lookup and prepare the lookup data
26 static struct fscache_object
*cachefiles_alloc_object(
27 struct fscache_cache
*_cache
,
28 struct fscache_cookie
*cookie
)
30 struct cachefiles_lookup_data
*lookup_data
;
31 struct cachefiles_object
*object
;
32 struct cachefiles_cache
*cache
;
33 struct cachefiles_xattr
*auxdata
;
34 unsigned keylen
, auxlen
;
38 cache
= container_of(_cache
, struct cachefiles_cache
, cache
);
40 _enter("{%s},%p,", cache
->cache
.identifier
, cookie
);
42 lookup_data
= kmalloc(sizeof(*lookup_data
), cachefiles_gfp
);
44 goto nomem_lookup_data
;
46 /* create a new object record and a temporary leaf image */
47 object
= kmem_cache_alloc(cachefiles_object_jar
, cachefiles_gfp
);
51 ASSERTCMP(object
->backer
, ==, NULL
);
53 BUG_ON(test_bit(CACHEFILES_OBJECT_ACTIVE
, &object
->flags
));
54 atomic_set(&object
->usage
, 1);
56 fscache_object_init(&object
->fscache
, cookie
, &cache
->cache
);
58 object
->type
= cookie
->def
->type
;
60 /* get hold of the raw key
61 * - stick the length on the front and leave space on the back for the
64 buffer
= kmalloc((2 + 512) + 3, cachefiles_gfp
);
68 keylen
= cookie
->key_len
;
69 if (keylen
<= sizeof(cookie
->inline_key
))
70 p
= cookie
->inline_key
;
73 memcpy(buffer
+ 2, p
, keylen
);
75 *(uint16_t *)buffer
= keylen
;
76 ((char *)buffer
)[keylen
+ 2] = 0;
77 ((char *)buffer
)[keylen
+ 3] = 0;
78 ((char *)buffer
)[keylen
+ 4] = 0;
80 /* turn the raw key into something that can work with as a filename */
81 key
= cachefiles_cook_key(buffer
, keylen
+ 2, object
->type
);
85 /* get hold of the auxiliary data and prepend the object type */
87 auxlen
= cookie
->aux_len
;
89 if (auxlen
<= sizeof(cookie
->inline_aux
))
90 p
= cookie
->inline_aux
;
93 memcpy(auxdata
->data
, p
, auxlen
);
96 auxdata
->len
= auxlen
+ 1;
97 auxdata
->type
= cookie
->type
;
99 lookup_data
->auxdata
= auxdata
;
100 lookup_data
->key
= key
;
101 object
->lookup_data
= lookup_data
;
103 _leave(" = %p [%p]", &object
->fscache
, lookup_data
);
104 return &object
->fscache
;
109 BUG_ON(test_bit(CACHEFILES_OBJECT_ACTIVE
, &object
->flags
));
110 kmem_cache_free(cachefiles_object_jar
, object
);
111 fscache_object_destroyed(&cache
->cache
);
115 _leave(" = -ENOMEM");
116 return ERR_PTR(-ENOMEM
);
120 * attempt to look up the nominated node in this cache
121 * - return -ETIMEDOUT to be scheduled again
123 static int cachefiles_lookup_object(struct fscache_object
*_object
)
125 struct cachefiles_lookup_data
*lookup_data
;
126 struct cachefiles_object
*parent
, *object
;
127 struct cachefiles_cache
*cache
;
128 const struct cred
*saved_cred
;
131 _enter("{OBJ%x}", _object
->debug_id
);
133 cache
= container_of(_object
->cache
, struct cachefiles_cache
, cache
);
134 parent
= container_of(_object
->parent
,
135 struct cachefiles_object
, fscache
);
136 object
= container_of(_object
, struct cachefiles_object
, fscache
);
137 lookup_data
= object
->lookup_data
;
139 ASSERTCMP(lookup_data
, !=, NULL
);
141 /* look up the key, creating any missing bits */
142 cachefiles_begin_secure(cache
, &saved_cred
);
143 ret
= cachefiles_walk_to_object(parent
, object
,
145 lookup_data
->auxdata
);
146 cachefiles_end_secure(cache
, saved_cred
);
148 /* polish off by setting the attributes of non-index files */
150 object
->fscache
.cookie
->def
->type
!= FSCACHE_COOKIE_TYPE_INDEX
)
151 cachefiles_attr_changed(&object
->fscache
);
153 if (ret
< 0 && ret
!= -ETIMEDOUT
) {
155 pr_warn("Lookup failed error %d\n", ret
);
156 fscache_object_lookup_error(&object
->fscache
);
159 _leave(" [%d]", ret
);
164 * indication of lookup completion
166 static void cachefiles_lookup_complete(struct fscache_object
*_object
)
168 struct cachefiles_object
*object
;
170 object
= container_of(_object
, struct cachefiles_object
, fscache
);
172 _enter("{OBJ%x,%p}", object
->fscache
.debug_id
, object
->lookup_data
);
174 if (object
->lookup_data
) {
175 kfree(object
->lookup_data
->key
);
176 kfree(object
->lookup_data
->auxdata
);
177 kfree(object
->lookup_data
);
178 object
->lookup_data
= NULL
;
183 * increment the usage count on an inode object (may fail if unmounting)
186 struct fscache_object
*cachefiles_grab_object(struct fscache_object
*_object
,
187 enum fscache_obj_ref_trace why
)
189 struct cachefiles_object
*object
=
190 container_of(_object
, struct cachefiles_object
, fscache
);
193 _enter("{OBJ%x,%d}", _object
->debug_id
, atomic_read(&object
->usage
));
195 #ifdef CACHEFILES_DEBUG_SLAB
196 ASSERT((atomic_read(&object
->usage
) & 0xffff0000) != 0x6b6b0000);
199 u
= atomic_inc_return(&object
->usage
);
200 trace_cachefiles_ref(object
, _object
->cookie
,
201 (enum cachefiles_obj_ref_trace
)why
, u
);
202 return &object
->fscache
;
206 * update the auxiliary data for an object object on disk
208 static void cachefiles_update_object(struct fscache_object
*_object
)
210 struct cachefiles_object
*object
;
211 struct cachefiles_xattr
*auxdata
;
212 struct cachefiles_cache
*cache
;
213 struct fscache_cookie
*cookie
;
214 const struct cred
*saved_cred
;
218 _enter("{OBJ%x}", _object
->debug_id
);
220 object
= container_of(_object
, struct cachefiles_object
, fscache
);
221 cache
= container_of(object
->fscache
.cache
, struct cachefiles_cache
,
224 if (!fscache_use_cookie(_object
)) {
229 cookie
= object
->fscache
.cookie
;
230 auxlen
= cookie
->aux_len
;
233 fscache_unuse_cookie(_object
);
238 auxdata
= kmalloc(2 + auxlen
+ 3, cachefiles_gfp
);
240 fscache_unuse_cookie(_object
);
245 aux
= (auxlen
<= sizeof(cookie
->inline_aux
)) ?
246 cookie
->inline_aux
: cookie
->aux
;
248 memcpy(auxdata
->data
, aux
, auxlen
);
249 fscache_unuse_cookie(_object
);
251 auxdata
->len
= auxlen
+ 1;
252 auxdata
->type
= cookie
->type
;
254 cachefiles_begin_secure(cache
, &saved_cred
);
255 cachefiles_update_object_xattr(object
, auxdata
);
256 cachefiles_end_secure(cache
, saved_cred
);
262 * discard the resources pinned by an object and effect retirement if
265 static void cachefiles_drop_object(struct fscache_object
*_object
)
267 struct cachefiles_object
*object
;
268 struct cachefiles_cache
*cache
;
269 const struct cred
*saved_cred
;
271 blkcnt_t i_blocks
= 0;
275 object
= container_of(_object
, struct cachefiles_object
, fscache
);
278 object
->fscache
.debug_id
, atomic_read(&object
->usage
));
280 cache
= container_of(object
->fscache
.cache
,
281 struct cachefiles_cache
, cache
);
283 #ifdef CACHEFILES_DEBUG_SLAB
284 ASSERT((atomic_read(&object
->usage
) & 0xffff0000) != 0x6b6b0000);
287 /* We need to tidy the object up if we did in fact manage to open it.
288 * It's possible for us to get here before the object is fully
289 * initialised if the parent goes away or the object gets retired
290 * before we set it up.
292 if (object
->dentry
) {
293 /* delete retired objects */
294 if (test_bit(FSCACHE_OBJECT_RETIRED
, &object
->fscache
.flags
) &&
295 _object
!= cache
->cache
.fsdef
297 _debug("- retire object OBJ%x", object
->fscache
.debug_id
);
298 inode
= d_backing_inode(object
->dentry
);
300 i_blocks
= inode
->i_blocks
;
302 cachefiles_begin_secure(cache
, &saved_cred
);
303 cachefiles_delete_object(cache
, object
);
304 cachefiles_end_secure(cache
, saved_cred
);
307 /* close the filesystem stuff attached to the object */
308 if (object
->backer
!= object
->dentry
)
309 dput(object
->backer
);
310 object
->backer
= NULL
;
313 /* note that the object is now inactive */
314 if (test_bit(CACHEFILES_OBJECT_ACTIVE
, &object
->flags
))
315 cachefiles_mark_object_inactive(cache
, object
, i_blocks
);
317 dput(object
->dentry
);
318 object
->dentry
= NULL
;
324 * dispose of a reference to an object
326 static void cachefiles_put_object(struct fscache_object
*_object
,
327 enum fscache_obj_ref_trace why
)
329 struct cachefiles_object
*object
;
330 struct fscache_cache
*cache
;
335 object
= container_of(_object
, struct cachefiles_object
, fscache
);
338 object
->fscache
.debug_id
, atomic_read(&object
->usage
));
340 #ifdef CACHEFILES_DEBUG_SLAB
341 ASSERT((atomic_read(&object
->usage
) & 0xffff0000) != 0x6b6b0000);
344 ASSERTIFCMP(object
->fscache
.parent
,
345 object
->fscache
.parent
->n_children
, >, 0);
347 u
= atomic_dec_return(&object
->usage
);
348 trace_cachefiles_ref(object
, _object
->cookie
,
349 (enum cachefiles_obj_ref_trace
)why
, u
);
350 ASSERTCMP(u
, !=, -1);
352 _debug("- kill object OBJ%x", object
->fscache
.debug_id
);
354 ASSERT(!test_bit(CACHEFILES_OBJECT_ACTIVE
, &object
->flags
));
355 ASSERTCMP(object
->fscache
.parent
, ==, NULL
);
356 ASSERTCMP(object
->backer
, ==, NULL
);
357 ASSERTCMP(object
->dentry
, ==, NULL
);
358 ASSERTCMP(object
->fscache
.n_ops
, ==, 0);
359 ASSERTCMP(object
->fscache
.n_children
, ==, 0);
361 if (object
->lookup_data
) {
362 kfree(object
->lookup_data
->key
);
363 kfree(object
->lookup_data
->auxdata
);
364 kfree(object
->lookup_data
);
365 object
->lookup_data
= NULL
;
368 cache
= object
->fscache
.cache
;
369 fscache_object_destroy(&object
->fscache
);
370 kmem_cache_free(cachefiles_object_jar
, object
);
371 fscache_object_destroyed(cache
);
380 static void cachefiles_sync_cache(struct fscache_cache
*_cache
)
382 struct cachefiles_cache
*cache
;
383 const struct cred
*saved_cred
;
386 _enter("%p", _cache
);
388 cache
= container_of(_cache
, struct cachefiles_cache
, cache
);
390 /* make sure all pages pinned by operations on behalf of the netfs are
392 cachefiles_begin_secure(cache
, &saved_cred
);
393 down_read(&cache
->mnt
->mnt_sb
->s_umount
);
394 ret
= sync_filesystem(cache
->mnt
->mnt_sb
);
395 up_read(&cache
->mnt
->mnt_sb
->s_umount
);
396 cachefiles_end_secure(cache
, saved_cred
);
399 cachefiles_io_error(cache
,
400 "Attempt to sync backing fs superblock"
401 " returned error %d",
406 * check if the backing cache is updated to FS-Cache
407 * - called by FS-Cache when evaluates if need to invalidate the cache
409 static int cachefiles_check_consistency(struct fscache_operation
*op
)
411 struct cachefiles_object
*object
;
412 struct cachefiles_cache
*cache
;
413 const struct cred
*saved_cred
;
416 _enter("{OBJ%x}", op
->object
->debug_id
);
418 object
= container_of(op
->object
, struct cachefiles_object
, fscache
);
419 cache
= container_of(object
->fscache
.cache
,
420 struct cachefiles_cache
, cache
);
422 cachefiles_begin_secure(cache
, &saved_cred
);
423 ret
= cachefiles_check_auxdata(object
);
424 cachefiles_end_secure(cache
, saved_cred
);
426 _leave(" = %d", ret
);
431 * notification the attributes on an object have changed
432 * - called with reads/writes excluded by FS-Cache
434 static int cachefiles_attr_changed(struct fscache_object
*_object
)
436 struct cachefiles_object
*object
;
437 struct cachefiles_cache
*cache
;
438 const struct cred
*saved_cred
;
439 struct iattr newattrs
;
444 ni_size
= _object
->store_limit_l
;
446 _enter("{OBJ%x},[%llu]",
447 _object
->debug_id
, (unsigned long long) ni_size
);
449 object
= container_of(_object
, struct cachefiles_object
, fscache
);
450 cache
= container_of(object
->fscache
.cache
,
451 struct cachefiles_cache
, cache
);
453 if (ni_size
== object
->i_size
)
459 ASSERT(d_is_reg(object
->backer
));
461 fscache_set_store_limit(&object
->fscache
, ni_size
);
463 oi_size
= i_size_read(d_backing_inode(object
->backer
));
464 if (oi_size
== ni_size
)
467 cachefiles_begin_secure(cache
, &saved_cred
);
468 inode_lock(d_inode(object
->backer
));
470 /* if there's an extension to a partial page at the end of the backing
471 * file, we need to discard the partial page so that we pick up new
473 if (oi_size
& ~PAGE_MASK
&& ni_size
> oi_size
) {
474 _debug("discard tail %llx", oi_size
);
475 newattrs
.ia_valid
= ATTR_SIZE
;
476 newattrs
.ia_size
= oi_size
& PAGE_MASK
;
477 ret
= notify_change(object
->backer
, &newattrs
, NULL
);
479 goto truncate_failed
;
482 newattrs
.ia_valid
= ATTR_SIZE
;
483 newattrs
.ia_size
= ni_size
;
484 ret
= notify_change(object
->backer
, &newattrs
, NULL
);
487 inode_unlock(d_inode(object
->backer
));
488 cachefiles_end_secure(cache
, saved_cred
);
491 fscache_set_store_limit(&object
->fscache
, 0);
492 cachefiles_io_error_obj(object
, "Size set failed");
496 _leave(" = %d", ret
);
501 * Invalidate an object
503 static void cachefiles_invalidate_object(struct fscache_operation
*op
)
505 struct cachefiles_object
*object
;
506 struct cachefiles_cache
*cache
;
507 const struct cred
*saved_cred
;
512 object
= container_of(op
->object
, struct cachefiles_object
, fscache
);
513 cache
= container_of(object
->fscache
.cache
,
514 struct cachefiles_cache
, cache
);
516 ni_size
= op
->object
->store_limit_l
;
518 _enter("{OBJ%x},[%llu]",
519 op
->object
->debug_id
, (unsigned long long)ni_size
);
521 if (object
->backer
) {
522 ASSERT(d_is_reg(object
->backer
));
524 fscache_set_store_limit(&object
->fscache
, ni_size
);
526 path
.dentry
= object
->backer
;
527 path
.mnt
= cache
->mnt
;
529 cachefiles_begin_secure(cache
, &saved_cred
);
530 ret
= vfs_truncate(&path
, 0);
532 ret
= vfs_truncate(&path
, ni_size
);
533 cachefiles_end_secure(cache
, saved_cred
);
536 fscache_set_store_limit(&object
->fscache
, 0);
538 cachefiles_io_error_obj(object
,
539 "Invalidate failed");
543 fscache_op_complete(op
, true);
548 * dissociate a cache from all the pages it was backing
550 static void cachefiles_dissociate_pages(struct fscache_cache
*cache
)
555 const struct fscache_cache_ops cachefiles_cache_ops
= {
556 .name
= "cachefiles",
557 .alloc_object
= cachefiles_alloc_object
,
558 .lookup_object
= cachefiles_lookup_object
,
559 .lookup_complete
= cachefiles_lookup_complete
,
560 .grab_object
= cachefiles_grab_object
,
561 .update_object
= cachefiles_update_object
,
562 .invalidate_object
= cachefiles_invalidate_object
,
563 .drop_object
= cachefiles_drop_object
,
564 .put_object
= cachefiles_put_object
,
565 .sync_cache
= cachefiles_sync_cache
,
566 .attr_changed
= cachefiles_attr_changed
,
567 .read_or_alloc_page
= cachefiles_read_or_alloc_page
,
568 .read_or_alloc_pages
= cachefiles_read_or_alloc_pages
,
569 .allocate_page
= cachefiles_allocate_page
,
570 .allocate_pages
= cachefiles_allocate_pages
,
571 .write_page
= cachefiles_write_page
,
572 .uncache_page
= cachefiles_uncache_page
,
573 .dissociate_pages
= cachefiles_dissociate_pages
,
574 .check_consistency
= cachefiles_check_consistency
,