public inbox for linux-mtd@lists.infradead.org
 help / color / mirror / Atom feed
From: David Woodhouse <dwmw2@infradead.org>
To: dedekind@infradead.org
Cc: David Brownell <david-b@pacbell.net>,
	linux-mtd@lists.infradead.org, trimarchimichael@yahoo.it,
	jwboyer@gmail.com, akpm@linux-foundation.org,
	rmk@arm.linux.org.uk
Subject: Re: [patch 02/13] jffs2 summary allocation: don't use vmalloc()
Date: Thu, 31 Jul 2008 09:48:15 +0100	[thread overview]
Message-ID: <1217494095.3454.55.camel@pmac.infradead.org> (raw)
In-Reply-To: <1217491258.9432.20.camel@sauron>

On Thu, 2008-07-31 at 11:00 +0300, Artem Bityutskiy wrote:
> I've just glanced to JFFS2, and this sum_buf does not have to be of
> eraseblock size. It should be something like a couple of NAND pages in
> size, or, say, 5-10% of eraseblock size. So I would say, in this
> particular case JFFS2 may be fixed an kmalloc() may be used.

That's a reasonable answer in the short term; good idea. And we don't
have to worry too much about proving a lower bound on the size we'll
want to use for the summary -- because the summary is optional, it's OK
just to abort it if it would have overflowed our truncated buffer. 

Something like this should do the trick...

diff --git a/fs/jffs2/summary.c b/fs/jffs2/summary.c
index 629af01..6caf1e1 100644
--- a/fs/jffs2/summary.c
+++ b/fs/jffs2/summary.c
@@ -23,6 +23,8 @@
 
 int jffs2_sum_init(struct jffs2_sb_info *c)
 {
+	uint32_t sum_size = max_t(uint32_t, c->sector_size, MAX_SUMMARY_SIZE);
+
 	c->summary = kzalloc(sizeof(struct jffs2_summary), GFP_KERNEL);
 
 	if (!c->summary) {
@@ -30,7 +32,7 @@ int jffs2_sum_init(struct jffs2_sb_info *c)
 		return -ENOMEM;
 	}
 
-	c->summary->sum_buf = vmalloc(c->sector_size);
+	c->summary->sum_buf = kmalloc(sum_size, GFP_KERNEL);
 
 	if (!c->summary->sum_buf) {
 		JFFS2_WARNING("Can't allocate buffer for writing out summary information!\n");
@@ -49,7 +51,7 @@ void jffs2_sum_exit(struct jffs2_sb_info *c)
 
 	jffs2_sum_disable_collecting(c->summary);
 
-	vfree(c->summary->sum_buf);
+	kfree(c->summary->sum_buf);
 	c->summary->sum_buf = NULL;
 
 	kfree(c->summary);
@@ -665,7 +667,7 @@ crc_err:
 /* Write summary data to flash - helper function for jffs2_sum_write_sumnode() */
 
 static int jffs2_sum_write_data(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
-					uint32_t infosize, uint32_t datasize, int padsize)
+				uint32_t infosize, uint32_t datasize, int padsize)
 {
 	struct jffs2_raw_summary isum;
 	union jffs2_sum_mem *temp;
@@ -676,6 +678,26 @@ static int jffs2_sum_write_data(struct jffs2_sb_info *c, struct jffs2_eraseblock
 	int ret;
 	size_t retlen;
 
+	if (padsize + datasize > MAX_SUMMARY_SIZE) {
+		/* It won't fit in the buffer. Abort summary for this jeb */
+		jffs2_sum_disable_collecting(c->summary);
+
+		JFFS2_WARNING("Summary too big (%d data, %d pad) in eraseblock at %08x\n",
+			      datasize, padsize, jeb->offset);
+		/* Non-fatal */
+		return 0;
+	}
+	/* Is there enough space for summary? */
+	if (padsize < 0) {
+		/* don't try to write out summary for this jeb */
+		jffs2_sum_disable_collecting(c->summary);
+
+		JFFS2_WARNING("Not enough space for summary, padsize = %d\n",
+			      padsize);
+		/* Non-fatal */
+		return 0;
+	}
+
 	memset(c->summary->sum_buf, 0xff, datasize);
 	memset(&isum, 0, sizeof(isum));
 
@@ -821,7 +843,7 @@ int jffs2_sum_write_sumnode(struct jffs2_sb_info *c)
 {
 	int datasize, infosize, padsize;
 	struct jffs2_eraseblock *jeb;
-	int ret;
+	int ret = 0;
 
 	dbg_summary("called\n");
 
@@ -841,16 +863,6 @@ int jffs2_sum_write_sumnode(struct jffs2_sb_info *c)
 	infosize += padsize;
 	datasize += padsize;
 
-	/* Is there enough space for summary? */
-	if (padsize < 0) {
-		/* don't try to write out summary for this jeb */
-		jffs2_sum_disable_collecting(c->summary);
-
-		JFFS2_WARNING("Not enough space for summary, padsize = %d\n", padsize);
-		spin_lock(&c->erase_completion_lock);
-		return 0;
-	}
-
 	ret = jffs2_sum_write_data(c, jeb, infosize, datasize, padsize);
 	spin_lock(&c->erase_completion_lock);
 	return ret;
diff --git a/fs/jffs2/summary.h b/fs/jffs2/summary.h
index 8bf34f2..60207a2 100644
--- a/fs/jffs2/summary.h
+++ b/fs/jffs2/summary.h
@@ -13,6 +13,12 @@
 #ifndef JFFS2_SUMMARY_H
 #define JFFS2_SUMMARY_H
 
+/* Limit summary size to 64KiB so that we can kmalloc it. If the summary
+   is larger than that, we have to just ditch it and avoid using summary
+   for the eraseblock in question... and it probably doesn't hurt us much
+   anyway. */
+#define MAX_SUMMARY_SIZE 65536
+
 #include <linux/uio.h>
 #include <linux/jffs2.h>
 



-- 
dwmw2

  reply	other threads:[~2008-07-31  8:48 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-07-30 19:34 [patch 02/13] jffs2 summary allocation: don't use vmalloc() akpm
2008-07-30 22:39 ` David Brownell
2008-07-30 22:46   ` Andrew Morton
2008-07-31  5:10     ` David Brownell
2008-07-31  5:37       ` Artem Bityutskiy
2008-07-31  6:57         ` David Brownell
2008-07-31  8:03           ` Artem Bityutskiy
2008-07-31  5:15   ` Artem Bityutskiy
2008-07-31  6:56     ` David Brownell
2008-07-31  8:00       ` Artem Bityutskiy
2008-07-31  8:48         ` David Woodhouse [this message]
2008-07-31  9:09           ` David Woodhouse
2008-07-31  7:33   ` David Woodhouse
2008-07-31  8:21     ` David Brownell

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=1217494095.3454.55.camel@pmac.infradead.org \
    --to=dwmw2@infradead.org \
    --cc=akpm@linux-foundation.org \
    --cc=david-b@pacbell.net \
    --cc=dedekind@infradead.org \
    --cc=jwboyer@gmail.com \
    --cc=linux-mtd@lists.infradead.org \
    --cc=rmk@arm.linux.org.uk \
    --cc=trimarchimichael@yahoo.it \
    /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