diff options
Diffstat (limited to 'include/linux/fscache.h')
-rw-r--r-- | include/linux/fscache.h | 113 |
1 files changed, 99 insertions, 14 deletions
diff --git a/include/linux/fscache.h b/include/linux/fscache.h index 19b46458e4e8..115bb81912cc 100644 --- a/include/linux/fscache.h +++ b/include/linux/fscache.h | |||
@@ -167,6 +167,42 @@ struct fscache_netfs { | |||
167 | }; | 167 | }; |
168 | 168 | ||
169 | /* | 169 | /* |
170 | * data file or index object cookie | ||
171 | * - a file will only appear in one cache | ||
172 | * - a request to cache a file may or may not be honoured, subject to | ||
173 | * constraints such as disk space | ||
174 | * - indices are created on disk just-in-time | ||
175 | */ | ||
176 | struct fscache_cookie { | ||
177 | atomic_t usage; /* number of users of this cookie */ | ||
178 | atomic_t n_children; /* number of children of this cookie */ | ||
179 | atomic_t n_active; /* number of active users of netfs ptrs */ | ||
180 | spinlock_t lock; | ||
181 | spinlock_t stores_lock; /* lock on page store tree */ | ||
182 | struct hlist_head backing_objects; /* object(s) backing this file/index */ | ||
183 | const struct fscache_cookie_def *def; /* definition */ | ||
184 | struct fscache_cookie *parent; /* parent of this entry */ | ||
185 | void *netfs_data; /* back pointer to netfs */ | ||
186 | struct radix_tree_root stores; /* pages to be stored on this cookie */ | ||
187 | #define FSCACHE_COOKIE_PENDING_TAG 0 /* pages tag: pending write to cache */ | ||
188 | #define FSCACHE_COOKIE_STORING_TAG 1 /* pages tag: writing to cache */ | ||
189 | |||
190 | unsigned long flags; | ||
191 | #define FSCACHE_COOKIE_LOOKING_UP 0 /* T if non-index cookie being looked up still */ | ||
192 | #define FSCACHE_COOKIE_NO_DATA_YET 1 /* T if new object with no cached data yet */ | ||
193 | #define FSCACHE_COOKIE_UNAVAILABLE 2 /* T if cookie is unavailable (error, etc) */ | ||
194 | #define FSCACHE_COOKIE_INVALIDATING 3 /* T if cookie is being invalidated */ | ||
195 | #define FSCACHE_COOKIE_RELINQUISHED 4 /* T if cookie has been relinquished */ | ||
196 | #define FSCACHE_COOKIE_ENABLED 5 /* T if cookie is enabled */ | ||
197 | #define FSCACHE_COOKIE_ENABLEMENT_LOCK 6 /* T if cookie is being en/disabled */ | ||
198 | }; | ||
199 | |||
200 | static inline bool fscache_cookie_enabled(struct fscache_cookie *cookie) | ||
201 | { | ||
202 | return test_bit(FSCACHE_COOKIE_ENABLED, &cookie->flags); | ||
203 | } | ||
204 | |||
205 | /* | ||
170 | * slow-path functions for when there is actually caching available, and the | 206 | * slow-path functions for when there is actually caching available, and the |
171 | * netfs does actually have a valid token | 207 | * netfs does actually have a valid token |
172 | * - these are not to be called directly | 208 | * - these are not to be called directly |
@@ -181,8 +217,8 @@ extern void __fscache_release_cache_tag(struct fscache_cache_tag *); | |||
181 | extern struct fscache_cookie *__fscache_acquire_cookie( | 217 | extern struct fscache_cookie *__fscache_acquire_cookie( |
182 | struct fscache_cookie *, | 218 | struct fscache_cookie *, |
183 | const struct fscache_cookie_def *, | 219 | const struct fscache_cookie_def *, |
184 | void *); | 220 | void *, bool); |
185 | extern void __fscache_relinquish_cookie(struct fscache_cookie *, int); | 221 | extern void __fscache_relinquish_cookie(struct fscache_cookie *, bool); |
186 | extern int __fscache_check_consistency(struct fscache_cookie *); | 222 | extern int __fscache_check_consistency(struct fscache_cookie *); |
187 | extern void __fscache_update_cookie(struct fscache_cookie *); | 223 | extern void __fscache_update_cookie(struct fscache_cookie *); |
188 | extern int __fscache_attr_changed(struct fscache_cookie *); | 224 | extern int __fscache_attr_changed(struct fscache_cookie *); |
@@ -211,6 +247,9 @@ extern void __fscache_uncache_all_inode_pages(struct fscache_cookie *, | |||
211 | struct inode *); | 247 | struct inode *); |
212 | extern void __fscache_readpages_cancel(struct fscache_cookie *cookie, | 248 | extern void __fscache_readpages_cancel(struct fscache_cookie *cookie, |
213 | struct list_head *pages); | 249 | struct list_head *pages); |
250 | extern void __fscache_disable_cookie(struct fscache_cookie *, bool); | ||
251 | extern void __fscache_enable_cookie(struct fscache_cookie *, | ||
252 | bool (*)(void *), void *); | ||
214 | 253 | ||
215 | /** | 254 | /** |
216 | * fscache_register_netfs - Register a filesystem as desiring caching services | 255 | * fscache_register_netfs - Register a filesystem as desiring caching services |
@@ -289,6 +328,7 @@ void fscache_release_cache_tag(struct fscache_cache_tag *tag) | |||
289 | * @def: A description of the cache object, including callback operations | 328 | * @def: A description of the cache object, including callback operations |
290 | * @netfs_data: An arbitrary piece of data to be kept in the cookie to | 329 | * @netfs_data: An arbitrary piece of data to be kept in the cookie to |
291 | * represent the cache object to the netfs | 330 | * represent the cache object to the netfs |
331 | * @enable: Whether or not to enable a data cookie immediately | ||
292 | * | 332 | * |
293 | * This function is used to inform FS-Cache about part of an index hierarchy | 333 | * This function is used to inform FS-Cache about part of an index hierarchy |
294 | * that can be used to locate files. This is done by requesting a cookie for | 334 | * that can be used to locate files. This is done by requesting a cookie for |
@@ -301,10 +341,12 @@ static inline | |||
301 | struct fscache_cookie *fscache_acquire_cookie( | 341 | struct fscache_cookie *fscache_acquire_cookie( |
302 | struct fscache_cookie *parent, | 342 | struct fscache_cookie *parent, |
303 | const struct fscache_cookie_def *def, | 343 | const struct fscache_cookie_def *def, |
304 | void *netfs_data) | 344 | void *netfs_data, |
345 | bool enable) | ||
305 | { | 346 | { |
306 | if (fscache_cookie_valid(parent)) | 347 | if (fscache_cookie_valid(parent) && fscache_cookie_enabled(parent)) |
307 | return __fscache_acquire_cookie(parent, def, netfs_data); | 348 | return __fscache_acquire_cookie(parent, def, netfs_data, |
349 | enable); | ||
308 | else | 350 | else |
309 | return NULL; | 351 | return NULL; |
310 | } | 352 | } |
@@ -322,7 +364,7 @@ struct fscache_cookie *fscache_acquire_cookie( | |||
322 | * description. | 364 | * description. |
323 | */ | 365 | */ |
324 | static inline | 366 | static inline |
325 | void fscache_relinquish_cookie(struct fscache_cookie *cookie, int retire) | 367 | void fscache_relinquish_cookie(struct fscache_cookie *cookie, bool retire) |
326 | { | 368 | { |
327 | if (fscache_cookie_valid(cookie)) | 369 | if (fscache_cookie_valid(cookie)) |
328 | __fscache_relinquish_cookie(cookie, retire); | 370 | __fscache_relinquish_cookie(cookie, retire); |
@@ -341,7 +383,7 @@ void fscache_relinquish_cookie(struct fscache_cookie *cookie, int retire) | |||
341 | static inline | 383 | static inline |
342 | int fscache_check_consistency(struct fscache_cookie *cookie) | 384 | int fscache_check_consistency(struct fscache_cookie *cookie) |
343 | { | 385 | { |
344 | if (fscache_cookie_valid(cookie)) | 386 | if (fscache_cookie_valid(cookie) && fscache_cookie_enabled(cookie)) |
345 | return __fscache_check_consistency(cookie); | 387 | return __fscache_check_consistency(cookie); |
346 | else | 388 | else |
347 | return 0; | 389 | return 0; |
@@ -360,7 +402,7 @@ int fscache_check_consistency(struct fscache_cookie *cookie) | |||
360 | static inline | 402 | static inline |
361 | void fscache_update_cookie(struct fscache_cookie *cookie) | 403 | void fscache_update_cookie(struct fscache_cookie *cookie) |
362 | { | 404 | { |
363 | if (fscache_cookie_valid(cookie)) | 405 | if (fscache_cookie_valid(cookie) && fscache_cookie_enabled(cookie)) |
364 | __fscache_update_cookie(cookie); | 406 | __fscache_update_cookie(cookie); |
365 | } | 407 | } |
366 | 408 | ||
@@ -407,7 +449,7 @@ void fscache_unpin_cookie(struct fscache_cookie *cookie) | |||
407 | static inline | 449 | static inline |
408 | int fscache_attr_changed(struct fscache_cookie *cookie) | 450 | int fscache_attr_changed(struct fscache_cookie *cookie) |
409 | { | 451 | { |
410 | if (fscache_cookie_valid(cookie)) | 452 | if (fscache_cookie_valid(cookie) && fscache_cookie_enabled(cookie)) |
411 | return __fscache_attr_changed(cookie); | 453 | return __fscache_attr_changed(cookie); |
412 | else | 454 | else |
413 | return -ENOBUFS; | 455 | return -ENOBUFS; |
@@ -429,7 +471,7 @@ int fscache_attr_changed(struct fscache_cookie *cookie) | |||
429 | static inline | 471 | static inline |
430 | void fscache_invalidate(struct fscache_cookie *cookie) | 472 | void fscache_invalidate(struct fscache_cookie *cookie) |
431 | { | 473 | { |
432 | if (fscache_cookie_valid(cookie)) | 474 | if (fscache_cookie_valid(cookie) && fscache_cookie_enabled(cookie)) |
433 | __fscache_invalidate(cookie); | 475 | __fscache_invalidate(cookie); |
434 | } | 476 | } |
435 | 477 | ||
@@ -503,7 +545,7 @@ int fscache_read_or_alloc_page(struct fscache_cookie *cookie, | |||
503 | void *context, | 545 | void *context, |
504 | gfp_t gfp) | 546 | gfp_t gfp) |
505 | { | 547 | { |
506 | if (fscache_cookie_valid(cookie)) | 548 | if (fscache_cookie_valid(cookie) && fscache_cookie_enabled(cookie)) |
507 | return __fscache_read_or_alloc_page(cookie, page, end_io_func, | 549 | return __fscache_read_or_alloc_page(cookie, page, end_io_func, |
508 | context, gfp); | 550 | context, gfp); |
509 | else | 551 | else |
@@ -554,7 +596,7 @@ int fscache_read_or_alloc_pages(struct fscache_cookie *cookie, | |||
554 | void *context, | 596 | void *context, |
555 | gfp_t gfp) | 597 | gfp_t gfp) |
556 | { | 598 | { |
557 | if (fscache_cookie_valid(cookie)) | 599 | if (fscache_cookie_valid(cookie) && fscache_cookie_enabled(cookie)) |
558 | return __fscache_read_or_alloc_pages(cookie, mapping, pages, | 600 | return __fscache_read_or_alloc_pages(cookie, mapping, pages, |
559 | nr_pages, end_io_func, | 601 | nr_pages, end_io_func, |
560 | context, gfp); | 602 | context, gfp); |
@@ -585,7 +627,7 @@ int fscache_alloc_page(struct fscache_cookie *cookie, | |||
585 | struct page *page, | 627 | struct page *page, |
586 | gfp_t gfp) | 628 | gfp_t gfp) |
587 | { | 629 | { |
588 | if (fscache_cookie_valid(cookie)) | 630 | if (fscache_cookie_valid(cookie) && fscache_cookie_enabled(cookie)) |
589 | return __fscache_alloc_page(cookie, page, gfp); | 631 | return __fscache_alloc_page(cookie, page, gfp); |
590 | else | 632 | else |
591 | return -ENOBUFS; | 633 | return -ENOBUFS; |
@@ -634,7 +676,7 @@ int fscache_write_page(struct fscache_cookie *cookie, | |||
634 | struct page *page, | 676 | struct page *page, |
635 | gfp_t gfp) | 677 | gfp_t gfp) |
636 | { | 678 | { |
637 | if (fscache_cookie_valid(cookie)) | 679 | if (fscache_cookie_valid(cookie) && fscache_cookie_enabled(cookie)) |
638 | return __fscache_write_page(cookie, page, gfp); | 680 | return __fscache_write_page(cookie, page, gfp); |
639 | else | 681 | else |
640 | return -ENOBUFS; | 682 | return -ENOBUFS; |
@@ -744,4 +786,47 @@ void fscache_uncache_all_inode_pages(struct fscache_cookie *cookie, | |||
744 | __fscache_uncache_all_inode_pages(cookie, inode); | 786 | __fscache_uncache_all_inode_pages(cookie, inode); |
745 | } | 787 | } |
746 | 788 | ||
789 | /** | ||
790 | * fscache_disable_cookie - Disable a cookie | ||
791 | * @cookie: The cookie representing the cache object | ||
792 | * @invalidate: Invalidate the backing object | ||
793 | * | ||
794 | * Disable a cookie from accepting further alloc, read, write, invalidate, | ||
795 | * update or acquire operations. Outstanding operations can still be waited | ||
796 | * upon and pages can still be uncached and the cookie relinquished. | ||
797 | * | ||
798 | * This will not return until all outstanding operations have completed. | ||
799 | * | ||
800 | * If @invalidate is set, then the backing object will be invalidated and | ||
801 | * detached, otherwise it will just be detached. | ||
802 | */ | ||
803 | static inline | ||
804 | void fscache_disable_cookie(struct fscache_cookie *cookie, bool invalidate) | ||
805 | { | ||
806 | if (fscache_cookie_valid(cookie) && fscache_cookie_enabled(cookie)) | ||
807 | __fscache_disable_cookie(cookie, invalidate); | ||
808 | } | ||
809 | |||
810 | /** | ||
811 | * fscache_enable_cookie - Reenable a cookie | ||
812 | * @cookie: The cookie representing the cache object | ||
813 | * @can_enable: A function to permit enablement once lock is held | ||
814 | * @data: Data for can_enable() | ||
815 | * | ||
816 | * Reenable a previously disabled cookie, allowing it to accept further alloc, | ||
817 | * read, write, invalidate, update or acquire operations. An attempt will be | ||
818 | * made to immediately reattach the cookie to a backing object. | ||
819 | * | ||
820 | * The can_enable() function is called (if not NULL) once the enablement lock | ||
821 | * is held to rule on whether enablement is still permitted to go ahead. | ||
822 | */ | ||
823 | static inline | ||
824 | void fscache_enable_cookie(struct fscache_cookie *cookie, | ||
825 | bool (*can_enable)(void *data), | ||
826 | void *data) | ||
827 | { | ||
828 | if (fscache_cookie_valid(cookie) && !fscache_cookie_enabled(cookie)) | ||
829 | __fscache_enable_cookie(cookie, can_enable, data); | ||
830 | } | ||
831 | |||
747 | #endif /* _LINUX_FSCACHE_H */ | 832 | #endif /* _LINUX_FSCACHE_H */ |