Commit 31fbdf7a authored by Artem B. Bityuckiy's avatar Artem B. Bityuckiy Committed by Thomas Gleixner

[JFFS2] Fix NOR specific scan BUG

Fix fairly sad NOR-specific bug - during FS building ic->scan_dents
isn't zero, but jffs2_mark_node_obsolete() migt be called it tries to
finde the ic corresponding to ref - this requires ic->scan_dents = 0.
Signed-off-by: default avatarArtem B. Bityuckiy <dedekind@infradead.org>
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
parent 67e345d1
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* For licensing information, see the file 'LICENCE' in this directory. * For licensing information, see the file 'LICENCE' in this directory.
* *
* $Id: build.c,v 1.69 2004/12/16 20:22:18 dmarlin Exp $ * $Id: build.c,v 1.70 2005/02/28 08:21:05 dedekind Exp $
* *
*/ */
...@@ -97,14 +97,16 @@ static int jffs2_build_filesystem(struct jffs2_sb_info *c) ...@@ -97,14 +97,16 @@ static int jffs2_build_filesystem(struct jffs2_sb_info *c)
/* First, scan the medium and build all the inode caches with /* First, scan the medium and build all the inode caches with
lists of physical nodes */ lists of physical nodes */
c->flags |= JFFS2_SB_FLAG_MOUNTING; c->flags |= JFFS2_SB_FLAG_SCANNING;
ret = jffs2_scan_medium(c); ret = jffs2_scan_medium(c);
c->flags &= ~JFFS2_SB_FLAG_SCANNING;
if (ret) if (ret)
goto exit; goto exit;
D1(printk(KERN_DEBUG "Scanned flash completely\n")); D1(printk(KERN_DEBUG "Scanned flash completely\n"));
D2(jffs2_dump_block_lists(c)); D2(jffs2_dump_block_lists(c));
c->flags |= JFFS2_SB_FLAG_BUILDING;
/* Now scan the directory tree, increasing nlink according to every dirent found. */ /* Now scan the directory tree, increasing nlink according to every dirent found. */
for_each_inode(i, c, ic) { for_each_inode(i, c, ic) {
D1(printk(KERN_DEBUG "Pass 1: ino #%u\n", ic->ino)); D1(printk(KERN_DEBUG "Pass 1: ino #%u\n", ic->ino));
...@@ -116,7 +118,6 @@ static int jffs2_build_filesystem(struct jffs2_sb_info *c) ...@@ -116,7 +118,6 @@ static int jffs2_build_filesystem(struct jffs2_sb_info *c)
cond_resched(); cond_resched();
} }
} }
c->flags &= ~JFFS2_SB_FLAG_MOUNTING;
D1(printk(KERN_DEBUG "Pass 1 complete\n")); D1(printk(KERN_DEBUG "Pass 1 complete\n"));
...@@ -164,6 +165,8 @@ static int jffs2_build_filesystem(struct jffs2_sb_info *c) ...@@ -164,6 +165,8 @@ static int jffs2_build_filesystem(struct jffs2_sb_info *c)
ic->scan_dents = NULL; ic->scan_dents = NULL;
cond_resched(); cond_resched();
} }
c->flags &= ~JFFS2_SB_FLAG_BUILDING;
D1(printk(KERN_DEBUG "Pass 3 complete\n")); D1(printk(KERN_DEBUG "Pass 3 complete\n"));
D2(jffs2_dump_block_lists(c)); D2(jffs2_dump_block_lists(c));
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* For licensing information, see the file 'LICENCE' in this directory. * For licensing information, see the file 'LICENCE' in this directory.
* *
* $Id: nodemgmt.c,v 1.118 2005/02/27 23:01:32 dwmw2 Exp $ * $Id: nodemgmt.c,v 1.119 2005/02/28 08:21:05 dedekind Exp $
* *
*/ */
...@@ -403,7 +403,7 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref ...@@ -403,7 +403,7 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
jeb = &c->blocks[blocknr]; jeb = &c->blocks[blocknr];
if (jffs2_can_mark_obsolete(c) && !jffs2_is_readonly(c) && if (jffs2_can_mark_obsolete(c) && !jffs2_is_readonly(c) &&
!(c->flags & JFFS2_SB_FLAG_MOUNTING)) { !(c->flags & (JFFS2_SB_FLAG_SCANNING | JFFS2_SB_FLAG_BUILDING))) {
/* Hm. This may confuse static lock analysis. If any of the above /* Hm. This may confuse static lock analysis. If any of the above
three conditions is false, we're going to return from this three conditions is false, we're going to return from this
function without actually obliterating any nodes or freeing function without actually obliterating any nodes or freeing
...@@ -470,8 +470,8 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref ...@@ -470,8 +470,8 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
D1(ACCT_PARANOIA_CHECK(jeb)); D1(ACCT_PARANOIA_CHECK(jeb));
if (c->flags & JFFS2_SB_FLAG_MOUNTING) { if (c->flags & JFFS2_SB_FLAG_SCANNING) {
/* Mount in progress. Don't muck about with the block /* Flash scanning is in progress. Don't muck about with the block
lists because they're not ready yet, and don't actually lists because they're not ready yet, and don't actually
obliterate nodes that look obsolete. If they weren't obliterate nodes that look obsolete. If they weren't
marked obsolete on the flash at the time they _became_ marked obsolete on the flash at the time they _became_
...@@ -530,7 +530,8 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref ...@@ -530,7 +530,8 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
spin_unlock(&c->erase_completion_lock); spin_unlock(&c->erase_completion_lock);
if (!jffs2_can_mark_obsolete(c) || jffs2_is_readonly(c)) { if (!jffs2_can_mark_obsolete(c) || jffs2_is_readonly(c) ||
(c->flags & JFFS2_SB_FLAG_BUILDING)) {
/* We didn't lock the erase_free_sem */ /* We didn't lock the erase_free_sem */
return; return;
} }
......
/* $Id: jffs2_fs_sb.h,v 1.50 2005/02/09 09:23:55 pavlov Exp $ */ /* $Id: jffs2_fs_sb.h,v 1.51 2005/02/28 08:21:06 dedekind Exp $ */
#ifndef _JFFS2_FS_SB #ifndef _JFFS2_FS_SB
#define _JFFS2_FS_SB #define _JFFS2_FS_SB
...@@ -14,7 +14,8 @@ ...@@ -14,7 +14,8 @@
#include <linux/rwsem.h> #include <linux/rwsem.h>
#define JFFS2_SB_FLAG_RO 1 #define JFFS2_SB_FLAG_RO 1
#define JFFS2_SB_FLAG_MOUNTING 2 #define JFFS2_SB_FLAG_SCANNING 2 /* Flash scanning is in progress */
#define JFFS2_SB_FLAG_BUILDING 4 /* File system building is in progress */
struct jffs2_inodirty; struct jffs2_inodirty;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment