Ejemplo n.º 1
0
int reserve_new_block(struct dnode_of_data *dn)
{
    struct f2fs_sb_info *sbi = F2FS_I_SB(dn->inode);

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

    trace_f2fs_reserve_new_block(dn->inode, dn->nid, dn->ofs_in_node);

    dn->data_blkaddr = NEW_ADDR;
    set_data_blkaddr(dn);
    mark_inode_dirty(dn->inode);
    sync_inode_page(dn);
    return 0;
}
Ejemplo 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;
}