jffs2文件系统磁盘写入

在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_ref
		return -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);	//多余部分是0

		if ( 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 BREAKME
	static 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;
	} else
		spin_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;
}




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值