[JFFS2] Reduce excessive node count for syslog files.

Linux-MTD Mailing List linux-mtd at lists.infradead.org
Sat May 13 23:12:04 EDT 2006


Commit:     cf5eba53346fbfdf1b80e05ca3fd7fe2ec841077
Parent:     151e76590f66f5406eb2e1f4270c5323f385d2e8
Author:     David Woodhouse <dwmw2 at infradead.org>
AuthorDate: Sun May 14 04:06:24 2006 +0100
Commit:     David Woodhouse <dwmw2 at infradead.org>
CommitDate: Sun May 14 04:06:24 2006 +0100

    [JFFS2] Reduce excessive node count for syslog files.
    
    We currently get fairly poor behaviour with files which get many short
    writes, such as system logs. This is because we end up with many tiny
    data nodes, and the rbtree gets massive. None of these nodes are
    actually obsolete, so they are counted as 'clean' space. Eraseblocks can
    be entirely full of these nodes (which are REF_NORMAL instead of
    REF_PRISTINE), and still they count entirely towards 'used_size' and the
    eraseblocks can sit on the clean_list for a long time without being
    picked for GC.
    
    One way to alleviate this in the long term is to account REF_NORMAL
    space separately from REF_PRISTINE space, rather than counting them both
    towards used_size. Then these eraseblocks can be picked for GC and the
    offending nodes will be garbage collected.
    
    The short-term fix, though -- which probably makes sense even if we do
    eventually implement the above -- is to merge these nodes as they're
    written. When we write the last byte in a page, write the _whole_ page.
    This obsoletes the earlier nodes in the page _immediately_ and we don't
    even need to wait for the garbage collection to do it.
    
    Original implementation from Ferenc Havasi <havasi at inf.u-szeged.hu>
    Signed-off-by: David Woodhouse <dwmw2 at infradead.org>

 fs/jffs2/file.c |   20 ++++++++++++++------
 1 files changed, 14 insertions(+), 6 deletions(-)

diff --git a/fs/jffs2/file.c b/fs/jffs2/file.c
index 9f41712..3349db0 100644
--- a/fs/jffs2/file.c
+++ b/fs/jffs2/file.c
@@ -215,12 +215,20 @@ static int jffs2_commit_write (struct fi
 	D1(printk(KERN_DEBUG "jffs2_commit_write(): ino #%lu, page at 0x%lx, range %d-%d, flags %lx\n",
 		  inode->i_ino, pg->index << PAGE_CACHE_SHIFT, start, end, pg->flags));
 
-	if (!start && end == PAGE_CACHE_SIZE) {
-		/* We need to avoid deadlock with page_cache_read() in
-		   jffs2_garbage_collect_pass(). So we have to mark the
-		   page up to date, to prevent page_cache_read() from
-		   trying to re-lock it. */
-		SetPageUptodate(pg);
+	if (end == PAGE_CACHE_SIZE) {
+		if (!start) {
+			/* We need to avoid deadlock with page_cache_read() in
+			   jffs2_garbage_collect_pass(). So we have to mark the
+			   page up to date, to prevent page_cache_read() from
+			   trying to re-lock it. */
+			SetPageUptodate(pg);
+		} else {
+			/* When writing out the end of a page, write out the 
+			   _whole_ page. This helps to reduce the number of
+			   nodes in files which have many short writes, like
+			   syslog files. */
+			start = aligned_start = 0;
+		}
 	}
 
 	ri = jffs2_alloc_raw_inode();




More information about the linux-mtd-cvs mailing list