mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Hugh Dickins <hugh@veritas.com>
To: Andrew Morton <akpm@linux-foundation.org>
Cc: Christoph Rohland <hans-christoph.rohland@sap.com>,
	Erez Zadok <ezk@cs.sunysb.edu>,
	linux-kernel@vger.kernel.org
Subject: [PATCH 5/9] tmpfs: allocate on read when stacked
Date: Tue, 18 Dec 2007 22:02:13 +0000 (GMT)	[thread overview]
Message-ID: <Pine.LNX.4.64.0712182201290.27165@blonde.wat.veritas.com> (raw)
In-Reply-To: <Pine.LNX.4.64.0712182144370.26235@blonde.wat.veritas.com>

tmpfs is expected to limit the memory used (unless mounted with nr_blocks=0
or size=0).  But if a stacked filesystem such as unionfs gets pages from a
sparse tmpfs file by reading holes, and then writes to them, it can easily
exceed any such limit at present.

So suppress the SGP_READ "don't allocate page" ZERO_PAGE optimization when
reading for the kernel (a KERNEL_DS check, ugh, sorry about that).  Indeed,
pessimistically mark such pages as dirty, so they cannot get reclaimed and
unaccounted by mistake.  The venerable shmem_recalc_inode code (originally
to account for the reclaim of clean pages) suffices to get the accounting
right when swappages are dropped in favour of more uptodate filepages.

This also fixes the NULL shmem_swp_entry BUG or oops in shmem_writepage,
caused by unionfs writing to a very sparse tmpfs file: to minimize memory
allocation in swapout, tmpfs requires the swap vector be allocated upfront,
which wasn't always happening in this stacked case.

Signed-off-by: Hugh Dickins <hugh@veritas.com>
---

 mm/shmem.c |   14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

--- tmpfs4/mm/shmem.c	2007-12-05 16:42:19.000000000 +0000
+++ tmpfs5/mm/shmem.c	2007-12-05 16:42:19.000000000 +0000
@@ -80,6 +80,7 @@
 enum sgp_type {
 	SGP_READ,	/* don't exceed i_size, don't allocate page */
 	SGP_CACHE,	/* don't exceed i_size, may allocate page */
+	SGP_DIRTY,	/* like SGP_CACHE, but set new page dirty */
 	SGP_WRITE,	/* may exceed i_size, may allocate page */
 };
 
@@ -1333,6 +1334,8 @@ repeat:
 		clear_highpage(filepage);
 		flush_dcache_page(filepage);
 		SetPageUptodate(filepage);
+		if (sgp == SGP_DIRTY)
+			set_page_dirty(filepage);
 	}
 done:
 	*pagep = filepage;
@@ -1518,6 +1521,15 @@ static void do_shmem_file_read(struct fi
 	struct inode *inode = filp->f_path.dentry->d_inode;
 	struct address_space *mapping = inode->i_mapping;
 	unsigned long index, offset;
+	enum sgp_type sgp = SGP_READ;
+
+	/*
+	 * Might this read be for a stacking filesystem?  Then when reading
+	 * holes of a sparse file, we actually need to allocate those pages,
+	 * and even mark them dirty, so it cannot exceed the max_blocks limit.
+	 */
+	if (segment_eq(get_fs(), KERNEL_DS))
+		sgp = SGP_DIRTY;
 
 	index = *ppos >> PAGE_CACHE_SHIFT;
 	offset = *ppos & ~PAGE_CACHE_MASK;
@@ -1536,7 +1548,7 @@ static void do_shmem_file_read(struct fi
 				break;
 		}
 
-		desc->error = shmem_getpage(inode, index, &page, SGP_READ, NULL);
+		desc->error = shmem_getpage(inode, index, &page, sgp, NULL);
 		if (desc->error) {
 			if (desc->error == -EINVAL)
 				desc->error = 0;

  parent reply	other threads:[~2007-12-18 22:03 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-12-18 21:55 [PATCH 0/9] tmpfs: towards unionfs and memcgroups Hugh Dickins
2007-12-18 21:57 ` [PATCH 1/9] tmpfs: move swap_state stats update Hugh Dickins
2007-12-18 21:59 ` [PATCH 2/9] tmpfs: shuffle add_to_swap_caches Hugh Dickins
2007-12-19  1:55   ` Nick Piggin
2007-12-18 22:00 ` [PATCH 3/9] tmpfs: move swap swizzling into shmem Hugh Dickins
2007-12-18 22:01 ` [PATCH 4/9] tmpfs: allow filepage alongside swappage Hugh Dickins
2007-12-18 22:51   ` Erez Zadok
2007-12-19  0:30     ` Hugh Dickins
2007-12-18 22:02 ` Hugh Dickins [this message]
2007-12-18 22:03 ` [PATCH 6/9] tmpfs: make shmem_unuse more preemptible Hugh Dickins
2007-12-18 22:04 ` [PATCH 7/9] tmpfs: open a window in shmem_unuse_inode Hugh Dickins
2007-12-18 22:05 ` [PATCH 8/9] tmpfs: radix_tree_preloading Hugh Dickins
2007-12-19  6:50   ` Nick Piggin
2007-12-18 22:06 ` [PATCH 9/9] tmpfs: fix shmem_swaplist races Hugh Dickins

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=Pine.LNX.4.64.0712182201290.27165@blonde.wat.veritas.com \
    --to=hugh@veritas.com \
    --cc=akpm@linux-foundation.org \
    --cc=ezk@cs.sunysb.edu \
    --cc=hans-christoph.rohland@sap.com \
    --cc=linux-kernel@vger.kernel.org \
    /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

all inboxes | Powered by JetHome®