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 */
prev 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