Can you try this patch instead? David --- From: David Howells <dhowells@xxxxxxxxxx> Subject: [PATCH] FS-Cache: Debug the Bad Page state --- fs/cachefiles/rdwr.c | 20 ++++++++++---------- fs/fscache/page.c | 19 ++++++++++++++++++- include/linux/fscache-cache.h | 3 ++- 3 files changed, 30 insertions(+), 12 deletions(-) diff --git a/fs/cachefiles/rdwr.c b/fs/cachefiles/rdwr.c index 0f0d41f..acff835 100644 --- a/fs/cachefiles/rdwr.c +++ b/fs/cachefiles/rdwr.c @@ -178,7 +178,7 @@ static void cachefiles_read_copier(struct fscache_operation *_op) copy_highpage(monitor->netfs_page, monitor->back_page); pagevec_add(&pagevec, monitor->netfs_page); - fscache_mark_pages_cached(monitor->op, &pagevec); + fscache_mark_pages_cached(monitor->op, &pagevec, true); error = 0; } else if (!PageError(monitor->back_page)) { /* the page has probably been truncated */ @@ -336,7 +336,7 @@ backing_page_already_uptodate: _debug("- uptodate"); pagevec_add(pagevec, netpage); - fscache_mark_pages_cached(op, pagevec); + fscache_mark_pages_cached(op, pagevec, true); copy_highpage(netpage, backpage); fscache_end_io(op, netpage, 0); @@ -449,7 +449,7 @@ int cachefiles_read_or_alloc_page(struct fscache_retrieval *op, } else if (cachefiles_has_space(cache, 0, 1) == 0) { /* there's space in the cache we can use */ pagevec_add(&pagevec, page); - fscache_mark_pages_cached(op, &pagevec); + fscache_mark_pages_cached(op, &pagevec, true); ret = -ENODATA; } else { ret = -ENOBUFS; @@ -627,7 +627,7 @@ static int cachefiles_read_backing_file(struct cachefiles_object *object, backpage = NULL; if (!pagevec_add(mark_pvec, netpage)) - fscache_mark_pages_cached(op, mark_pvec); + fscache_mark_pages_cached(op, mark_pvec, true); page_cache_get(netpage); if (!pagevec_add(&lru_pvec, netpage)) @@ -761,13 +761,13 @@ int cachefiles_read_or_alloc_pages(struct fscache_retrieval *op, (*nr_pages)--; nrbackpages++; } else if (space && pagevec_add(&pagevec, page) == 0) { - fscache_mark_pages_cached(op, &pagevec); + fscache_mark_pages_cached(op, &pagevec, false); ret = -ENODATA; } } if (pagevec_count(&pagevec) > 0) - fscache_mark_pages_cached(op, &pagevec); + fscache_mark_pages_cached(op, &pagevec, false); if (list_empty(pages)) ret = 0; @@ -782,7 +782,7 @@ int cachefiles_read_or_alloc_pages(struct fscache_retrieval *op, } if (pagevec_count(&pagevec) > 0) - fscache_mark_pages_cached(op, &pagevec); + fscache_mark_pages_cached(op, &pagevec, true); _leave(" = %d [nr=%u%s]", ret, *nr_pages, list_empty(pages) ? " empty" : ""); @@ -820,7 +820,7 @@ int cachefiles_allocate_page(struct fscache_retrieval *op, if (ret == 0) { pagevec_init(&pagevec, 0); pagevec_add(&pagevec, page); - fscache_mark_pages_cached(op, &pagevec); + fscache_mark_pages_cached(op, &pagevec, false); } else { ret = -ENOBUFS; } @@ -864,11 +864,11 @@ int cachefiles_allocate_pages(struct fscache_retrieval *op, list_for_each_entry(page, pages, lru) { if (pagevec_add(&pagevec, page) == 0) - fscache_mark_pages_cached(op, &pagevec); + fscache_mark_pages_cached(op, &pagevec, false); } if (pagevec_count(&pagevec) > 0) - fscache_mark_pages_cached(op, &pagevec); + fscache_mark_pages_cached(op, &pagevec, false); ret = -ENODATA; } else { ret = -ENOBUFS; diff --git a/fs/fscache/page.c b/fs/fscache/page.c index 47aefd3..9461617 100644 --- a/fs/fscache/page.c +++ b/fs/fscache/page.c @@ -955,12 +955,14 @@ EXPORT_SYMBOL(__fscache_uncache_page); * fscache_mark_pages_cached - Mark pages as being cached * @op: The retrieval op pages are being marked for * @pagevec: The pages to be marked + * @should_have_mapping: True if the pages should have a mapping set * * Mark a bunch of netfs pages as being cached. After this is called, * the netfs must call fscache_uncache_page() to remove the mark. */ void fscache_mark_pages_cached(struct fscache_retrieval *op, - struct pagevec *pagevec) + struct pagevec *pagevec, + bool should_have_mapping) { struct fscache_cookie *cookie = op->op.object->cookie; unsigned long loop; @@ -983,6 +985,21 @@ void fscache_mark_pages_cached(struct fscache_retrieval *op, cookie->def->name, page->index); } } + if ((should_have_mapping && !page->mapping) || + (!should_have_mapping && page->mapping)) { + static bool once_only; + if (once_only) + goto skip; + once_only = 1; + printk(KERN_ALERT + "page:%p count:%d mapcount:%d mapping:%p index:%#lx\n", + page, page_count(page), page_mapcount(page), + page->mapping, page->index); + WARN_ON(1); + skip: + ; + } + } if (cookie->def->mark_pages_cached) diff --git a/include/linux/fscache-cache.h b/include/linux/fscache-cache.h index c57db27..762b3f7 100644 --- a/include/linux/fscache-cache.h +++ b/include/linux/fscache-cache.h @@ -532,7 +532,8 @@ extern void fscache_withdraw_cache(struct fscache_cache *cache); extern void fscache_io_error(struct fscache_cache *cache); extern void fscache_mark_pages_cached(struct fscache_retrieval *op, - struct pagevec *pagevec); + struct pagevec *pagevec, + bool should_have_mapping); extern enum fscache_checkaux fscache_check_aux(struct fscache_object *object, const void *data, -- Linux-cachefs mailing list Linux-cachefs@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/linux-cachefs