📄 file.c
字号:
pg_buf += holeend - offset; offset = holeend; frag = frag->next; 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); 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); ClearPageUptodate(pg); SetPageError(pg); kunmap(pg); return ret; } } 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); ClearPageError(pg); flush_dcache_page(pg); kunmap(pg); D1(printk(KERN_DEBUG "readpage finished\n")); return 0;}int jffs2_do_readpage_unlock(struct inode *inode, struct page *pg){ int ret = jffs2_do_readpage_nolock(inode, pg); UnlockPage(pg); return ret;}int jffs2_readpage (struct file *filp, struct page *pg){ struct jffs2_inode_info *f = JFFS2_INODE_INFO(filp->f_dentry->d_inode); int ret; down(&f->sem); ret = jffs2_do_readpage_unlock(filp->f_dentry->d_inode, 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 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) { /* Make new hole frag from old EOF to new page */ struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb); struct jffs2_raw_inode ri; struct jffs2_full_dnode *fn; __u32 phys_ofs, alloc_len; D1(printk(KERN_DEBUG "Writing new hole frag 0x%x-0x%x between current EOF and new page\n", (unsigned int)inode->i_size, pageofs)); ret = jffs2_reserve_space(c, sizeof(ri), &phys_ofs, &alloc_len, ALLOC_NORMAL); if (ret) { up(&f->sem); return ret; } memset(&ri, 0, sizeof(ri)); ri.magic = JFFS2_MAGIC_BITMASK; ri.nodetype = JFFS2_NODETYPE_INODE; ri.totlen = sizeof(ri); ri.hdr_crc = crc32(0, &ri, sizeof(struct jffs2_unknown_node)-4); ri.ino = f->inocache->ino; ri.version = ++f->highest_version; ri.mode = inode->i_mode; ri.uid = inode->i_uid; ri.gid = inode->i_gid; ri.isize = max((__u32)inode->i_size, pageofs); ri.atime = ri.ctime = ri.mtime = CURRENT_TIME; ri.offset = inode->i_size; ri.dsize = pageofs - inode->i_size; ri.csize = 0; ri.compr = JFFS2_COMPR_ZERO; ri.node_crc = crc32(0, &ri, sizeof(ri)-8); ri.data_crc = 0; fn = jffs2_write_dnode(inode, &ri, NULL, 0, phys_ofs, NULL); jffs2_complete_reservation(c); if (IS_ERR(fn)) { ret = PTR_ERR(fn); up(&f->sem); return ret; } ret = jffs2_add_full_dnode_to_inode(c, f, fn); if (f->metadata) { jffs2_mark_node_obsolete(c, f->metadata->raw); jffs2_free_full_dnode(f->metadata); f->metadata = NULL; } if (ret) { D1(printk(KERN_DEBUG "Eep. add_full_dnode_to_inode() failed in prepare_write, returned %d\n", ret)); jffs2_mark_node_obsolete(c, fn->raw); jffs2_free_full_dnode(fn); up(&f->sem); return ret; } inode->i_size = pageofs; } /* Read in the page if it wasn't already present */ if (!Page_Uptodate(pg) && (start || end < PAGE_SIZE)) ret = jffs2_do_readpage_nolock(inode, pg); D1(printk(KERN_DEBUG "end prepare_write(). nrpages %ld\n", inode->i_mapping->nrpages)); up(&f->sem); return ret;}int jffs2_commit_write (struct file *filp, struct page *pg, unsigned start, unsigned end){ /* 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 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); __u32 file_ofs = (pg->index << PAGE_CACHE_SHIFT); __u32 writelen = min((__u32)PAGE_CACHE_SIZE, newsize - file_ofs); struct jffs2_raw_inode *ri; 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)); ri = jffs2_alloc_raw_inode(); if (!ri) return -ENOMEM; while(writelen) { struct jffs2_full_dnode *fn; unsigned char *comprbuf = NULL; unsigned char comprtype = JFFS2_COMPR_NONE; __u32 phys_ofs, alloclen; __u32 datalen, cdatalen; D2(printk(KERN_DEBUG "jffs2_commit_write() loop: 0x%x to write to 0x%x\n", writelen, file_ofs)); ret = jffs2_reserve_space(c, sizeof(*ri) + JFFS2_MIN_DATA_LEN, &phys_ofs, &alloclen, ALLOC_NORMAL); if (ret) { SetPageError(pg); D1(printk(KERN_DEBUG "jffs2_reserve_space returned %d\n", ret)); break; } down(&f->sem); datalen = writelen; cdatalen = min(alloclen - sizeof(*ri), writelen); comprbuf = kmalloc(cdatalen, GFP_KERNEL); if (comprbuf) { comprtype = jffs2_compress(page_address(pg)+ (file_ofs & (PAGE_CACHE_SIZE-1)), comprbuf, &datalen, &cdatalen); } if (comprtype == JFFS2_COMPR_NONE) { /* Either compression failed, or the allocation of comprbuf failed */ if (comprbuf) kfree(comprbuf); comprbuf = page_address(pg) + (file_ofs & (PAGE_CACHE_SIZE -1)); datalen = cdatalen; } /* Now comprbuf points to the data to be written, be it compressed or not. comprtype holds the compression type, and comprtype == JFFS2_COMPR_NONE means that the comprbuf doesn't need to be kfree()d. */ ri->magic = JFFS2_MAGIC_BITMASK; ri->nodetype = JFFS2_NODETYPE_INODE; ri->totlen = sizeof(*ri) + cdatalen; ri->hdr_crc = crc32(0, ri, sizeof(struct jffs2_unknown_node)-4); ri->ino = inode->i_ino; ri->version = ++f->highest_version; ri->mode = inode->i_mode; ri->uid = inode->i_uid; ri->gid = inode->i_gid; ri->isize = max((__u32)inode->i_size, file_ofs + datalen); ri->atime = ri->ctime = ri->mtime = CURRENT_TIME; ri->offset = file_ofs; ri->csize = cdatalen; ri->dsize = datalen; ri->compr = comprtype; ri->node_crc = crc32(0, ri, sizeof(*ri)-8); ri->data_crc = crc32(0, comprbuf, cdatalen); fn = jffs2_write_dnode(inode, ri, comprbuf, cdatalen, phys_ofs, NULL); jffs2_complete_reservation(c); if (comprtype != JFFS2_COMPR_NONE) kfree(comprbuf); if (IS_ERR(fn)) { ret = PTR_ERR(fn); up(&f->sem); SetPageError(pg); break; } ret = jffs2_add_full_dnode_to_inode(c, f, fn); if (f->metadata) { jffs2_mark_node_obsolete(c, f->metadata->raw); jffs2_free_full_dnode(f->metadata); f->metadata = NULL; } up(&f->sem); if (ret) { /* Eep */ D1(printk(KERN_DEBUG "Eep. add_full_dnode_to_inode() failed in commit_write, returned %d\n", ret)); jffs2_mark_node_obsolete(c, fn->raw); jffs2_free_full_dnode(fn); SetPageError(pg); break; } inode->i_size = ri->isize; inode->i_blocks = (inode->i_size + 511) >> 9; inode->i_ctime = inode->i_mtime = ri->ctime; if (!datalen) { printk(KERN_WARNING "Eep. We didn't actually write any bloody data\n"); ret = -EIO; SetPageError(pg); break; } D1(printk(KERN_DEBUG "increasing writtenlen by %d\n", datalen)); writtenlen += datalen; file_ofs += datalen; writelen -= datalen; } jffs2_free_raw_inode(ri); if (writtenlen < end) { /* generic_file_write has written more to the page cache than we've actually written to the medium. Mark the page !Uptodate so that it gets reread */ D1(printk(KERN_DEBUG "jffs2_commit_write(): Not all bytes written. Marking page !uptodate\n")); SetPageError(pg); ClearPageUptodate(pg); } if (writtenlen <= start) { /* We didn't even get to the start of the affected part */ ret = ret?ret:-ENOSPC; D1(printk(KERN_DEBUG "jffs2_commit_write(): Only %x bytes written to page. start (%x) not reached, returning %d\n", writtenlen, start, ret)); } writtenlen = min(end-start, writtenlen-start); D1(printk(KERN_DEBUG "jffs2_commit_write() returning %d. nrpages is %ld\n",writtenlen?writtenlen:ret, inode->i_mapping->nrpages)); return writtenlen?writtenlen:ret;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -