patch-2.4.20 linux-2.4.20/fs/jffs2/file.c
Next file: linux-2.4.20/fs/jffs2/gc.c
Previous file: linux-2.4.20/fs/jffs2/dir.c
Back to the patch index
Back to the overall index
- Lines: 135
- Date:
Thu Nov 28 15:53:15 2002
- Orig file:
linux-2.4.19/fs/jffs2/file.c
- Orig date:
Fri Aug 2 17:39:45 2002
diff -urN linux-2.4.19/fs/jffs2/file.c linux-2.4.20/fs/jffs2/file.c
@@ -31,7 +31,7 @@
* provisions above, a recipient may use your version of this file
* under either the RHEPL or the GPL.
*
- * $Id: file.c,v 1.58.2.1 2002/02/23 14:25:36 dwmw2 Exp $
+ * $Id: file.c,v 1.58.2.6 2002/11/12 13:17:01 dwmw2 Exp $
*
*/
@@ -276,23 +276,28 @@
continue;
} else {
__u32 readlen;
- readlen = min(frag->size, end - offset);
- D1(printk(KERN_DEBUG "Reading %d-%d from node at 0x%x\n", frag->ofs, frag->ofs+readlen, frag->node->raw->flash_offset & ~3));
- ret = jffs2_read_dnode(c, frag->node, pg_buf, frag->ofs - frag->node->ofs, readlen);
+ __u32 fragofs; /* offset within the frag to start reading */
+
+ fragofs = offset - frag->ofs;
+ readlen = min(frag->size - fragofs, end - offset);
+ D1(printk(KERN_DEBUG "Reading %d-%d from node at 0x%x\n", frag->ofs+fragofs,
+ fragofs+frag->ofs+readlen, frag->node->raw->flash_offset & ~3));
+ ret = jffs2_read_dnode(c, frag->node, pg_buf, fragofs + frag->ofs - frag->node->ofs, readlen);
D2(printk(KERN_DEBUG "node read done\n"));
if (ret) {
D1(printk(KERN_DEBUG"jffs2_readpage error %d\n",ret));
- memset(pg_buf, 0, frag->size);
+ memset(pg_buf, 0, readlen);
ClearPageUptodate(pg);
SetPageError(pg);
kunmap(pg);
return ret;
}
+
+ pg_buf += readlen;
+ offset += readlen;
+ frag = frag->next;
+ D2(printk(KERN_DEBUG "node read was OK. Looping\n"));
}
- pg_buf += frag->size;
- offset += frag->size;
- frag = frag->next;
- D2(printk(KERN_DEBUG "node read was OK. Looping\n"));
}
D2(printk(KERN_DEBUG "readpage finishing\n"));
SetPageUptodate(pg);
@@ -315,23 +320,22 @@
int jffs2_readpage (struct file *filp, struct page *pg)
{
- struct jffs2_inode_info *f = JFFS2_INODE_INFO(filp->f_dentry->d_inode);
+ struct jffs2_inode_info *f = JFFS2_INODE_INFO(pg->mapping->host);
int ret;
down(&f->sem);
- ret = jffs2_do_readpage_unlock(filp->f_dentry->d_inode, pg);
+ ret = jffs2_do_readpage_unlock(pg->mapping->host, pg);
up(&f->sem);
return ret;
}
int jffs2_prepare_write (struct file *filp, struct page *pg, unsigned start, unsigned end)
{
- struct inode *inode = filp->f_dentry->d_inode;
+ struct inode *inode = pg->mapping->host;
struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
__u32 pageofs = pg->index << PAGE_CACHE_SHIFT;
int ret = 0;
- down(&f->sem);
D1(printk(KERN_DEBUG "jffs2_prepare_write() nrpages %ld\n", inode->i_mapping->nrpages));
if (pageofs > inode->i_size) {
@@ -345,10 +349,10 @@
(unsigned int)inode->i_size, pageofs));
ret = jffs2_reserve_space(c, sizeof(ri), &phys_ofs, &alloc_len, ALLOC_NORMAL);
- if (ret) {
- up(&f->sem);
+ if (ret)
return ret;
- }
+
+ down(&f->sem);
memset(&ri, 0, sizeof(ri));
ri.magic = JFFS2_MAGIC_BITMASK;
@@ -391,14 +395,17 @@
return ret;
}
inode->i_size = pageofs;
+ up(&f->sem);
}
- /* Read in the page if it wasn't already present */
- if (!Page_Uptodate(pg) && (start || end < PAGE_SIZE))
+ /* Read in the page if it wasn't already present, unless it's a whole page */
+ if (!Page_Uptodate(pg) && (start || end < PAGE_CACHE_SIZE)) {
+ down(&f->sem);
ret = jffs2_do_readpage_nolock(inode, pg);
- D1(printk(KERN_DEBUG "end prepare_write(). nrpages %ld\n", inode->i_mapping->nrpages));
- up(&f->sem);
+ up(&f->sem);
+ }
+ D1(printk(KERN_DEBUG "end prepare_write(). pg->flags %lx\n", pg->flags));
return ret;
}
@@ -407,7 +414,7 @@
/* Actually commit the write from the page cache page we're looking at.
* For now, we write the full page out each time. It sucks, but it's simple
*/
- struct inode *inode = filp->f_dentry->d_inode;
+ struct inode *inode = pg->mapping->host;
struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
__u32 newsize = max_t(__u32, filp->f_dentry->d_inode->i_size, (pg->index << PAGE_CACHE_SHIFT) + end);
@@ -417,7 +424,15 @@
int ret = 0;
ssize_t writtenlen = 0;
- D1(printk(KERN_DEBUG "jffs2_commit_write(): ino #%lu, page at 0x%lx, range %d-%d, nrpages %ld\n", inode->i_ino, pg->index << PAGE_CACHE_SHIFT, start, end, filp->f_dentry->d_inode->i_mapping->nrpages));
+ D1(printk(KERN_DEBUG "jffs2_commit_write(): ino #%lu, page at 0x%lx, range %d-%d, flags %lx\n", inode->i_ino, pg->index << PAGE_CACHE_SHIFT, start, end, pg->flags));
+
+ if (!start && end == PAGE_CACHE_SIZE) {
+ /* We need to avoid deadlock with page_cache_read() in
+ jffs2_garbage_collect_pass(). So we have to mark the
+ page up to date, to prevent page_cache_read() from
+ trying to re-lock it. */
+ SetPageUptodate(pg);
+ }
ri = jffs2_alloc_raw_inode();
if (!ri)
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)