mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: David Howells <dhowells@redhat.com>
To: viro@ftp.linux.org.uk, hch@infradead.org,
	Trond.Myklebust@netapp.com, sds@tycho.nsa.gov,
	casey@schaufler-ca.com
Cc: linux-kernel@vger.kernel.org, selinux@tycho.nsa.gov,
	linux-security-module@vger.kernel.org, dhowells@redhat.com
Subject: [PATCH 05/22] FS-Cache: Release page->private after failed readahead
Date: Fri, 21 Sep 2007 15:47:29 +0100	[thread overview]
Message-ID: <20070921144729.8323.28219.stgit@warthog.procyon.org.uk> (raw)
In-Reply-To: <20070921144703.8323.50492.stgit@warthog.procyon.org.uk>

The attached patch causes read_cache_pages() to release page-private data on a
page for which add_to_page_cache() fails or the filler function fails. This
permits pages with caching references associated with them to be cleaned up.

The invalidatepage() address space op is called (indirectly) to do the honours.

Signed-Off-By: David Howells <dhowells@redhat.com>
---

 mm/readahead.c |   40 ++++++++++++++++++++++++++++++++++++++--
 1 files changed, 38 insertions(+), 2 deletions(-)

diff --git a/mm/readahead.c b/mm/readahead.c
index 39bf45d..12d1378 100644
--- a/mm/readahead.c
+++ b/mm/readahead.c
@@ -15,6 +15,7 @@
 #include <linux/backing-dev.h>
 #include <linux/task_io_accounting_ops.h>
 #include <linux/pagevec.h>
+#include <linux/buffer_head.h>
 
 void default_unplug_io_fn(struct backing_dev_info *bdi, struct page *page)
 {
@@ -51,6 +52,41 @@ EXPORT_SYMBOL_GPL(file_ra_state_init);
 
 #define list_to_page(head) (list_entry((head)->prev, struct page, lru))
 
+/*
+ * see if a page needs releasing upon read_cache_pages() failure
+ * - the caller of read_cache_pages() may have set PG_private before calling,
+ *   such as the NFS fs marking pages that are cached locally on disk, thus we
+ *   need to give the fs a chance to clean up in the event of an error
+ */
+static void read_cache_pages_invalidate_page(struct address_space *mapping,
+					     struct page *page)
+{
+	if (PagePrivate(page)) {
+		if (TestSetPageLocked(page))
+			BUG();
+		page->mapping = mapping;
+		do_invalidatepage(page, 0);
+		page->mapping = NULL;
+		unlock_page(page);
+	}
+	page_cache_release(page);
+}
+
+/*
+ * release a list of pages, invalidating them first if need be
+ */
+static void read_cache_pages_invalidate_pages(struct address_space *mapping,
+					      struct list_head *pages)
+{
+	struct page *victim;
+
+	while (!list_empty(pages)) {
+		victim = list_to_page(pages);
+		list_del(&victim->lru);
+		read_cache_pages_invalidate_page(mapping, victim);
+	}
+}
+
 /**
  * read_cache_pages - populate an address space with some pages & start reads against them
  * @mapping: the address_space
@@ -74,14 +110,14 @@ int read_cache_pages(struct address_space *mapping, struct list_head *pages,
 		page = list_to_page(pages);
 		list_del(&page->lru);
 		if (add_to_page_cache(page, mapping, page->index, GFP_KERNEL)) {
-			page_cache_release(page);
+			read_cache_pages_invalidate_page(mapping, page);
 			continue;
 		}
 		ret = filler(data, page);
 		if (!pagevec_add(&lru_pvec, page))
 			__pagevec_lru_add(&lru_pvec);
 		if (ret) {
-			put_pages_list(pages);
+			read_cache_pages_invalidate_pages(mapping, pages);
 			break;
 		}
 		task_io_account_read(PAGE_CACHE_SIZE);


  parent reply	other threads:[~2007-09-21 19:51 UTC|newest]

Thread overview: 36+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-09-21 14:47 [PATCH 00/22] Introduce credential record David Howells
2007-09-21 14:47 ` [PATCH 01/22] CRED: Introduce a COW credentials record David Howells
2007-09-21 14:47 ` [PATCH 02/22] CRED: Split the task security data and move part of it into struct cred David Howells
2007-09-21 14:47 ` [PATCH 03/22] CRED: Move the effective capabilities into the cred struct David Howells
2007-09-21 14:47 ` [PATCH 04/22] CRED: Request a credential record for a kernel service David Howells
2007-09-21 14:47 ` David Howells [this message]
2007-09-21 14:47 ` [PATCH 06/22] FS-Cache: Recruit a couple of page flags for cache management David Howells
2007-09-21 14:47 ` [PATCH 07/22] FS-Cache: Provide an add_wait_queue_tail() function David Howells
2007-09-21 14:47 ` [PATCH 08/22] FS-Cache: Generic filesystem caching facility David Howells
2007-09-21 14:47 ` [PATCH 09/22] CacheFiles: Add missing copy_page export for ia64 David Howells
2007-09-21 14:47 ` [PATCH 10/22] CacheFiles: Add a hook to write a single page of data to an inode David Howells
2007-09-21 19:30   ` Trond Myklebust
2007-09-21 23:11   ` David Howells
2007-09-21 14:48 ` [PATCH 11/22] CacheFiles: Permit the page lock state to be monitored David Howells
2007-09-21 19:33   ` Trond Myklebust
2007-09-21 23:14   ` David Howells
2007-09-21 14:48 ` [PATCH 12/22] CacheFiles: Export things for CacheFiles David Howells
2007-09-21 14:48 ` [PATCH 13/22] CacheFiles: A cache that backs onto a mounted filesystem David Howells
2007-09-21 14:48 ` [PATCH 14/22] NFS: Use local caching David Howells
2007-09-21 17:00   ` Peter Staubach
2007-09-21 23:22   ` David Howells
2007-09-21 23:37   ` David Howells
2007-09-24 13:31     ` Peter Staubach
2007-09-21 14:48 ` [PATCH 15/22] NFS: Configuration and mount option changes to enable local caching on NFS David Howells
2007-09-21 14:48 ` [PATCH 16/22] NFS: Display local caching state David Howells
2007-09-21 14:48 ` [PATCH 17/22] AFS: Add TestSetPageError() David Howells
2007-09-21 14:48 ` [PATCH 18/22] AFS: Add a function to excise a rejected write from the pagecache David Howells
2007-09-21 14:48 ` [PATCH 19/22] AFS: Improve handling of a rejected writeback David Howells
2007-09-21 14:48 ` [PATCH 20/22] AFS: Implement shared-writable mmap David Howells
2007-09-21 14:48 ` [PATCH 21/22] AF_RXRPC: Save the operation ID for debugging David Howells
2007-09-21 14:48 ` [PATCH 22/22] FS-Cache: Make kAFS use FS-Cache David Howells
2007-09-21 14:58 ` [PATCH 00/22] Introduce credential record David Howells
2007-09-21 15:36 ` Casey Schaufler
2007-09-21 15:40   ` David Howells
2007-09-21 16:04     ` Casey Schaufler
2007-09-21 23:18       ` David Howells

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20070921144729.8323.28219.stgit@warthog.procyon.org.uk \
    --to=dhowells@redhat.com \
    --cc=Trond.Myklebust@netapp.com \
    --cc=casey@schaufler-ca.com \
    --cc=hch@infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-security-module@vger.kernel.org \
    --cc=sds@tycho.nsa.gov \
    --cc=selinux@tycho.nsa.gov \
    --cc=viro@ftp.linux.org.uk \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

Powered by JetHome