diff options
author | David Howells <dhowells@redhat.com> | 2009-04-03 11:42:39 -0400 |
---|---|---|
committer | David Howells <dhowells@redhat.com> | 2009-04-03 11:42:39 -0400 |
commit | b510882281d56873e1194021643b7c325336f84f (patch) | |
tree | 86cd206b0d2b55dc355833ca238d46488161b64c /include/linux/fscache.h | |
parent | 952efe7b7840e1c726ae88222245e4efe6bd88f3 (diff) |
FS-Cache: Implement data I/O part of netfs API
Implement the data I/O part of the FS-Cache netfs API. The documentation and
API header file were added in a previous patch.
This patch implements the following functions for the netfs to call:
(*) fscache_attr_changed().
Indicate that the object has changed its attributes. The only attribute
currently recorded is the file size. Only pages within the set file size
will be stored in the cache.
This operation is submitted for asynchronous processing, and will return
immediately. It will return -ENOMEM if an out of memory error is
encountered, -ENOBUFS if the object is not actually cached, or 0 if the
operation is successfully queued.
(*) fscache_read_or_alloc_page().
(*) fscache_read_or_alloc_pages().
Request data be fetched from the disk, and allocate internal metadata to
track the netfs pages and reserve disk space for unknown pages.
These operations perform semi-asynchronous data reads. Upon returning
they will indicate which pages they think can be retrieved from disk, and
will have set in progress attempts to retrieve those pages.
These will return, in order of preference, -ENOMEM on memory allocation
error, -ERESTARTSYS if a signal interrupted proceedings, -ENODATA if one
or more requested pages are not yet cached, -ENOBUFS if the object is not
actually cached or if there isn't space for future pages to be cached on
this object, or 0 if successful.
In the case of the multipage function, the pages for which reads are set
in progress will be removed from the list and the page count decreased
appropriately.
If any read operations should fail, the completion function will be given
an error, and will also be passed contextual information to allow the
netfs to fall back to querying the server for the absent pages.
For each successful read, the page completion function will also be
called.
Any pages subsequently tracked by the cache will have PG_fscache set upon
them on return. fscache_uncache_page() must be called for such pages.
If supplied by the netfs, the mark_pages_cached() cookie op will be
invoked for any pages now tracked.
(*) fscache_alloc_page().
Allocate internal metadata to track a netfs page and reserve disk space.
This will return -ENOMEM on memory allocation error, -ERESTARTSYS on
signal, -ENOBUFS if the object isn't cached, or there isn't enough space
in the cache, or 0 if successful.
Any pages subsequently tracked by the cache will have PG_fscache set upon
them on return. fscache_uncache_page() must be called for such pages.
If supplied by the netfs, the mark_pages_cached() cookie op will be
invoked for any pages now tracked.
(*) fscache_write_page().
Request data be stored to disk. This may only be called on pages that
have been read or alloc'd by the above three functions and have not yet
been uncached.
This will return -ENOMEM on memory allocation error, -ERESTARTSYS on
signal, -ENOBUFS if the object isn't cached, or there isn't immediately
enough space in the cache, or 0 if successful.
On a successful return, this operation will have queued the page for
asynchronous writing to the cache. The page will be returned with
PG_fscache_write set until the write completes one way or another. The
caller will not be notified if the write fails due to an I/O error. If
that happens, the object will become available and all pending writes will
be aborted.
Note that the cache may batch up page writes, and so it may take a while
to get around to writing them out.
The caller must assume that until PG_fscache_write is cleared the page is
use by the cache. Any changes made to the page may be reflected on disk.
The page may even be under DMA.
(*) fscache_uncache_page().
Indicate that the cache should stop tracking a page previously read or
alloc'd from the cache. If the page was alloc'd only, but unwritten, it
will not appear on disk.
Signed-off-by: David Howells <dhowells@redhat.com>
Acked-by: Steve Dickson <steved@redhat.com>
Acked-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Acked-by: Al Viro <viro@zeniv.linux.org.uk>
Tested-by: Daire Byrne <Daire.Byrne@framestore.com>
Diffstat (limited to 'include/linux/fscache.h')
-rw-r--r-- | include/linux/fscache.h | 52 |
1 files changed, 47 insertions, 5 deletions
diff --git a/include/linux/fscache.h b/include/linux/fscache.h index 245b48646ef..6d8ee466e0a 100644 --- a/include/linux/fscache.h +++ b/include/linux/fscache.h | |||
@@ -184,6 +184,24 @@ extern struct fscache_cookie *__fscache_acquire_cookie( | |||
184 | void *); | 184 | void *); |
185 | extern void __fscache_relinquish_cookie(struct fscache_cookie *, int); | 185 | extern void __fscache_relinquish_cookie(struct fscache_cookie *, int); |
186 | extern void __fscache_update_cookie(struct fscache_cookie *); | 186 | extern void __fscache_update_cookie(struct fscache_cookie *); |
187 | extern int __fscache_attr_changed(struct fscache_cookie *); | ||
188 | extern int __fscache_read_or_alloc_page(struct fscache_cookie *, | ||
189 | struct page *, | ||
190 | fscache_rw_complete_t, | ||
191 | void *, | ||
192 | gfp_t); | ||
193 | extern int __fscache_read_or_alloc_pages(struct fscache_cookie *, | ||
194 | struct address_space *, | ||
195 | struct list_head *, | ||
196 | unsigned *, | ||
197 | fscache_rw_complete_t, | ||
198 | void *, | ||
199 | gfp_t); | ||
200 | extern int __fscache_alloc_page(struct fscache_cookie *, struct page *, gfp_t); | ||
201 | extern int __fscache_write_page(struct fscache_cookie *, struct page *, gfp_t); | ||
202 | extern void __fscache_uncache_page(struct fscache_cookie *, struct page *); | ||
203 | extern bool __fscache_check_page_write(struct fscache_cookie *, struct page *); | ||
204 | extern void __fscache_wait_on_page_write(struct fscache_cookie *, struct page *); | ||
187 | 205 | ||
188 | /** | 206 | /** |
189 | * fscache_register_netfs - Register a filesystem as desiring caching services | 207 | * fscache_register_netfs - Register a filesystem as desiring caching services |
@@ -361,7 +379,10 @@ void fscache_unpin_cookie(struct fscache_cookie *cookie) | |||
361 | static inline | 379 | static inline |
362 | int fscache_attr_changed(struct fscache_cookie *cookie) | 380 | int fscache_attr_changed(struct fscache_cookie *cookie) |
363 | { | 381 | { |
364 | return -ENOBUFS; | 382 | if (fscache_cookie_valid(cookie)) |
383 | return __fscache_attr_changed(cookie); | ||
384 | else | ||
385 | return -ENOBUFS; | ||
365 | } | 386 | } |
366 | 387 | ||
367 | /** | 388 | /** |
@@ -418,7 +439,11 @@ int fscache_read_or_alloc_page(struct fscache_cookie *cookie, | |||
418 | void *context, | 439 | void *context, |
419 | gfp_t gfp) | 440 | gfp_t gfp) |
420 | { | 441 | { |
421 | return -ENOBUFS; | 442 | if (fscache_cookie_valid(cookie)) |
443 | return __fscache_read_or_alloc_page(cookie, page, end_io_func, | ||
444 | context, gfp); | ||
445 | else | ||
446 | return -ENOBUFS; | ||
422 | } | 447 | } |
423 | 448 | ||
424 | /** | 449 | /** |
@@ -464,7 +489,12 @@ int fscache_read_or_alloc_pages(struct fscache_cookie *cookie, | |||
464 | void *context, | 489 | void *context, |
465 | gfp_t gfp) | 490 | gfp_t gfp) |
466 | { | 491 | { |
467 | return -ENOBUFS; | 492 | if (fscache_cookie_valid(cookie)) |
493 | return __fscache_read_or_alloc_pages(cookie, mapping, pages, | ||
494 | nr_pages, end_io_func, | ||
495 | context, gfp); | ||
496 | else | ||
497 | return -ENOBUFS; | ||
468 | } | 498 | } |
469 | 499 | ||
470 | /** | 500 | /** |
@@ -490,7 +520,10 @@ int fscache_alloc_page(struct fscache_cookie *cookie, | |||
490 | struct page *page, | 520 | struct page *page, |
491 | gfp_t gfp) | 521 | gfp_t gfp) |
492 | { | 522 | { |
493 | return -ENOBUFS; | 523 | if (fscache_cookie_valid(cookie)) |
524 | return __fscache_alloc_page(cookie, page, gfp); | ||
525 | else | ||
526 | return -ENOBUFS; | ||
494 | } | 527 | } |
495 | 528 | ||
496 | /** | 529 | /** |
@@ -516,7 +549,10 @@ int fscache_write_page(struct fscache_cookie *cookie, | |||
516 | struct page *page, | 549 | struct page *page, |
517 | gfp_t gfp) | 550 | gfp_t gfp) |
518 | { | 551 | { |
519 | return -ENOBUFS; | 552 | if (fscache_cookie_valid(cookie)) |
553 | return __fscache_write_page(cookie, page, gfp); | ||
554 | else | ||
555 | return -ENOBUFS; | ||
520 | } | 556 | } |
521 | 557 | ||
522 | /** | 558 | /** |
@@ -537,6 +573,8 @@ static inline | |||
537 | void fscache_uncache_page(struct fscache_cookie *cookie, | 573 | void fscache_uncache_page(struct fscache_cookie *cookie, |
538 | struct page *page) | 574 | struct page *page) |
539 | { | 575 | { |
576 | if (fscache_cookie_valid(cookie)) | ||
577 | __fscache_uncache_page(cookie, page); | ||
540 | } | 578 | } |
541 | 579 | ||
542 | /** | 580 | /** |
@@ -553,6 +591,8 @@ static inline | |||
553 | bool fscache_check_page_write(struct fscache_cookie *cookie, | 591 | bool fscache_check_page_write(struct fscache_cookie *cookie, |
554 | struct page *page) | 592 | struct page *page) |
555 | { | 593 | { |
594 | if (fscache_cookie_valid(cookie)) | ||
595 | return __fscache_check_page_write(cookie, page); | ||
556 | return false; | 596 | return false; |
557 | } | 597 | } |
558 | 598 | ||
@@ -571,6 +611,8 @@ static inline | |||
571 | void fscache_wait_on_page_write(struct fscache_cookie *cookie, | 611 | void fscache_wait_on_page_write(struct fscache_cookie *cookie, |
572 | struct page *page) | 612 | struct page *page) |
573 | { | 613 | { |
614 | if (fscache_cookie_valid(cookie)) | ||
615 | __fscache_wait_on_page_write(cookie, page); | ||
574 | } | 616 | } |
575 | 617 | ||
576 | #endif /* _LINUX_FSCACHE_H */ | 618 | #endif /* _LINUX_FSCACHE_H */ |