static ssize_t f2fs_direct_IO(int rw, struct kiocb *iocb,
				const struct iovec *iov, loff_t offset,
				unsigned long nr_segs)
{
	struct file *file = iocb->ki_filp;
	struct address_space *mapping = file->f_mapping;
	struct inode *inode = mapping->host;
	size_t count = iov_length(iov, nr_segs);
	int err;

	/* we don't need to use inline_data strictly */
	if (f2fs_has_inline_data(inode)) {
		err = f2fs_convert_inline_inode(inode);
		if (err)
			return err;
	}

	if (f2fs_encrypted_inode(inode) && S_ISREG(inode->i_mode))
		return 0;

	err = check_direct_IO(inode, rw, iov, offset, nr_segs);
	if (err)
		return err;

	trace_f2fs_direct_IO_enter(inode, offset, count, rw);

	if (rw & WRITE) {
		__allocate_data_blocks(inode, offset, count);
		if (unlikely(f2fs_cp_error(F2FS_I_SB(inode)))) {
			err = -EIO;
			goto out;
		}
	}

	err = blockdev_direct_IO(rw, iocb, inode, iov, offset, nr_segs,
							get_data_block_dio);
out:
	if (err < 0 && (rw & WRITE))
		f2fs_write_failed(mapping, offset + count);

	trace_f2fs_direct_IO_exit(inode, offset, count, rw, err);

	return err;
}
Beispiel #2
0
static ssize_t f2fs_direct_IO(struct kiocb *iocb, struct iov_iter *iter,
                              loff_t offset)
{
    struct file *file = iocb->ki_filp;
    struct address_space *mapping = file->f_mapping;
    struct inode *inode = mapping->host;
    size_t count = iov_iter_count(iter);
    int err;

    /* we don't need to use inline_data strictly */
    if (f2fs_has_inline_data(inode)) {
        err = f2fs_convert_inline_inode(inode);
        if (err)
            return err;
    }

    if (f2fs_encrypted_inode(inode) && S_ISREG(inode->i_mode))
        return 0;

    err = check_direct_IO(inode, iter, offset);
    if (err)
        return err;

    trace_f2fs_direct_IO_enter(inode, offset, count, iov_iter_rw(iter));

    if (iov_iter_rw(iter) == WRITE)
        __allocate_data_blocks(inode, offset, count);

    err = blockdev_direct_IO(iocb, inode, iter, offset, get_data_block_dio);
    if (err < 0 && iov_iter_rw(iter) == WRITE)
        f2fs_write_failed(mapping, offset + count);

    trace_f2fs_direct_IO_exit(inode, offset, count, iov_iter_rw(iter), err);

    return err;
}