Exemplo n.º 1
0
/**
 * ubifs_read_node - read node.
 * @c: UBIFS file-system description object
 * @buf: buffer to read to
 * @type: node type
 * @len: node length (not aligned)
 * @lnum: logical eraseblock number
 * @offs: offset within the logical eraseblock
 *
 * This function reads a node of known type and and length, checks it and
 * stores in @buf. Returns zero in case of success, %-EUCLEAN if CRC mismatched
 * and a negative error code in case of failure.
 */
int ubifs_read_node(const struct ubifs_info *c, void *buf, int type, int len,
		    int lnum, int offs)
{
	int err, l;
	struct ubifs_ch *ch = buf;
       int try_count = 0;

	dbg_io("LEB %d:%d, %s, length %d", lnum, offs, dbg_ntype(type), len);
	ubifs_assert(lnum >= 0 && lnum < c->leb_cnt && offs >= 0);
	ubifs_assert(len >= UBIFS_CH_SZ && offs + len <= c->leb_size);
	ubifs_assert(!(offs & 7) && offs < c->leb_size);
	ubifs_assert(type >= 0 && type < UBIFS_NODE_TYPES_CNT);

try_read:
	err = ubi_read(c->ubi, lnum, buf, offs, len);
	if (err && err != -EBADMSG) {
		ubifs_err("cannot read node %d from LEB %d:%d, error %d",
			  type, lnum, offs, err);
		return err;
	}

	if (type != ch->node_type) {
		ubifs_err("bad node type (%d but expected %d)",
			  ch->node_type, type);
		goto out;
	}

	err = ubifs_check_node(c, buf, lnum, offs, 0, 0);
	if (err) {
		ubifs_err("expected node type %d", type);
              if(try_count < 3){
                  try_count++;
                  udelay(100);
                  goto try_read;
              }
              else{
		   return err;
              }
	}

	l = le32_to_cpu(ch->len);
	if (l != len) {
		ubifs_err("bad node length %d, expected %d", l, len);
		goto out;
	}

	return 0;

out:
	ubifs_err("bad node at LEB %d:%d, LEB mapping status %d", lnum, offs,
		  ubi_is_mapped(c->ubi, lnum));
	dbg_dump_node(c, buf);
	dbg_dump_stack();
	return -EINVAL;
}
Exemplo n.º 2
0
int ubifs_is_mapped(const struct ubifs_info *c, int lnum)
{
	int err;

	err = ubi_is_mapped(c->ubi, lnum);
	if (err < 0) {
		ubifs_err("ubi_is_mapped failed for LEB %d, error %d",
			  lnum, err);
		dbg_dump_stack();
	}
	return err;
}
Exemplo n.º 3
0
/**
 * ubifs_read_node - read node.
 * @c: UBIFS file-system description object
 * @buf: buffer to read to
 * @type: node type
 * @len: node length (not aligned)
 * @lnum: logical eraseblock number
 * @offs: offset within the logical eraseblock
 *
 * This function reads a node of known type and and length, checks it and
 * stores in @buf. Returns zero in case of success, %-EUCLEAN if CRC mismatched
 * and a negative error code in case of failure.
 */
