diff options
-rw-r--r-- | fs/cachefiles/rdwr.c | 34 | ||||
-rw-r--r-- | fs/fscache/page.c | 59 | ||||
-rw-r--r-- | include/linux/fscache-cache.h | 3 | ||||
-rw-r--r-- | include/linux/fscache.h | 12 |
4 files changed, 56 insertions, 52 deletions
diff --git a/fs/cachefiles/rdwr.c b/fs/cachefiles/rdwr.c index c994691d9445..3367abdcdac4 100644 --- a/fs/cachefiles/rdwr.c +++ b/fs/cachefiles/rdwr.c | |||
@@ -176,9 +176,8 @@ static void cachefiles_read_copier(struct fscache_operation *_op) | |||
176 | recheck: | 176 | recheck: |
177 | if (PageUptodate(monitor->back_page)) { | 177 | if (PageUptodate(monitor->back_page)) { |
178 | copy_highpage(monitor->netfs_page, monitor->back_page); | 178 | copy_highpage(monitor->netfs_page, monitor->back_page); |
179 | 179 | fscache_mark_page_cached(monitor->op, | |
180 | pagevec_add(&pagevec, monitor->netfs_page); | 180 | monitor->netfs_page); |
181 | fscache_mark_pages_cached(monitor->op, &pagevec); | ||
182 | error = 0; | 181 | error = 0; |
183 | } else if (!PageError(monitor->back_page)) { | 182 | } else if (!PageError(monitor->back_page)) { |
184 | /* the page has probably been truncated */ | 183 | /* the page has probably been truncated */ |
@@ -335,8 +334,7 @@ backing_page_already_present: | |||
335 | backing_page_already_uptodate: | 334 | backing_page_already_uptodate: |
336 | _debug("- uptodate"); | 335 | _debug("- uptodate"); |
337 | 336 | ||
338 | pagevec_add(pagevec, netpage); | 337 | fscache_mark_page_cached(op, netpage); |
339 | fscache_mark_pages_cached(op, pagevec); | ||
340 | 338 | ||
341 | copy_highpage(netpage, backpage); | 339 | copy_highpage(netpage, backpage); |
342 | fscache_end_io(op, netpage, 0); | 340 | fscache_end_io(op, netpage, 0); |
@@ -448,8 +446,7 @@ int cachefiles_read_or_alloc_page(struct fscache_retrieval *op, | |||
448 | &pagevec); | 446 | &pagevec); |
449 | } else if (cachefiles_has_space(cache, 0, 1) == 0) { | 447 | } else if (cachefiles_has_space(cache, 0, 1) == 0) { |
450 | /* there's space in the cache we can use */ | 448 | /* there's space in the cache we can use */ |
451 | pagevec_add(&pagevec, page); | 449 | fscache_mark_page_cached(op, page); |
452 | fscache_mark_pages_cached(op, &pagevec); | ||
453 | ret = -ENODATA; | 450 | ret = -ENODATA; |
454 | } else { | 451 | } else { |
455 | ret = -ENOBUFS; | 452 | ret = -ENOBUFS; |
@@ -465,8 +462,7 @@ int cachefiles_read_or_alloc_page(struct fscache_retrieval *op, | |||
465 | */ | 462 | */ |
466 | static int cachefiles_read_backing_file(struct cachefiles_object *object, | 463 | static int cachefiles_read_backing_file(struct cachefiles_object *object, |
467 | struct fscache_retrieval *op, | 464 | struct fscache_retrieval *op, |
468 | struct list_head *list, | 465 | struct list_head *list) |
469 | struct pagevec *mark_pvec) | ||
470 | { | 466 | { |
471 | struct cachefiles_one_read *monitor = NULL; | 467 | struct cachefiles_one_read *monitor = NULL; |
472 | struct address_space *bmapping = object->backer->d_inode->i_mapping; | 468 | struct address_space *bmapping = object->backer->d_inode->i_mapping; |
@@ -626,13 +622,13 @@ static int cachefiles_read_backing_file(struct cachefiles_object *object, | |||
626 | page_cache_release(backpage); | 622 | page_cache_release(backpage); |
627 | backpage = NULL; | 623 | backpage = NULL; |
628 | 624 | ||
629 | if (!pagevec_add(mark_pvec, netpage)) | 625 | fscache_mark_page_cached(op, netpage); |
630 | fscache_mark_pages_cached(op, mark_pvec); | ||
631 | 626 | ||
632 | page_cache_get(netpage); | 627 | page_cache_get(netpage); |
633 | if (!pagevec_add(&lru_pvec, netpage)) | 628 | if (!pagevec_add(&lru_pvec, netpage)) |
634 | __pagevec_lru_add_file(&lru_pvec); | 629 | __pagevec_lru_add_file(&lru_pvec); |
635 | 630 | ||
631 | /* the netpage is unlocked and marked up to date here */ | ||
636 | fscache_end_io(op, netpage, 0); | 632 | fscache_end_io(op, netpage, 0); |
637 | page_cache_release(netpage); | 633 | page_cache_release(netpage); |
638 | netpage = NULL; | 634 | netpage = NULL; |
@@ -775,15 +771,11 @@ int cachefiles_read_or_alloc_pages(struct fscache_retrieval *op, | |||
775 | /* submit the apparently valid pages to the backing fs to be read from | 771 | /* submit the apparently valid pages to the backing fs to be read from |
776 | * disk */ | 772 | * disk */ |
777 | if (nrbackpages > 0) { | 773 | if (nrbackpages > 0) { |
778 | ret2 = cachefiles_read_backing_file(object, op, &backpages, | 774 | ret2 = cachefiles_read_backing_file(object, op, &backpages); |
779 | &pagevec); | ||
780 | if (ret2 == -ENOMEM || ret2 == -EINTR) | 775 | if (ret2 == -ENOMEM || ret2 == -EINTR) |
781 | ret = ret2; | 776 | ret = ret2; |
782 | } | 777 | } |
783 | 778 | ||
784 | if (pagevec_count(&pagevec) > 0) | ||
785 | fscache_mark_pages_cached(op, &pagevec); | ||
786 | |||
787 | _leave(" = %d [nr=%u%s]", | 779 | _leave(" = %d [nr=%u%s]", |
788 | ret, *nr_pages, list_empty(pages) ? " empty" : ""); | 780 | ret, *nr_pages, list_empty(pages) ? " empty" : ""); |
789 | return ret; | 781 | return ret; |
@@ -806,7 +798,6 @@ int cachefiles_allocate_page(struct fscache_retrieval *op, | |||
806 | { | 798 | { |
807 | struct cachefiles_object *object; | 799 | struct cachefiles_object *object; |
808 | struct cachefiles_cache *cache; | 800 | struct cachefiles_cache *cache; |
809 | struct pagevec pagevec; | ||
810 | int ret; | 801 | int ret; |
811 | 802 | ||
812 | object = container_of(op->op.object, | 803 | object = container_of(op->op.object, |
@@ -817,13 +808,10 @@ int cachefiles_allocate_page(struct fscache_retrieval *op, | |||
817 | _enter("%p,{%lx},", object, page->index); | 808 | _enter("%p,{%lx},", object, page->index); |
818 | 809 | ||
819 | ret = cachefiles_has_space(cache, 0, 1); | 810 | ret = cachefiles_has_space(cache, 0, 1); |
820 | if (ret == 0) { | 811 | if (ret == 0) |
821 | pagevec_init(&pagevec, 0); | 812 | fscache_mark_page_cached(op, page); |
822 | pagevec_add(&pagevec, page); | 813 | else |
823 | fscache_mark_pages_cached(op, &pagevec); | ||
824 | } else { | ||
825 | ret = -ENOBUFS; | 814 | ret = -ENOBUFS; |
826 | } | ||
827 | 815 | ||
828 | _leave(" = %d", ret); | 816 | _leave(" = %d", ret); |
829 | return ret; | 817 | return ret; |
diff --git a/fs/fscache/page.c b/fs/fscache/page.c index 3f7a59bfa7ad..d7c663cfc923 100644 --- a/fs/fscache/page.c +++ b/fs/fscache/page.c | |||
@@ -915,6 +915,40 @@ done: | |||
915 | EXPORT_SYMBOL(__fscache_uncache_page); | 915 | EXPORT_SYMBOL(__fscache_uncache_page); |
916 | 916 | ||
917 | /** | 917 | /** |
918 | * fscache_mark_page_cached - Mark a page as being cached | ||
919 | * @op: The retrieval op pages are being marked for | ||
920 | * @page: The page to be marked | ||
921 | * | ||
922 | * Mark a netfs page as being cached. After this is called, the netfs | ||
923 | * must call fscache_uncache_page() to remove the mark. | ||
924 | */ | ||
925 | void fscache_mark_page_cached(struct fscache_retrieval *op, struct page *page) | ||
926 | { | ||
927 | struct fscache_cookie *cookie = op->op.object->cookie; | ||
928 | |||
929 | #ifdef CONFIG_FSCACHE_STATS | ||
930 | atomic_inc(&fscache_n_marks); | ||
931 | #endif | ||
932 | |||
933 | _debug("- mark %p{%lx}", page, page->index); | ||
934 | if (TestSetPageFsCache(page)) { | ||
935 | static bool once_only; | ||
936 | if (!once_only) { | ||
937 | once_only = true; | ||
938 | printk(KERN_WARNING "FS-Cache:" | ||
939 | " Cookie type %s marked page %lx" | ||
940 | " multiple times\n", | ||
941 | cookie->def->name, page->index); | ||
942 | } | ||
943 | } | ||
944 | |||
945 | if (cookie->def->mark_page_cached) | ||
946 | cookie->def->mark_page_cached(cookie->netfs_data, | ||
947 | op->mapping, page); | ||
948 | } | ||
949 | EXPORT_SYMBOL(fscache_mark_page_cached); | ||
950 | |||
951 | /** | ||
918 | * fscache_mark_pages_cached - Mark pages as being cached | 952 | * fscache_mark_pages_cached - Mark pages as being cached |
919 | * @op: The retrieval op pages are being marked for | 953 | * @op: The retrieval op pages are being marked for |
920 | * @pagevec: The pages to be marked | 954 | * @pagevec: The pages to be marked |
@@ -925,32 +959,11 @@ EXPORT_SYMBOL(__fscache_uncache_page); | |||
925 | void fscache_mark_pages_cached(struct fscache_retrieval *op, | 959 | void fscache_mark_pages_cached(struct fscache_retrieval *op, |
926 | struct pagevec *pagevec) | 960 | struct pagevec *pagevec) |
927 | { | 961 | { |
928 | struct fscache_cookie *cookie = op->op.object->cookie; | ||
929 | unsigned long loop; | 962 | unsigned long loop; |
930 | 963 | ||
931 | #ifdef CONFIG_FSCACHE_STATS | 964 | for (loop = 0; loop < pagevec->nr; loop++) |
932 | atomic_add(pagevec->nr, &fscache_n_marks); | 965 | fscache_mark_page_cached(op, pagevec->pages[loop]); |
933 | #endif | ||
934 | |||
935 | for (loop = 0; loop < pagevec->nr; loop++) { | ||
936 | struct page *page = pagevec->pages[loop]; | ||
937 | |||
938 | _debug("- mark %p{%lx}", page, page->index); | ||
939 | if (TestSetPageFsCache(page)) { | ||
940 | static bool once_only; | ||
941 | if (!once_only) { | ||
942 | once_only = true; | ||
943 | printk(KERN_WARNING "FS-Cache:" | ||
944 | " Cookie type %s marked page %lx" | ||
945 | " multiple times\n", | ||
946 | cookie->def->name, page->index); | ||
947 | } | ||
948 | } | ||
949 | } | ||
950 | 966 | ||
951 | if (cookie->def->mark_pages_cached) | ||
952 | cookie->def->mark_pages_cached(cookie->netfs_data, | ||
953 | op->mapping, pagevec); | ||
954 | pagevec_reinit(pagevec); | 967 | pagevec_reinit(pagevec); |
955 | } | 968 | } |
956 | EXPORT_SYMBOL(fscache_mark_pages_cached); | 969 | EXPORT_SYMBOL(fscache_mark_pages_cached); |
diff --git a/include/linux/fscache-cache.h b/include/linux/fscache-cache.h index ce31408b1e47..9879183b55d8 100644 --- a/include/linux/fscache-cache.h +++ b/include/linux/fscache-cache.h | |||
@@ -504,6 +504,9 @@ extern void fscache_withdraw_cache(struct fscache_cache *cache); | |||
504 | 504 | ||
505 | extern void fscache_io_error(struct fscache_cache *cache); | 505 | extern void fscache_io_error(struct fscache_cache *cache); |
506 | 506 | ||
507 | extern void fscache_mark_page_cached(struct fscache_retrieval *op, | ||
508 | struct page *page); | ||
509 | |||
507 | extern void fscache_mark_pages_cached(struct fscache_retrieval *op, | 510 | extern void fscache_mark_pages_cached(struct fscache_retrieval *op, |
508 | struct pagevec *pagevec); | 511 | struct pagevec *pagevec); |
509 | 512 | ||
diff --git a/include/linux/fscache.h b/include/linux/fscache.h index 9ec20dec3353..f4b6353543bf 100644 --- a/include/linux/fscache.h +++ b/include/linux/fscache.h | |||
@@ -135,14 +135,14 @@ struct fscache_cookie_def { | |||
135 | */ | 135 | */ |
136 | void (*put_context)(void *cookie_netfs_data, void *context); | 136 | void (*put_context)(void *cookie_netfs_data, void *context); |
137 | 137 | ||
138 | /* indicate pages that now have cache metadata retained | 138 | /* indicate page that now have cache metadata retained |
139 | * - this function should mark the specified pages as now being cached | 139 | * - this function should mark the specified page as now being cached |
140 | * - the pages will have been marked with PG_fscache before this is | 140 | * - the page will have been marked with PG_fscache before this is |
141 | * called, so this is optional | 141 | * called, so this is optional |
142 | */ | 142 | */ |
143 | void (*mark_pages_cached)(void *cookie_netfs_data, | 143 | void (*mark_page_cached)(void *cookie_netfs_data, |
144 | struct address_space *mapping, | 144 | struct address_space *mapping, |
145 | struct pagevec *cached_pvec); | 145 | struct page *page); |
146 | 146 | ||
147 | /* indicate the cookie is no longer cached | 147 | /* indicate the cookie is no longer cached |
148 | * - this function is called when the backing store currently caching | 148 | * - this function is called when the backing store currently caching |