Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0c949334 authored by Al Viro's avatar Al Viro
Browse files

iov_iter_truncate()



Now It Can Be Done(tm) - we don't need to do iov_shorten() in
generic_file_direct_write() anymore, now that all ->direct_IO()
instances are converted to proper iov_iter methods and honour
iter->count and iter->iov_offset properly.

Get rid of count/ocount arguments of generic_file_direct_write(),
while we are at it.

Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 28060d5d
Loading
Loading
Loading
Loading
+8 −9
Original line number Diff line number Diff line
@@ -1659,8 +1659,7 @@ static noinline ssize_t __btrfs_buffered_write(struct file *file,

static ssize_t __btrfs_direct_write(struct kiocb *iocb,
				    struct iov_iter *from,
				    loff_t pos,
				    size_t count, size_t ocount)
				    loff_t pos)
{
	struct file *file = iocb->ki_filp;
	ssize_t written;
@@ -1668,9 +1667,9 @@ static ssize_t __btrfs_direct_write(struct kiocb *iocb,
	loff_t endbyte;
	int err;

	written = generic_file_direct_write(iocb, from, pos, count, ocount);
	written = generic_file_direct_write(iocb, from, pos);

	if (written < 0 || written == count)
	if (written < 0 || !iov_iter_count(from))
		return written;

	pos += written;
@@ -1720,13 +1719,14 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb,
	u64 end_pos;
	ssize_t num_written = 0;
	ssize_t err = 0;
	size_t count, ocount;
	size_t count;
	bool sync = (file->f_flags & O_DSYNC) || IS_SYNC(file->f_mapping->host);
	struct iov_iter i;

	mutex_lock(&inode->i_mutex);

	count = ocount = iov_length(iov, nr_segs);
	count = iov_length(iov, nr_segs);
	iov_iter_init(&i, WRITE, iov, nr_segs, count);

	current->backing_dev_info = inode->i_mapping->backing_dev_info;
	err = generic_write_checks(file, &pos, &count, S_ISBLK(inode->i_mode));
@@ -1740,7 +1740,7 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb,
		goto out;
	}

	iov_iter_init(&i, WRITE, iov, nr_segs, count);
	iov_iter_truncate(&i, count);

	err = file_remove_suid(file);
	if (err) {
@@ -1783,8 +1783,7 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb,
		atomic_inc(&BTRFS_I(inode)->sync_writers);

	if (unlikely(file->f_flags & O_DIRECT)) {
		num_written = __btrfs_direct_write(iocb, &i,
						   pos, count, ocount);
		num_written = __btrfs_direct_write(iocb, &i, pos);
	} else {
		num_written = __btrfs_buffered_write(file, &i, pos);
		if (num_written > 0)
+8 −10
Original line number Diff line number Diff line
@@ -1188,8 +1188,7 @@ static ssize_t fuse_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
{
	struct file *file = iocb->ki_filp;
	struct address_space *mapping = file->f_mapping;
	size_t count = 0;
	size_t ocount = 0;
	size_t count;
	ssize_t written = 0;
	ssize_t written_buffered = 0;
	struct inode *inode = mapping->host;
@@ -1208,7 +1207,8 @@ static ssize_t fuse_file_aio_write(struct kiocb *iocb, const struct iovec *iov,

	WARN_ON(iocb->ki_pos != pos);

	count = ocount = iov_length(iov, nr_segs);
	count = iov_length(iov, nr_segs);
	iov_iter_init(&i, WRITE, iov, nr_segs, count);
	mutex_lock(&inode->i_mutex);

	/* We can write back this queue in page reclaim */
@@ -1217,11 +1217,11 @@ static ssize_t fuse_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
	err = generic_write_checks(file, &pos, &count, S_ISBLK(inode->i_mode));
	if (err)
		goto out;
	iov_iter_init(&i, WRITE, iov, nr_segs, count);

	if (count == 0)
		goto out;

	iov_iter_truncate(&i, count);
	err = file_remove_suid(file);
	if (err)
		goto out;
@@ -1231,8 +1231,8 @@ static ssize_t fuse_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
		goto out;

	if (file->f_flags & O_DIRECT) {
		written = generic_file_direct_write(iocb, &i, pos, count, ocount);
		if (written < 0 || written == count)
		written = generic_file_direct_write(iocb, &i, pos);
		if (written < 0 || !iov_iter_count(&i))
			goto out;

		pos += written;
@@ -1469,8 +1469,7 @@ static ssize_t __fuse_direct_write(struct fuse_io_priv *io,

	res = generic_write_checks(file, ppos, &count, 0);
	if (!res) {
		if (iter->count > count)
			iter->count = count;
		iov_iter_truncate(iter, count);
		res = fuse_direct_io(io, iter, ppos, FUSE_DIO_WRITE);
	}

@@ -2896,8 +2895,7 @@ fuse_direct_IO(int rw, struct kiocb *iocb, struct iov_iter *iter,
		if (offset >= i_size)
			return 0;
		count = min_t(loff_t, count, fuse_round_up(i_size - offset));
		if (iter->count > count)
			iter->count = count;
		iov_iter_truncate(iter, count);
	}

	io = kmalloc(sizeof(struct fuse_io_priv), GFP_KERNEL);
+5 −5
Original line number Diff line number Diff line
@@ -2241,7 +2241,6 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb,
	int ret, direct_io, appending, rw_level, have_alloc_sem  = 0;
	int can_do_direct, has_refcount = 0;
	ssize_t written = 0;
	size_t ocount;		/* original count */
	size_t count;		/* after file limit checks */
	loff_t old_size, *ppos = &iocb->ki_pos;
	u32 old_clusters;
@@ -2253,6 +2252,9 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb,
	int unaligned_dio = 0;
	struct iov_iter from;

	count = iov_length(iov, nr_segs);
	iov_iter_init(&from, WRITE, iov, nr_segs, count);

	trace_ocfs2_file_aio_write(inode, file, file->f_path.dentry,
		(unsigned long long)OCFS2_I(inode)->ip_blkno,
		file->f_path.dentry->d_name.len,
@@ -2355,16 +2357,14 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb,
	/* communicate with ocfs2_dio_end_io */
	ocfs2_iocb_set_rw_locked(iocb, rw_level);

	count = ocount = iov_length(iov, nr_segs);
	ret = generic_write_checks(file, ppos, &count,
				   S_ISBLK(inode->i_mode));
	if (ret)
		goto out_dio;

	iov_iter_init(&from, WRITE, iov, nr_segs, count);
	iov_iter_truncate(&from, count);
	if (direct_io) {
		written = generic_file_direct_write(iocb, &from, *ppos,
						    count, ocount);
		written = generic_file_direct_write(iocb, &from, *ppos);
		if (written < 0) {
			ret = written;
			goto out_dio;
+5 −4
Original line number Diff line number Diff line
@@ -626,7 +626,7 @@ xfs_file_dio_aio_write(
	const struct iovec	*iovp,
	unsigned long		nr_segs,
	loff_t			pos,
	size_t			ocount)
	size_t			count)
{
	struct file		*file = iocb->ki_filp;
	struct address_space	*mapping = file->f_mapping;
@@ -634,7 +634,6 @@ xfs_file_dio_aio_write(
	struct xfs_inode	*ip = XFS_I(inode);
	struct xfs_mount	*mp = ip->i_mount;
	ssize_t			ret = 0;
	size_t			count = ocount;
	int			unaligned_io = 0;
	int			iolock;
	struct xfs_buftarg	*target = XFS_IS_REALTIME_INODE(ip) ?
@@ -645,6 +644,8 @@ xfs_file_dio_aio_write(
	if ((pos | count) & target->bt_logical_sectormask)
		return -XFS_ERROR(EINVAL);

	iov_iter_init(&from, WRITE, iovp, nr_segs, count);

	/* "unaligned" here means not aligned to a filesystem block */
	if ((pos & mp->m_blockmask) || ((pos + count) & mp->m_blockmask))
		unaligned_io = 1;
@@ -676,6 +677,7 @@ xfs_file_dio_aio_write(
	ret = xfs_file_aio_write_checks(file, &pos, &count, &iolock);
	if (ret)
		goto out;
	iov_iter_truncate(&from, count);

	if (mapping->nrpages) {
		ret = filemap_write_and_wait_range(VFS_I(ip)->i_mapping,
@@ -697,8 +699,7 @@ xfs_file_dio_aio_write(
	}

	trace_xfs_file_direct_write(ip, count, iocb->ki_pos, 0);
	iov_iter_init(&from, WRITE, iovp, nr_segs, count);
	ret = generic_file_direct_write(iocb, &from, pos, count, ocount);
	ret = generic_file_direct_write(iocb, &from, pos);

out:
	xfs_rw_iunlock(ip, iolock);
+1 −2
Original line number Diff line number Diff line
@@ -2407,8 +2407,7 @@ extern ssize_t generic_file_aio_read(struct kiocb *, const struct iovec *, unsig
extern ssize_t generic_file_read_iter(struct kiocb *, struct iov_iter *);
extern ssize_t __generic_file_aio_write(struct kiocb *, const struct iovec *, unsigned long);
extern ssize_t generic_file_aio_write(struct kiocb *, const struct iovec *, unsigned long, loff_t);
extern ssize_t generic_file_direct_write(struct kiocb *, struct iov_iter *,
		loff_t, size_t, size_t);
extern ssize_t generic_file_direct_write(struct kiocb *, struct iov_iter *, loff_t);
extern ssize_t generic_perform_write(struct file *, struct iov_iter *, loff_t);
extern ssize_t do_sync_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos);
extern ssize_t do_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos);
Loading