int ubifs_read_node(const struct ubifs_info *c, void *buf, int type, int len,
		    int lnum, int offs)
{
	int err, l;
	struct ubifs_ch *ch = buf;
#if defined(FEATURE_UBIFS_PERF_INDEX)
	unsigned long long time1 = sched_clock();
#endif

	dbg_io("LEB %d:%d, %s, length %d", lnum, offs, dbg_ntype(type), len);
	ubifs_assert(lnum >= 0 && lnum < c->leb_cnt && offs >= 0);
	ubifs_assert(len >= UBIFS_CH_SZ && offs + len <= c->leb_size);
	ubifs_assert(!(offs & 7) && offs < c->leb_size);
	ubifs_assert(type >= 0 && type < UBIFS_NODE_TYPES_CNT);

	err = ubifs_leb_read(c, lnum, buf, offs, len, 0);
	if (err && err != -EBADMSG)
		return err;

	if (type != ch->node_type) {
		ubifs_err("bad node type (%d but expected %d)",
			  ch->node_type, type);
		goto out;
	}

	err = ubifs_check_node(c, buf, lnum, offs, 0, 0);
	if (err) {
		ubifs_err("expected node type %d", type);
		return err;
	}

	l = le32_to_cpu(ch->len);
	if (l != len) {
		ubifs_err("bad node length %d, expected %d", l, len);
		goto out;
	}

#if defined(FEATURE_UBIFS_PERF_INDEX)
	if(type == UBIFS_DATA_NODE) {
		ubifs_perf_lrcount(sched_clock() - time1, len);
	}
#endif
	return 0;

out:
	ubifs_err("bad node at LEB %d:%d, LEB mapping status %d", lnum, offs,
		  ubi_is_mapped(c->ubi, lnum));
	dbg_dump_node(c, buf);
	dbg_dump_stack();
	return -EINVAL;
}
Exemplo n.º 4
0
static int do_cached_write (struct ubiblk_dev *ubiblk, unsigned long sector, 
			    int len, const char *buf)
{
	struct ubi_volume_desc *uv = ubiblk->uv;
	int ppb = uv->vol->ubi->leb_size / uv->vol->ubi->min_io_size;
	unsigned short sectors_per_page =  uv->vol->ubi->min_io_size >> 9;
	unsigned short page_shift =  ffs(uv->vol->ubi->min_io_size) - 1;
	unsigned short virt_block, page, page_offset; 	
	unsigned long virt_page; 
	
	virt_page = sector / sectors_per_page;
	page_offset = sector % sectors_per_page;
	virt_block = virt_page / ppb; 
	page = virt_page % ppb;

	if(ubi_is_mapped(uv, virt_block ) == UNMAPPED ){
		mutex_lock(&ubiblk->cache_mutex);
		ubiblk_flush_writecache(ubiblk);
		mutex_unlock(&ubiblk->cache_mutex);
	
		ubiblk_setup_writecache(ubiblk, virt_block);
          	ubi_leb_map(uv, virt_block, UBI_UNKNOWN);

	} else {
		if ( STATE_USED == ubiblk->write_cache_state ) {
			if ( ubiblk->vbw != virt_block) {
			// Commit before we start a new cache.
				mutex_lock(&ubiblk->cache_mutex);
				ubiblk_flush_writecache(ubiblk);
				mutex_unlock(&ubiblk->cache_mutex);

				ubiblk_setup_writecache(ubiblk, virt_block);
				ubi_leb_unmap(uv, virt_block);
			  	ubi_leb_map(uv, virt_block, UBI_UNKNOWN);
			} else {
				//dprintk("cache hit: 0x%x\n", virt_page);
			}
		} else {
//			printk("with existing mapping\n");
			ubiblk_setup_writecache(ubiblk, virt_block);
			ubi_leb_unmap(uv, virt_block);		
			ubi_leb_map(uv, virt_block, UBI_UNKNOWN);
		}                        
	}		
	memcpy(&ubiblk->write_cache[(page<<page_shift) +(page_offset<<9)],
	       buf,len);
	return 0;
}
Exemplo n.º 5
0
/**
 * ubifs_read_node - read node.
 * @c: UBIFS file-system description object
 * @buf: buffer to read to
 * @type: node type
 * @len: node length (not aligned)
 * @lnum: logical eraseblock number
 * @offs: offset within the logical eraseblock
 *
 * This function reads a node of known type and and length, checks it and
 * stores in @buf. Returns zero in case of success, %-EUCLEAN if CRC mismatched
 * and a negative error code in case of failure.
 */
