Beispiel #1
0
void
write_data(fsinfo_t *fsopts, fsnode *node, unsigned char *buf, size_t len,
    uint32_t ofs)
{
	struct chfs_flash_data_node fdata;

	memset(&fdata, 0, sizeof(fdata));
	if (len == 0) {
		return;
	}
	
	pad_block_if_less_than(fsopts, sizeof(fdata) + len);

	fdata.magic = htole16(CHFS_FS_MAGIC_BITMASK);
	fdata.type = htole16(CHFS_NODETYPE_DATA);
	fdata.length = htole32(CHFS_PAD(sizeof(fdata) + len));
	fdata.hdr_crc = htole32(crc32(0, (uint8_t *)&fdata,
	    CHFS_NODE_HDR_SIZE - 4));
	fdata.vno = htole64(node->inode->ino);
	fdata.data_length = htole32(len);
	fdata.offset = htole32(ofs);
	fdata.data_crc = htole32(crc32(0, (uint8_t *)buf, len));
	fdata.node_crc = htole32(crc32(0,
	    (uint8_t *)&fdata, sizeof(fdata) - 4));

	buf_write(fsopts, &fdata, sizeof(fdata));
	buf_write(fsopts, buf, len);
	padword(fsopts);
}
Beispiel #2
0
void
write_vnode(fsinfo_t *fsopts, fsnode *node)
{
	struct chfs_flash_vnode fvnode;
	memset(&fvnode, 0, sizeof(fvnode));
	
	fvnode.magic = htole16(CHFS_FS_MAGIC_BITMASK);
	fvnode.type = htole16(CHFS_NODETYPE_VNODE);
	fvnode.length = htole32(CHFS_PAD(sizeof(fvnode)));
	fvnode.hdr_crc = htole32(crc32(0, (uint8_t *)&fvnode,
	    CHFS_NODE_HDR_SIZE - 4));
	fvnode.vno = htole64(node->inode->ino);
	fvnode.version = htole64(version++);
	fvnode.mode = htole32(node->inode->st.st_mode);
	fvnode.dn_size = htole32(node->inode->st.st_size);
	fvnode.atime = htole32(node->inode->st.st_atime);
	fvnode.ctime = htole32(node->inode->st.st_ctime);
	fvnode.mtime = htole32(node->inode->st.st_mtime);
	fvnode.gid = htole32(node->inode->st.st_uid);
	fvnode.uid = htole32(node->inode->st.st_gid);
	fvnode.node_crc = htole32(crc32(0, (uint8_t *)&fvnode,
	    sizeof(fvnode) - 4));

	pad_block_if_less_than(fsopts, sizeof(fvnode));
	buf_write(fsopts, &fvnode, sizeof(fvnode));
	padword(fsopts);
}
Beispiel #3
0
void
write_dirent(fsinfo_t *fsopts, fsnode *node)
{
	struct chfs_flash_dirent_node fdirent;
	char *name;

	name = emalloc(strlen(node->name));
	memcpy(name, node->name, strlen(node->name));

	memset(&fdirent, 0, sizeof(fdirent));
	fdirent.magic = htole16(CHFS_FS_MAGIC_BITMASK);
	fdirent.type = htole16(CHFS_NODETYPE_DIRENT);
	fdirent.length = htole32(CHFS_PAD(sizeof(fdirent) + strlen(name)));
	fdirent.hdr_crc = htole32(crc32(0, (uint8_t *)&fdirent,
	    CHFS_NODE_HDR_SIZE - 4));
	fdirent.vno = htole64(node->inode->ino);
	if (node->parent != NULL) {
		fdirent.pvno = htole64(node->parent->inode->ino);
	} else {
		fdirent.pvno = htole64(node->inode->ino);
	}

	fdirent.version = htole64(version++);
	fdirent.mctime = 0;
	fdirent.nsize = htole32(strlen(name));
	fdirent.dtype = htole32(IFTOCHT(node->type & S_IFMT));
	fdirent.name_crc = htole32(crc32(0, (uint8_t *)name, fdirent.nsize));
	fdirent.node_crc = htole32(crc32(0, (uint8_t *)&fdirent,
	    sizeof(fdirent) - 4));
	
	pad_block_if_less_than(fsopts, sizeof(fdirent) + fdirent.nsize);
	buf_write(fsopts, &fdirent, sizeof(fdirent));
	buf_write(fsopts, name, fdirent.nsize);
	padword(fsopts);
}
Beispiel #4
0
/*
 * chfs_check_td_data - checks the data CRC of the node
 *
 * Returns: 0 - if everything OK;
 * 	    	1 - if CRC is incorrect;
 * 	    	2 - else;
 *	    	error code if an error occured.
 */
int
chfs_check_td_data(struct chfs_mount *chmp,
    struct chfs_tmp_dnode *td)
{
	int err;
	size_t retlen, len, totlen;
	uint32_t crc;
	uint64_t ofs;
	char *buf;
	struct chfs_node_ref *nref = td->node->nref;

	KASSERT(mutex_owned(&chmp->chm_lock_mountfields));
	KASSERT(!mutex_owned(&chmp->chm_lock_sizes));

	ofs = CHFS_GET_OFS(nref->nref_offset) + sizeof(struct chfs_flash_data_node);
	len = td->node->size;
	if (!len)
		return 0;

	/* Read data. */
	buf = kmem_alloc(len, KM_SLEEP);
	if (!buf) {
		dbg("allocating error\n");
		return 2;
	}
	err = chfs_read_leb(chmp, nref->nref_lnr, buf, ofs, len, &retlen);
	if (err) {
		dbg("error while reading: %d\n", err);
		err = 2;
		goto out;
	}

	/* Check crc. */
	if (len != retlen) {
		dbg("len:%zu, retlen:%zu\n", len, retlen);
		err = 2;
		goto out;
	}
	crc = crc32(0, (uint8_t *)buf, len);

	if (crc != td->data_crc) {
		dbg("crc failed, calculated: 0x%x, orig: 0x%x\n", crc, td->data_crc);
		kmem_free(buf, len);
		return 1;
	}

	/* Correct sizes. */
	CHFS_MARK_REF_NORMAL(nref);
	totlen = CHFS_PAD(sizeof(struct chfs_flash_data_node) + len);

	mutex_enter(&chmp->chm_lock_sizes);
	chfs_change_size_unchecked(chmp, &chmp->chm_blocks[nref->nref_lnr], -totlen);
	chfs_change_size_used(chmp, &chmp->chm_blocks[nref->nref_lnr], totlen);
	mutex_exit(&chmp->chm_lock_sizes);
	KASSERT(chmp->chm_blocks[nref->nref_lnr].used_size <= chmp->chm_ebh->eb_size);

	err = 0;
out:
	kmem_free(buf, len);
	return err;
}