Exemplo n.º 1
0
static void page_symlink(struct f2fs_sb_info *sbi, struct f2fs_node *inode,
					const char *symname, int symlen)
{
	nid_t ino = le32_to_cpu(inode->footer.ino);
	struct f2fs_summary sum;
	struct node_info ni;
	char *data_blk;
	block_t blkaddr = NULL_ADDR;
	int ret;

	get_node_info(sbi, ino, &ni);

	/* store into inline_data */
	if ((unsigned long)(symlen + 1) <= MAX_INLINE_DATA(inode)) {
		inode->i.i_inline |= F2FS_INLINE_DATA;
		inode->i.i_inline |= F2FS_DATA_EXIST;
		memcpy(inline_data_addr(inode), symname, symlen);
		return;
	}

	data_blk = calloc(BLOCK_SZ, 1);
	ASSERT(data_blk);

	memcpy(data_blk, symname, symlen);

	set_summary(&sum, ino, 0, ni.version);
	reserve_new_block(sbi, &blkaddr, &sum, CURSEG_WARM_DATA);

	ret = dev_write_block(data_blk, blkaddr);
	ASSERT(ret >= 0);

	inode->i.i_addr[get_extra_isize(inode)] = cpu_to_le32(blkaddr);
	free(data_blk);
}
Exemplo n.º 2
0
static int __allocate_data_block(struct dnode_of_data *dn)
{
	struct f2fs_sb_info *sbi = F2FS_I_SB(dn->inode);
	struct f2fs_inode_info *fi = F2FS_I(dn->inode);
	struct f2fs_summary sum;
	struct node_info ni;
	int seg = CURSEG_WARM_DATA;
	pgoff_t fofs;

	if (unlikely(is_inode_flag_set(F2FS_I(dn->inode), FI_NO_ALLOC)))
		return -EPERM;

	dn->data_blkaddr = datablock_addr(dn->node_page, dn->ofs_in_node);
	if (dn->data_blkaddr == NEW_ADDR)
		goto alloc;

	if (unlikely(!inc_valid_block_count(sbi, dn->inode, 1)))
		return -ENOSPC;

alloc:
	get_node_info(sbi, dn->nid, &ni);
	set_summary(&sum, dn->nid, dn->ofs_in_node, ni.version);

	if (dn->ofs_in_node == 0 && dn->inode_page == dn->node_page)
		seg = CURSEG_DIRECT_IO;

	allocate_data_block(sbi, NULL, dn->data_blkaddr, &dn->data_blkaddr,
								&sum, seg);
	set_data_blkaddr(dn);

	/* update i_size */
	fofs = start_bidx_of_node(ofs_of_node(dn->node_page), fi) +
							dn->ofs_in_node;
	if (i_size_read(dn->inode) < ((loff_t)(fofs + 1) << PAGE_CACHE_SHIFT))
		i_size_write(dn->inode,
				((loff_t)(fofs + 1) << PAGE_CACHE_SHIFT));

	/* direct IO doesn't use extent cache to maximize the performance */
	f2fs_drop_largest_extent(dn->inode, fofs);

	return 0;
}
/*
 * In this function, we get a new node blk, and write back
 * node_blk would be sloadd in RAM, linked by dn->node_blk
 */
