Ejemplo n.º 1
0
static int f2fs_collapse_range(struct inode *inode, loff_t offset, loff_t len)
{
	pgoff_t pg_start, pg_end;
	loff_t new_size;
	int ret;

	if (offset + len >= i_size_read(inode))
		return -EINVAL;

	/* collapse range should be aligned to block size of f2fs. */
	if (offset & (F2FS_BLKSIZE - 1) || len & (F2FS_BLKSIZE - 1))
		return -EINVAL;

	f2fs_balance_fs(F2FS_I_SB(inode));

	if (f2fs_has_inline_data(inode)) {
		ret = f2fs_convert_inline_inode(inode);
		if (ret)
			return ret;
	}

	pg_start = offset >> PAGE_CACHE_SHIFT;
	pg_end = (offset + len) >> PAGE_CACHE_SHIFT;

	/* write out all dirty pages from offset */
	ret = filemap_write_and_wait_range(inode->i_mapping, offset, LLONG_MAX);
	if (ret)
		return ret;

	truncate_pagecache(inode, 0, offset);

	ret = f2fs_do_collapse(inode, pg_start, pg_end);
	if (ret)
		return ret;

	/* write out all moved pages, if possible */
	filemap_write_and_wait_range(inode->i_mapping, offset, LLONG_MAX);
	truncate_pagecache(inode, 0, offset);

	new_size = i_size_read(inode) - len;
	truncate_pagecache(inode, 0, new_size);

	ret = truncate_blocks(inode, new_size, true);
	if (!ret)
		i_size_write(inode, new_size);

	return ret;
}
Ejemplo n.º 2
0
Archivo: file.c Proyecto: infidel/linux
static int f2fs_collapse_range(struct inode *inode, loff_t offset, loff_t len)
{
    pgoff_t pg_start, pg_end;
    loff_t new_size;
    int ret;

    if (!S_ISREG(inode->i_mode))
        return -EINVAL;

    if (offset + len >= i_size_read(inode))
        return -EINVAL;

    /* collapse range should be aligned to block size of f2fs. */
    if (offset & (F2FS_BLKSIZE - 1) || len & (F2FS_BLKSIZE - 1))
        return -EINVAL;

    pg_start = offset >> PAGE_CACHE_SHIFT;
    pg_end = (offset + len) >> PAGE_CACHE_SHIFT;

    /* write out all dirty pages from offset */
    ret = filemap_write_and_wait_range(inode->i_mapping, offset, LLONG_MAX);
    if (ret)
        return ret;

    truncate_pagecache(inode, offset);

    ret = f2fs_do_collapse(inode, pg_start, pg_end);
    if (ret)
        return ret;

    new_size = i_size_read(inode) - len;

    ret = truncate_blocks(inode, new_size, true);
    if (!ret)
        i_size_write(inode, new_size);

    return ret;
}