int ubifs_read_node(const struct ubifs_info *c, void *buf, int type, int len,
		    int lnum, int offs)
{
	int err, l;
	struct ubifs_ch *ch = buf;

	dbg_io("LEB %d:%d, %s, length %d", lnum, offs, dbg_ntype(type), len);
	ubifs_assert(c, lnum >= 0 && lnum < c->leb_cnt && offs >= 0);
	ubifs_assert(c, len >= UBIFS_CH_SZ && offs + len <= c->leb_size);
	ubifs_assert(c, !(offs & 7) && offs < c->leb_size);
	ubifs_assert(c, type >= 0 && type < UBIFS_NODE_TYPES_CNT);

	err = ubifs_leb_read(c, lnum, buf, offs, len, 0);
	if (err && err != -EBADMSG)
		return err;

	if (type != ch->node_type) {
		ubifs_errc(c, "bad node type (%d but expected %d)",
			   ch->node_type, type);
		goto out;
	}

	err = ubifs_check_node(c, buf, lnum, offs, 0, 0);
	if (err) {
		ubifs_errc(c, "expected node type %d", type);
		return err;
	}

	l = le32_to_cpu(ch->len);
	if (l != len) {
		ubifs_errc(c, "bad node length %d, expected %d", l, len);
		goto out;
	}

	return 0;

out:
	ubifs_errc(c, "bad node at LEB %d:%d, LEB mapping status %d", lnum,
		   offs, ubi_is_mapped(c->ubi, lnum));
	if (!c->probing) {
		ubifs_dump_node(c, buf);
		dump_stack();
	}
	return -EINVAL;
}
Exemplo n.º 6
0
/**
 * check_volume_empty - check if the UBI volume is empty.
 * @c: UBIFS file-system description object
 *
 * This function checks if the UBIFS volume is empty by looking if its LEBs are
 * mapped or not. The result of checking is stored in the @c->empty variable.
 * Returns zero in case of success and a negative error code in case of
 * failure.
 */
static int check_volume_empty(struct ubifs_info *c)
{
	int lnum, err;

	c->empty = 1;
	for (lnum = 0; lnum < c->leb_cnt; lnum++) {
		err = ubi_is_mapped(c->ubi, lnum);
		if (unlikely(err < 0))
			return err;
		if (err == 1) {
			c->empty = 0;
			break;
		}

		cond_resched();
	}

	return 0;
}
Exemplo n.º 7
0
static int do_cached_read (struct ubiblk_dev *ubiblk, unsigned long sector, 
			   int len, char *buf)
{
	struct ubi_volume_desc *uv = ubiblk->uv;
	int ppb = uv->vol->ubi->leb_size / uv->vol->ubi->min_io_size;
	unsigned short sectors_per_page =  uv->vol->ubi->min_io_size >> 9;
	unsigned short page_shift =  ffs(uv->vol->ubi->min_io_size) - 1;
	unsigned short virt_block, page, page_offset; 	
	unsigned long virt_page; 
		
	virt_page = sector / sectors_per_page;
	page_offset = sector % sectors_per_page;
	virt_block = virt_page / ppb; 
	page = virt_page % ppb;

	if(ubiblk->vbw == virt_block){		
		mutex_lock(&ubiblk->cache_mutex);
		ubiblk_flush_writecache(ubiblk);
		mutex_unlock(&ubiblk->cache_mutex);
	}

	if ( ubi_is_mapped( uv, virt_block) == UNMAPPED){
		// In a Flash Memory device, there might be a logical block that is
		// not allcated to a physical block due to the block not being used.
		// All data returned should be set to 0xFF when accessing this logical 
		// block.
		//	dprintk("address translate fail\n");
		memset(buf, 0xFF, 512);
	} else {

		if( ubiblk->vbr != virt_block ||ubiblk->read_cache_state == STATE_UNUSED ){
			ubiblk->vbr = virt_block;
			ubi_leb_read(uv, virt_block, ubiblk->read_cache, 0, uv->vol->usable_leb_size, 0);				
			ubiblk->read_cache_state = STATE_USED;
		}
		memcpy(buf, &ubiblk->read_cache[(page<<page_shift)+(page_offset<<9)], len);
	}
	return 0;
}