block_t new_node_block(struct f2fs_sb_info *sbi,
				struct dnode_of_data *dn, unsigned int ofs)
{
	struct f2fs_node *f2fs_inode;
	struct f2fs_node *node_blk;
	struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi);
	struct f2fs_summary sum;
	struct node_info ni;
	block_t blkaddr;
	int type;

	f2fs_inode = dn->inode_blk;

	node_blk = calloc(BLOCK_SZ, 1);
	ASSERT(node_blk);

	node_blk->footer.nid = cpu_to_le32(dn->nid);
	node_blk->footer.ino = f2fs_inode->footer.ino;
	node_blk->footer.flag = cpu_to_le32(ofs << OFFSET_BIT_SHIFT);
	node_blk->footer.cp_ver = ckpt->checkpoint_ver;

	type = CURSEG_COLD_NODE;
	if (IS_DNODE(node_blk)) {
		if (S_ISDIR(f2fs_inode->i.i_mode))
			type = CURSEG_HOT_NODE;
		else
			type = CURSEG_WARM_NODE;
	}

	get_node_info(sbi, dn->nid, &ni);
	set_summary(&sum, dn->nid, 0, ni.version);
	reserve_new_block(sbi, &blkaddr, &sum, type);

	/* update nat info */
	update_nat_blkaddr(sbi, le32_to_cpu(f2fs_inode->footer.ino),
						dn->nid, blkaddr);

	dn->node_blk = node_blk;
	inc_inode_blocks(dn);
	return blkaddr;
}
Exemplo n.º 4
0
static void make_empty_dir(struct f2fs_sb_info *sbi, struct f2fs_node *inode)
{
	struct f2fs_dentry_block *dent_blk;
	nid_t ino = le32_to_cpu(inode->footer.ino);
	nid_t pino = le32_to_cpu(inode->i.i_pino);
	struct f2fs_summary sum;
	struct node_info ni;
	block_t blkaddr = NULL_ADDR;
	int ret;

	get_node_info(sbi, ino, &ni);

	dent_blk = calloc(BLOCK_SZ, 1);
	ASSERT(dent_blk);

	dent_blk->dentry[0].hash_code = 0;
	dent_blk->dentry[0].ino = cpu_to_le32(ino);
	dent_blk->dentry[0].name_len = cpu_to_le16(1);
	dent_blk->dentry[0].file_type = F2FS_FT_DIR;
	memcpy(dent_blk->filename[0], ".", 1);

	dent_blk->dentry[1].hash_code = 0;
	dent_blk->dentry[1].ino = cpu_to_le32(pino);
	dent_blk->dentry[1].name_len = cpu_to_le16(2);
	dent_blk->dentry[1].file_type = F2FS_FT_DIR;
	memcpy(dent_blk->filename[1], "..", 2);

	test_and_set_bit_le(0, dent_blk->dentry_bitmap);
	test_and_set_bit_le(1, dent_blk->dentry_bitmap);

	set_summary(&sum, ino, 0, ni.version);
	reserve_new_block(sbi, &blkaddr, &sum, CURSEG_HOT_DATA);

	ret = dev_write_block(dent_blk, blkaddr);
	ASSERT(ret >= 0);

	inode->i.i_addr[get_extra_isize(inode)] = cpu_to_le32(blkaddr);
	free(dent_blk);
}
 void FinishPage::enter(bool advancing)
 {
   if (advancing)
     set_summary(create_summary(((WbPluginDbImport*)_form)->sql_import()->get_created_objects()));
 }
