jffs2文件系统磁盘写入

来源:互联网 发布:洛克希德马丁 知乎 编辑:程序博客网 时间:2024/05/22 11:07

在jffs2写入其实是一个页写入(不管是nand flash还是nor flash,无非norflash的页大小是1)。

当wbuf_len不足pagesize的时候,pagesize-wbuflen部分,写一个unknown_node,它有一个头,后面的数据是0,这部分的数据是waste的。

如下图:


具体代码:

static int __jffs2_flush_wbuf(struct jffs2_sb_info *c, int pad){struct jffs2_eraseblock *wbuf_jeb;int ret;size_t retlen;/* Nothing to do if not write-buffering the flash. In particular, we shouldn't   del_timer() the timer we never initialised. */if (!jffs2_is_writebuffered(c))return 0;if (!down_trylock(&c->alloc_sem)) {up(&c->alloc_sem);printk(KERN_CRIT "jffs2_flush_wbuf() called with alloc_sem not locked!\n");BUG();}if (!c->wbuf_len)/* already checked c->wbuf above */return 0;wbuf_jeb = &c->blocks[c->wbuf_ofs / c->sector_size];//擦除块if (jffs2_prealloc_raw_node_refs(c, wbuf_jeb, c->nextblock->allocated_refs + 1))//alloc出jffs2_raw_node_refreturn -ENOMEM;/* claim remaining space on the page   this happens, if we have a change to a new block,   or if fsync forces us to flush the writebuffer.   if we have a switch to next page, we will not have   enough remaining space for this.*/if (pad ) {c->wbuf_len = PAD(c->wbuf_len);//四字节对齐/* Pad with JFFS2_DIRTY_BITMASK initially.  this helps out ECC'd NOR   with 8 byte page size */memset(c->wbuf + c->wbuf_len, 0, c->wbuf_pagesize - c->wbuf_len);//多余部分是0if ( c->wbuf_len + sizeof(struct jffs2_unknown_node) < c->wbuf_pagesize) {//如果len还不致于超过一页,则生成一个unkown的node//这个node 紧挨着数据,表示后面空白数据的node//这个node是浪费掉的struct jffs2_unknown_node *padnode = (void *)(c->wbuf + c->wbuf_len);padnode->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);padnode->nodetype = cpu_to_je16(JFFS2_NODETYPE_PADDING);padnode->totlen = cpu_to_je32(c->wbuf_pagesize - c->wbuf_len);padnode->hdr_crc = cpu_to_je32(crc32(0, padnode, sizeof(*padnode)-4));}}/* else jffs2_flash_writev has actually filled in the rest of the   buffer for us, and will deal with the node refs etc. later. */#ifdef BREAKMEstatic int breakme;if (breakme++ == 20) {printk(KERN_NOTICE "Faking write error at 0x%08x\n", c->wbuf_ofs);breakme = 0;c->mtd->write(c->mtd, c->wbuf_ofs, c->wbuf_pagesize, &retlen,      brokenbuf);ret = -EIO;} else#endif//调用mtd函数,写入至物理层ret = c->mtd->write(c->mtd, c->wbuf_ofs, c->wbuf_pagesize, &retlen, c->wbuf);if (ret || retlen != c->wbuf_pagesize) {if (ret)printk(KERN_WARNING "jffs2_flush_wbuf(): Write failed with %d\n",ret);else {printk(KERN_WARNING "jffs2_flush_wbuf(): Write was short: %zd instead of %d\n",retlen, c->wbuf_pagesize);ret = -EIO;}jffs2_wbuf_recover(c);return ret;}/* Adjust free size of the block if we padded. */if (pad) {uint32_t waste = c->wbuf_pagesize - c->wbuf_len;//浪费的空间数D1(printk(KERN_DEBUG "jffs2_flush_wbuf() adjusting free_size of %sblock at %08x\n",  (wbuf_jeb==c->nextblock)?"next":"", wbuf_jeb->offset));/* wbuf_pagesize - wbuf_len is the amount of space that's to be   padded. If there is less free space in the block than that,   something screwed up */if (wbuf_jeb->free_size < waste) {//如果原来空闲的小于本次浪费的,这个是错误的printk(KERN_CRIT "jffs2_flush_wbuf(): Accounting error. wbuf at 0x%08x has 0x%03x bytes, 0x%03x left.\n",       c->wbuf_ofs, c->wbuf_len, waste);printk(KERN_CRIT "jffs2_flush_wbuf(): But free_size for block at 0x%08x is only 0x%08x\n",       wbuf_jeb->offset, wbuf_jeb->free_size);BUG();}spin_lock(&c->erase_completion_lock);jffs2_link_node_ref(c, wbuf_jeb, (c->wbuf_ofs + c->wbuf_len) | REF_OBSOLETE, waste, NULL);/* FIXME: that made it count as dirty. Convert to wasted */wbuf_jeb->dirty_size -= waste;//这个数据是浪费掉的,不是脏的//jffs2_link_node_ref中将这块区域标识成脏了c->dirty_size -= waste;wbuf_jeb->wasted_size += waste;c->wasted_size += waste;} elsespin_lock(&c->erase_completion_lock);/* Stick any now-obsoleted blocks on the erase_pending_list */jffs2_refile_wbuf_blocks(c);jffs2_clear_wbuf_ino_list(c);spin_unlock(&c->erase_completion_lock);memset(c->wbuf,0xff,c->wbuf_pagesize);/* adjust write buffer offset, else we get a non contiguous write bug */c->wbuf_ofs += c->wbuf_pagesize;c->wbuf_len = 0;return 0;}




原创粉丝点击