summaryrefslogtreecommitdiffstats
path: root/include/linux/fscache.h
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2013-09-20 19:09:31 -0400
committerDavid Howells <dhowells@redhat.com>2013-09-27 13:40:25 -0400
commit94d30ae90a00cafe686c1057be57f4885f963abf (patch)
tree2a4f927bcaf87e988f4f180d0a011856064186b5 /include/linux/fscache.h
parent8fb883f3e30065529e4f35d4b4f355193dcdb7a2 (diff)
FS-Cache: Provide the ability to enable/disable cookies
Provide the ability to enable and disable fscache cookies. A disabled cookie will reject or ignore further requests to: Acquire a child cookie Invalidate and update backing objects Check the consistency of a backing object Allocate storage for backing page Read backing pages Write to backing pages but still allows: Checks/waits on the completion of already in-progress objects Uncaching of pages Relinquishment of cookies Two new operations are provided: (1) Disable a cookie: void fscache_disable_cookie(struct fscache_cookie *cookie, bool invalidate); If the cookie is not already disabled, this locks the cookie against other dis/enablement ops, marks the cookie as being disabled, discards or invalidates any backing objects and waits for cessation of activity on any associated object. This is a wrapper around a chunk split out of fscache_relinquish_cookie(), but it reinitialises the cookie such that it can be reenabled. All possible failures are handled internally. The caller should consider calling fscache_uncache_all_inode_pages() afterwards to make sure all page markings are cleared up. (2) Enable a cookie: void fscache_enable_cookie(struct fscache_cookie *cookie, bool (*can_enable)(void *data), void *data) If the cookie is not already enabled, this locks the cookie against other dis/enablement ops, invokes can_enable() and, if the cookie is not an index cookie, will begin the procedure of acquiring backing objects. The optional can_enable() function is passed the data argument and returns a ruling as to whether or not enablement should actually be permitted to begin. All possible failures are handled internally. The cookie will only be marked as enabled if provisional backing objects are allocated. A later patch will introduce these to NFS. Cookie enablement during nfs_open() is then contingent on i_writecount <= 0. can_enable() checks for a race between open(O_RDONLY) and open(O_WRONLY/O_RDWR). This simplifies NFS's cookie handling and allows us to get rid of open(O_RDONLY) accidentally introducing caching to an inode that's open for writing already. One operation has its API modified: (3) Acquire a cookie. struct fscache_cookie *fscache_acquire_cookie( struct fscache_cookie *parent, const struct fscache_cookie_def *def, void *netfs_data, bool enable); This now has an additional argument that indicates whether the requested cookie should be enabled by default. It doesn't need the can_enable() function because the caller must prevent multiple calls for the same netfs object and it doesn't need to take the enablement lock because no one else can get at the cookie before this returns. Signed-off-by: David Howells <dhowells@redhat.com
Diffstat (limited to 'include/linux/fscache.h')
-rw-r--r--include/linux/fscache.h113
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 */
176struct 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
200static 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 *);
181extern struct fscache_cookie *__fscache_acquire_cookie( 217extern 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);
185extern void __fscache_relinquish_cookie(struct fscache_cookie *, int); 221extern void __fscache_relinquish_cookie(struct fscache_cookie *, bool);
186extern int __fscache_check_consistency(struct fscache_cookie *); 222extern int __fscache_check_consistency(struct fscache_cookie *);
187extern void __fscache_update_cookie(struct fscache_cookie *); 223extern void __fscache_update_cookie(struct fscache_cookie *);
188extern int __fscache_attr_changed(struct fscache_cookie *); 224extern 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 *);
212extern void __fscache_readpages_cancel(struct fscache_cookie *cookie, 248extern void __fscache_readpages_cancel(struct fscache_cookie *cookie,
213 struct list_head *pages); 249 struct list_head *pages);
250extern void __fscache_disable_cookie(struct fscache_cookie *, bool);
251extern 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
301struct fscache_cookie *fscache_acquire_cookie( 341struct 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 */
324static inline 366static inline
325void fscache_relinquish_cookie(struct fscache_cookie *cookie, int retire) 367void 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)
341static inline 383static inline
342int fscache_check_consistency(struct fscache_cookie *cookie) 384int 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)
360static inline 402static inline
361void fscache_update_cookie(struct fscache_cookie *cookie) 403void 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)
407static inline 449static inline
408int fscache_attr_changed(struct fscache_cookie *cookie) 450int 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)
429static inline 471static inline
430void fscache_invalidate(struct fscache_cookie *cookie) 472void 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 */
803static inline
804void 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 */
823static inline
824void 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 */