mtd/fs/jffs2 README.Locking,1.8,1.9 wbuf.c,1.79,1.80
David Woodhouse
dwmw2 at infradead.org
Sat Nov 20 05:35:44 EST 2004
Update of /home/cvs/mtd/fs/jffs2
In directory phoenix.infradead.org:/tmp/cvs-serv16991
Modified Files:
README.Locking wbuf.c
Log Message:
Clean up wbuf_sem a bit, document it.
Index: README.Locking
===================================================================
RCS file: /home/cvs/mtd/fs/jffs2/README.Locking,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- README.Locking 14 Nov 2004 11:43:41 -0000 1.8
+++ README.Locking 20 Nov 2004 10:35:40 -0000 1.9
@@ -133,3 +133,16 @@
collection code is looking at them.
Suggestions for alternative solutions to this problem would be welcomed.
+
+
+ wbuf_sem
+ --------
+
+This read/write semaphore protects against concurrent access to the
+write-behind buffer ('wbuf') used for flash chips where we must write
+in blocks. It protects both the contents of the wbuf and the metadata
+which indicates which flash region (if any) is currently covered by
+the buffer.
+
+Ordering constraints:
+ Lock wbuf_sem last, after the alloc_sem or and f->sem.
Index: wbuf.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs2/wbuf.c,v
retrieving revision 1.79
retrieving revision 1.80
diff -u -r1.79 -r1.80
--- wbuf.c 20 Nov 2004 10:21:40 -0000 1.79
+++ wbuf.c 20 Nov 2004 10:35:40 -0000 1.80
@@ -399,7 +399,11 @@
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, int alloc_wbuf_sem)
+#define NOPAD 0
+#define PAD_NOACCOUNT 1
+#define PAD_ACCOUNTING 2
+
+static int __jffs2_flush_wbuf(struct jffs2_sb_info *c, int pad)
{
int ret;
size_t retlen;
@@ -415,11 +419,8 @@
BUG();
}
- if (alloc_wbuf_sem)
- down_write(&c->wbuf_sem);
-
if(!c->wbuf || !c->wbuf_len)
- goto exit;
+ return 0;
/* claim remaining space on the page
this happens, if we have a change to a new block,
@@ -472,7 +473,7 @@
jffs2_wbuf_recover(c);
- goto exit;
+ return ret;
}
spin_lock(&c->erase_completion_lock);
@@ -511,9 +512,6 @@
/* 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;
}
@@ -542,7 +540,9 @@
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, 1);
+ down_write(&c->wbuf_sem);
+ ret = __jffs2_flush_wbuf(c, PAD_ACCOUNTING);
+ up_write(&c->wbuf_sem);
} else while (old_wbuf_len &&
old_wbuf_ofs == c->wbuf_ofs) {
@@ -554,7 +554,9 @@
if (ret) {
/* GC failed. Flush it with padding instead */
down(&c->alloc_sem);
- ret = __jffs2_flush_wbuf(c, 2, 1);
+ down_write(&c->wbuf_sem);
+ ret = __jffs2_flush_wbuf(c, PAD_ACCOUNTING);
+ up_write(&c->wbuf_sem);
break;
}
down(&c->alloc_sem);
@@ -569,7 +571,13 @@
/* 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, 1);
+ int ret;
+
+ down_write(&c->wbuf_sem);
+ ret = __jffs2_flush_wbuf(c, PAD_NOACCOUNT);
+ up_write(&c->wbuf_sem);
+
+ return ret;
}
#define PAGE_DIV(x) ( (x) & (~(c->wbuf_pagesize - 1)) )
@@ -621,7 +629,7 @@
/* 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(c, 1, 0);
+ ret = __jffs2_flush_wbuf(c, PAD_NOACCOUNT);
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));
@@ -686,7 +694,7 @@
}
/* write buffer is full, flush buffer */
- ret = __jffs2_flush_wbuf(c, 0, 0);
+ ret = __jffs2_flush_wbuf(c, NOPAD);
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));
More information about the linux-mtd-cvs
mailing list