Exemplo n.º 6
0
int f2fs_create(struct f2fs_sb_info *sbi, struct dentry *de)
{
	struct f2fs_node *parent, *child;
	struct node_info ni;
	struct f2fs_summary sum;
	block_t blkaddr = NULL_ADDR;
	int ret;

	/* Find if there is a */
	get_node_info(sbi, de->pino, &ni);
	if (ni.blk_addr == NULL_ADDR) {
		MSG(0, "No parent directory pino=%x\n", de->pino);
		return -1;
	}

	parent = calloc(BLOCK_SZ, 1);
	ASSERT(parent);

	ret = dev_read_block(parent, ni.blk_addr);
	ASSERT(ret >= 0);

	/* Must convert inline dentry before the following opertions */
	ret = convert_inline_dentry(sbi, parent, ni.blk_addr);
	if (ret) {
		MSG(0, "Convert inline dentry for pino=%x failed.\n", de->pino);
		return -1;
	}

	ret = f2fs_find_entry(sbi, parent, de);
	if (ret) {
		MSG(0, "Skip the existing \"%s\" pino=%x ERR=%d\n",
					de->name, de->pino, ret);
		if (de->file_type == F2FS_FT_REG_FILE)
			de->ino = 0;
		goto free_parent_dir;
	}

	child = calloc(BLOCK_SZ, 1);
	ASSERT(child);

	f2fs_alloc_nid(sbi, &de->ino, 1);

	init_inode_block(sbi, child, de);

	ret = f2fs_add_link(sbi, parent, child->i.i_name,
				le32_to_cpu(child->i.i_namelen),
				le32_to_cpu(child->footer.ino),
				map_de_type(le16_to_cpu(child->i.i_mode)),
				ni.blk_addr, 1);
	if (ret) {
		MSG(0, "Skip the existing \"%s\" pino=%x ERR=%d\n",
					de->name, de->pino, ret);
		goto free_child_dir;
	}

	/* write child */
	set_summary(&sum, de->ino, 0, ni.version);
	reserve_new_block(sbi, &blkaddr, &sum, CURSEG_HOT_NODE);

	/* update nat info */
	update_nat_blkaddr(sbi, de->ino, de->ino, blkaddr);

	ret = dev_write_block(child, blkaddr);
	ASSERT(ret >= 0);

	update_free_segments(sbi);
	MSG(1, "Info: Create %s -> %s\n"
		"  -- ino=%x, type=%x, mode=%x, uid=%x, "
		"gid=%x, cap=%"PRIx64", size=%lu, pino=%x\n",
		de->full_path, de->path,
		de->ino, de->file_type, de->mode,
		de->uid, de->gid, de->capabilities, de->size, de->pino);
free_child_dir:
	free(child);
free_parent_dir:
	free(parent);
	return 0;
}
Exemplo n.º 7
0
static int f2fs_do_collapse(struct inode *inode, pgoff_t start, pgoff_t end)
{
	struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
	struct dnode_of_data dn;
	pgoff_t nrpages = (i_size_read(inode) + PAGE_SIZE - 1) / PAGE_SIZE;
	int ret = 0;

	f2fs_lock_op(sbi);

	for (; end < nrpages; start++, end++) {
		block_t new_addr, old_addr;

		set_new_dnode(&dn, inode, NULL, NULL, 0);
		ret = get_dnode_of_data(&dn, end, LOOKUP_NODE_RA);
		if (ret && ret != -ENOENT) {
			goto out;
		} else if (ret == -ENOENT) {
			new_addr = NULL_ADDR;
		} else {
			new_addr = dn.data_blkaddr;
			truncate_data_blocks_range(&dn, 1);
			f2fs_put_dnode(&dn);
		}

		if (new_addr == NULL_ADDR) {
			set_new_dnode(&dn, inode, NULL, NULL, 0);
			ret = get_dnode_of_data(&dn, start, LOOKUP_NODE_RA);
			if (ret && ret != -ENOENT)
				goto out;
			else if (ret == -ENOENT)
				continue;

			if (dn.data_blkaddr == NULL_ADDR) {
				f2fs_put_dnode(&dn);
				continue;
			} else {
				truncate_data_blocks_range(&dn, 1);
			}

			f2fs_put_dnode(&dn);
		} else {
			struct page *ipage;

			ipage = get_node_page(sbi, inode->i_ino);
			if (IS_ERR(ipage)) {
				ret = PTR_ERR(ipage);
				goto out;
			}

			set_new_dnode(&dn, inode, ipage, NULL, 0);
			ret = f2fs_reserve_block(&dn, start);
			if (ret)
				goto out;

			old_addr = dn.data_blkaddr;
			if (old_addr != NEW_ADDR && new_addr == NEW_ADDR) {
				dn.data_blkaddr = NULL_ADDR;
				f2fs_update_extent_cache(&dn);
				invalidate_blocks(sbi, old_addr);

				dn.data_blkaddr = new_addr;
				set_data_blkaddr(&dn);
			} else if (new_addr != NEW_ADDR) {
				struct node_info ni;
				struct f2fs_summary sum;

				get_node_info(sbi, dn.nid, &ni);
				set_summary(&sum, dn.nid, dn.ofs_in_node,
								ni.version);

				f2fs_replace_block(sbi, &sum, old_addr,
								new_addr, true);

				dn.data_blkaddr = new_addr;
				set_data_blkaddr(&dn);
				f2fs_update_extent_cache(&dn);
			}

			f2fs_put_dnode(&dn);
		}
	}
	ret = 0;
out:
	f2fs_unlock_op(sbi);
	return ret;
}