public inbox for linux-mtd@lists.infradead.org
 help / color / mirror / Atom feed
From: "Artem B. Bityuckiy" <abityuckiy@yandex.ru>
To: Estelle HAMMACHE <estelle.hammache@st.com>
Cc: linux-mtd@lists.infradead.org, David Woodhouse <dwmw2@infradead.org>
Subject: Re: JFFS2 & SMP
Date: Wed, 03 Nov 2004 19:39:35 +0300	[thread overview]
Message-ID: <418909C7.3040508@yandex.ru> (raw)
In-Reply-To: <41879A58.F960F963@st.com>

[-- Attachment #1: Type: text/plain, Size: 161 bytes --]

Sorry, the patch was made not very accurately and will not easily 
applied, please, use this one.

-- 
Best Regards,
Artem B. Bityuckiy,
St.-Petersburg, Russia.

[-- Attachment #2: preempt-patch.diff --]
[-- Type: text/x-patch, Size: 6480 bytes --]

diff -auNr mtd-snapshot-20041008/fs/jffs2/build.c mtd-preepmpt-fix/fs/jffs2/build.c
--- mtd-snapshot-20041008/fs/jffs2/build.c	2003-10-29 02:00:34.000000000 +0300
+++ mtd-preepmpt-fix/fs/jffs2/build.c	2004-11-03 19:20:49.769732102 +0300
@@ -314,6 +314,7 @@
 
 	init_MUTEX(&c->alloc_sem);
 	init_MUTEX(&c->erase_free_sem);
+	init_rwsem(&c->wbuf_sem);
 	init_waitqueue_head(&c->erase_wait);
 	init_waitqueue_head(&c->inocache_wq);
 	spin_lock_init(&c->erase_completion_lock);
diff -auNr mtd-snapshot-20041008/fs/jffs2/wbuf.c mtd-preepmpt-fix/fs/jffs2/wbuf.c
--- mtd-snapshot-20041008/fs/jffs2/wbuf.c	2004-09-12 02:00:12.000000000 +0400
+++ mtd-preepmpt-fix/fs/jffs2/wbuf.c	2004-11-03 19:20:49.761733507 +0300
@@ -392,7 +392,7 @@
    1: Pad, do not adjust nextblock free_size
    2: Pad, adjust nextblock free_size
 */
-static int __jffs2_flush_wbuf(struct jffs2_sb_info *c, int pad)
+static int __jffs2_flush_wbuf(struct jffs2_sb_info *c, int pad, int alloc_wbuf_sem)
 {
 	int ret;
 	size_t retlen;
@@ -408,8 +408,11 @@
 		BUG();
 	}
 
+	if (alloc_wbuf_sem)
+		down_write(&c->wbuf_sem);
+
 	if(!c->wbuf || !c->wbuf_len)
-		return 0;
+		goto exit;
 
 	/* claim remaining space on the page
 	   this happens, if we have a change to a new block,
@@ -458,7 +461,7 @@
 
 		jffs2_wbuf_recover(c);
 
-		return ret; 
+		goto exit;
 	}
 
 	spin_lock(&c->erase_completion_lock);
@@ -497,6 +500,9 @@
 	/* adjust write buffer offset, else we get a non contiguous write bug */
 	c->wbuf_ofs += c->wbuf_pagesize;
 	c->wbuf_len = 0;
+exit:
+	if (alloc_wbuf_sem)
+		up_write(&c->wbuf_sem);
 	return 0;
 }
 
@@ -525,7 +531,7 @@
 	if (c->unchecked_size) {
 		/* GC won't make any progress for a while */
 		D1(printk(KERN_DEBUG "jffs2_flush_wbuf_gc() padding. Not finished checking\n"));
-		ret = __jffs2_flush_wbuf(c, 2);
+		ret = __jffs2_flush_wbuf(c, 2, 1);
 	} else while (old_wbuf_len &&
 		      old_wbuf_ofs == c->wbuf_ofs) {
 
@@ -537,7 +543,7 @@
 		if (ret) {
 			/* GC failed. Flush it with padding instead */
 			down(&c->alloc_sem);
-			ret = __jffs2_flush_wbuf(c, 2);
+			ret = __jffs2_flush_wbuf(c, 2, 1);
 			break;
 		}
 		down(&c->alloc_sem);
@@ -552,10 +558,9 @@
 /* Pad write-buffer to end and write it, wasting space. */
 int jffs2_flush_wbuf_pad(struct jffs2_sb_info *c)
 {
-	return __jffs2_flush_wbuf(c, 1);
+	return __jffs2_flush_wbuf(c, 1, 1);
 }
 
-
 #define PAGE_DIV(x) ( (x) & (~(c->wbuf_pagesize - 1)) )
 #define PAGE_MOD(x) ( (x) & (c->wbuf_pagesize - 1) )
 int jffs2_flash_writev(struct jffs2_sb_info *c, const struct kvec *invecs, unsigned long count, loff_t to, size_t *retlen, uint32_t ino)
@@ -575,6 +580,8 @@
 	if (!c->wbuf)
 		return jffs2_flash_direct_writev(c, invecs, count, to, retlen);
 	
+	down_write(&c->wbuf_sem);
+
 	/* If wbuf_ofs is not initialized, set it to target address */
 	if (c->wbuf_ofs == 0xFFFFFFFF) {
 		c->wbuf_ofs = PAGE_DIV(to);
@@ -592,12 +599,12 @@
 		/* It's a write to a new block */
 		if (c->wbuf_len) {
 			D1(printk(KERN_DEBUG "jffs2_flash_writev() to 0x%lx causes flush of wbuf at 0x%08x\n", (unsigned long)to, c->wbuf_ofs));
-			ret = jffs2_flush_wbuf_pad(c);
+			ret = __jffs2_flush_wbuf(c, 1, 1);
 			if (ret) {
 				/* the underlying layer has to check wbuf_len to do the cleanup */
 				D1(printk(KERN_WARNING "jffs2_flush_wbuf() called from jffs2_flash_writev() failed %d\n", ret));
 				*retlen = 0;
-				return ret;
+				goto exit;
 			}
 		}
 		/* set pointer to new block */
@@ -658,14 +665,14 @@
 		}			
 		
 		/* write buffer is full, flush buffer */
-		ret = __jffs2_flush_wbuf(c, 0);
+		ret = __jffs2_flush_wbuf(c, 0, 0);
 		if (ret) {
 			/* the underlying layer has to check wbuf_len to do the cleanup */
 			D1(printk(KERN_WARNING "jffs2_flush_wbuf() called from jffs2_flash_writev() failed %d\n", ret));
 			/* Retlen zero to make sure our caller doesn't mark the space dirty.
 			   We've already done everything that's necessary */
 			*retlen = 0;
-			return ret;
+			goto exit;
 		}
 		outvec_to += donelen;
 		c->wbuf_ofs = outvec_to;
@@ -709,7 +716,6 @@
 
 	if (splitvec != -1) {
 		uint32_t remainder;
-		int ret;
 
 		remainder = outvecs[splitvec].iov_len - split_ofs;
 		outvecs[splitvec].iov_len = split_ofs;
@@ -721,7 +727,7 @@
 			   c->wbuf is empty. 
 			*/
 			*retlen = donelen;
-			return ret;
+			goto exit;
 		}
 		
 		donelen += wbuf_retlen;
@@ -760,7 +766,11 @@
 	if (c->wbuf_len && ino)
 		jffs2_wbuf_dirties_inode(c, ino);
 
-	return 0;
+	ret = 0;
+	
+exit:
+	up_write(&c->wbuf_sem);
+	return ret;
 }
 
 /*
@@ -789,6 +799,8 @@
 
 	/* Read flash */
 	if (!jffs2_can_mark_obsolete(c)) {
+		down_read(&c->wbuf_sem);
+
 		ret = c->mtd->read_ecc(c->mtd, ofs, len, retlen, buf, NULL, c->oobinfo);
 
 		if ( (ret == -EBADMSG) && (*retlen == len) ) {
@@ -811,23 +823,23 @@
 
 	/* if no writebuffer available or write buffer empty, return */
 	if (!c->wbuf_pagesize || !c->wbuf_len)
-		return ret;
+		goto exit;
 
 	/* if we read in a different block, return */
 	if ( (ofs & ~(c->sector_size-1)) != (c->wbuf_ofs & ~(c->sector_size-1)) ) 
-		return ret;	
+		goto exit;
 
 	if (ofs >= c->wbuf_ofs) {
 		owbf = (ofs - c->wbuf_ofs);	/* offset in write buffer */
 		if (owbf > c->wbuf_len)		/* is read beyond write buffer ? */
-			return ret;
+			goto exit;
 		lwbf = c->wbuf_len - owbf;	/* number of bytes to copy */
 		if (lwbf > len)	
 			lwbf = len;
 	} else {	
 		orbf = (c->wbuf_ofs - ofs);	/* offset in read buffer */
 		if (orbf > len)			/* is write beyond write buffer ? */
-			return ret;
+			goto exit;
 		lwbf = len - orbf; 		/* number of bytes to copy */
 		if (lwbf > c->wbuf_len)	
 			lwbf = c->wbuf_len;
@@ -835,6 +847,8 @@
 	if (lwbf > 0)
 		memcpy(buf+orbf,c->wbuf+owbf,lwbf);
 
+exit:
+	up_read(&c->wbuf_sem);
 	return ret;
 }
 
diff -auNr mtd-snapshot-20041008/include/linux/jffs2_fs_sb.h mtd-preepmpt-fix/include/linux/jffs2_fs_sb.h
--- mtd-snapshot-20041008/include/linux/jffs2_fs_sb.h	2003-10-09 02:00:05.000000000 +0400
+++ mtd-preepmpt-fix/include/linux/jffs2_fs_sb.h	2004-11-03 19:20:50.058681364 +0300
@@ -36,8 +36,9 @@
 	struct semaphore alloc_sem;	/* Used to protect all the following 
 					   fields, and also to protect against
 					   out-of-order writing of nodes.
-					   And GC.
-					*/
+					   And GC. Also protects the write buffer
+					   against concurrent writes. */
+	struct rw_semaphore wbuf_sem;	/* Protects the write buffer while it is read */
 	uint32_t cleanmarker_size;	/* Size of an _inline_ CLEANMARKER
 					 (i.e. zero for OOB CLEANMARKER */
 

      parent reply	other threads:[~2004-11-03 16:40 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-10-27 12:35 JFFS2 & SMP Artem B. Bityuckiy
2004-10-27 12:59 ` David Woodhouse
2004-10-27 13:19   ` Artem B. Bityuckiy
2004-10-27 13:35   ` Artem B. Bityuckiy
2004-10-27 13:45     ` David Woodhouse
2004-10-27 14:09       ` Artem B. Bityuckiy
2004-10-27 14:59       ` Artem B. Bityuckiy
2004-10-27 15:07         ` Artem B. Bityuckiy
2004-10-28 12:14           ` Artem B. Bityuckiy
2004-10-28 12:33       ` Artem B. Bityuckiy
2004-10-28 13:57         ` Artem B. Bityuckiy
2004-11-02 14:31           ` Estelle HAMMACHE
2004-11-03 16:29             ` Artem B. Bityuckiy
2004-11-04  9:03               ` Estelle HAMMACHE
2004-11-04  9:36                 ` Artem B. Bityuckiy
     [not found]                   ` <418A591C.A4D46C9E@st.com>
2004-11-04 17:17                     ` Artem B. Bityuckiy
2004-11-05  9:06                       ` Estelle HAMMACHE
2004-11-05 11:51                         ` Artem B. Bityuckiy
2004-11-03 16:39             ` Artem B. Bityuckiy [this message]

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=418909C7.3040508@yandex.ru \
    --to=abityuckiy@yandex.ru \
    --cc=dwmw2@infradead.org \
    --cc=estelle.hammache@st.com \
    --cc=linux-mtd@lists.infradead.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