[JFFS2] Locking issues in summary write code.

Linux-MTD Mailing List linux-mtd at lists.infradead.org
Sun May 21 14:59:14 EDT 2006


Commit:     010b06d6d07d9fa5ea6070aa72bb3e0de1761ab7
Parent:     9167e0f811cbe28564c44a99c2f07b0ce5b368cf
Author:     David Woodhouse <dwmw2 at infradead.org>
AuthorDate: Sun May 21 13:15:59 2006 +0100
Commit:     David Woodhouse <dwmw2 at infradead.org>
CommitDate: Sun May 21 13:15:59 2006 +0100

    [JFFS2] Locking issues in summary write code.
    
    We can't use jffs2_scan_dirty_space() because it doesn't do any locking; it's
    only for use at scan time -- hence the 'scan' in the name.
    
    Also, don't allocate refs while we have c->erase_completion_lock held.
    
    Signed-off-by: David Woodhouse <dwmw2 at infradead.org>

 fs/jffs2/summary.c |   21 +++++++++++++++++----
 1 files changed, 17 insertions(+), 4 deletions(-)

diff --git a/fs/jffs2/summary.c b/fs/jffs2/summary.c
index 5a59c61..1451732 100644
--- a/fs/jffs2/summary.c
+++ b/fs/jffs2/summary.c
@@ -835,19 +835,32 @@ #endif
 	spin_unlock(&c->erase_completion_lock);
 	ret = jffs2_flash_writev(c, vecs, 2, jeb->offset + c->sector_size -
 				jeb->free_size, &retlen, 0);
-	spin_lock(&c->erase_completion_lock);
-
 
 	if (ret || (retlen != infosize)) {
+		struct jffs2_raw_node_ref *ref;
+
 		JFFS2_WARNING("Write of %u bytes at 0x%08x failed. returned %d, retlen %zd\n",
 			infosize, jeb->offset + c->sector_size - jeb->free_size, ret, retlen);
 
+		/* Waste remaining space */
+		ref = jffs2_alloc_raw_node_ref();
+		if (ref) {
+			spin_lock(&c->erase_completion_lock);
+
+			ref->flash_offset = jeb->offset + c->sector_size - jeb->free_size;
+			ref->flash_offset |= REF_OBSOLETE;
+			ref->next_in_ino = 0;
+
+			jffs2_link_node_ref(c, jeb, ref, c->sector_size - jeb->free_size);
+		}
+
 		c->summary->sum_size = JFFS2_SUMMARY_NOSUM_SIZE;
-		jffs2_scan_dirty_space(c, jeb, infosize);
 
 		return 1;
 	}
 
+	spin_lock(&c->erase_completion_lock);
+
 	return 0;
 }
 
@@ -890,7 +903,6 @@ int jffs2_sum_write_sumnode(struct jffs2
 	/* for ACCT_PARANOIA_CHECK */
 	spin_unlock(&c->erase_completion_lock);
 	summary_ref = jffs2_alloc_raw_node_ref();
-	spin_lock(&c->erase_completion_lock);
 
 	if (!summary_ref) {
 		JFFS2_NOTICE("Failed to allocate node ref for summary\n");
@@ -900,6 +912,7 @@ int jffs2_sum_write_sumnode(struct jffs2
 	summary_ref->next_in_ino = NULL;
 	summary_ref->flash_offset = (jeb->offset + c->sector_size - jeb->free_size) | REF_NORMAL;
 
+	spin_lock(&c->erase_completion_lock);
 	jffs2_link_node_ref(c, jeb, summary_ref, infosize);
 
 	return 0;



More information about the linux-mtd-cvs mailing list