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

Commit 3309dd04 authored by Al Viro's avatar Al Viro
Browse files

switch generic_write_checks() to iocb and iter



... returning -E... upon error and amount of data left in iter after
(possible) truncation upon success.  Note, that normal case gives
a non-zero (positive) return value, so any tests for != 0 _must_ be
updated.

Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>

Conflicts:
	fs/ext4/file.c
parent 90320251
Loading
Loading
Loading
Loading
+10 −16
Original line number Diff line number Diff line
@@ -404,21 +404,16 @@ static ssize_t
v9fs_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
{
	struct file *file = iocb->ki_filp;
	ssize_t retval = 0;
	loff_t origin = iocb->ki_pos;
	size_t count = iov_iter_count(from);
	ssize_t retval;
	loff_t origin;
	int err = 0;

	retval = generic_write_checks(file, &origin, &count);
	if (retval)
	retval = generic_write_checks(iocb, from);
	if (retval <= 0)
		return retval;

	iov_iter_truncate(from, count);

	if (!count)
		return 0;

	retval = p9_client_write(file->private_data, origin, from, &err);
	origin = iocb->ki_pos;
	retval = p9_client_write(file->private_data, iocb->ki_pos, from, &err);
	if (retval > 0) {
		struct inode *inode = file_inode(file);
		loff_t i_size;
@@ -428,12 +423,11 @@ v9fs_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
		if (inode->i_mapping && inode->i_mapping->nrpages)
			invalidate_inode_pages2_range(inode->i_mapping,
						      pg_start, pg_end);
		origin += retval;
		iocb->ki_pos += retval;
		i_size = i_size_read(inode);
		iocb->ki_pos = origin;
		if (origin > i_size) {
			inode_add_bytes(inode, origin - i_size);
			i_size_write(inode, origin);
		if (iocb->ki_pos > i_size) {
			inode_add_bytes(inode, iocb->ki_pos - i_size);
			i_size_write(inode, iocb->ki_pos);
		}
		return retval;
	}
+9 −15
Original line number Diff line number Diff line
@@ -1739,27 +1739,19 @@ static ssize_t btrfs_file_write_iter(struct kiocb *iocb,
	u64 start_pos;
	u64 end_pos;
	ssize_t num_written = 0;
	ssize_t err = 0;
	size_t count = iov_iter_count(from);
	bool sync = (file->f_flags & O_DSYNC) || IS_SYNC(file->f_mapping->host);
	loff_t pos = iocb->ki_pos;
	ssize_t err;
	loff_t pos;
	size_t count;

	mutex_lock(&inode->i_mutex);

	current->backing_dev_info = inode_to_bdi(inode);
	err = generic_write_checks(file, &pos, &count);
	if (err) {
	err = generic_write_checks(iocb, from);
	if (err <= 0) {
		mutex_unlock(&inode->i_mutex);
		goto out;
	}

	if (count == 0) {
		mutex_unlock(&inode->i_mutex);
		goto out;
		return err;
	}

	iov_iter_truncate(from, count);

	current->backing_dev_info = inode_to_bdi(inode);
	err = file_remove_suid(file);
	if (err) {
		mutex_unlock(&inode->i_mutex);
@@ -1786,6 +1778,8 @@ static ssize_t btrfs_file_write_iter(struct kiocb *iocb,
	 */
	update_time_for_write(inode);

	pos = iocb->ki_pos;
	count = iov_iter_count(from);
	start_pos = round_down(pos, root->sectorsize);
	if (start_pos > i_size_read(inode)) {
		/* Expand hole size to cover write data, preventing empty gap */
+6 −8
Original line number Diff line number Diff line
@@ -941,9 +941,9 @@ static ssize_t ceph_write_iter(struct kiocb *iocb, struct iov_iter *from)
	struct ceph_inode_info *ci = ceph_inode(inode);
	struct ceph_osd_client *osdc =
		&ceph_sb_to_client(inode->i_sb)->client->osdc;
	ssize_t count = iov_iter_count(from), written = 0;
	ssize_t count, written = 0;
	int err, want, got;
	loff_t pos = iocb->ki_pos;
	loff_t pos;

	if (ceph_snap(inode) != CEPH_NOSNAP)
		return -EROFS;
@@ -953,14 +953,12 @@ static ssize_t ceph_write_iter(struct kiocb *iocb, struct iov_iter *from)
	/* We can write back this queue in page reclaim */
	current->backing_dev_info = inode_to_bdi(inode);

	err = generic_write_checks(file, &pos, &count);
	if (err)
		goto out;

	if (count == 0)
	err = generic_write_checks(iocb, from);
	if (err <= 0)
		goto out;
	iov_iter_truncate(from, count);

	pos = iocb->ki_pos;
	count = iov_iter_count(from);
	err = file_remove_suid(file);
	if (err)
		goto out;
+6 −20
Original line number Diff line number Diff line
@@ -2563,7 +2563,6 @@ cifs_write_from_iter(loff_t offset, size_t len, struct iov_iter *from,
ssize_t cifs_user_writev(struct kiocb *iocb, struct iov_iter *from)
{
	struct file *file = iocb->ki_filp;
	size_t len;
	ssize_t total_written = 0;
	struct cifsFileInfo *open_file;
	struct cifs_tcon *tcon;
@@ -2579,16 +2578,10 @@ ssize_t cifs_user_writev(struct kiocb *iocb, struct iov_iter *from)
	 * write request.
	 */

	len = iov_iter_count(from);
	rc = generic_write_checks(file, &iocb->ki_pos, &len);
	if (rc)
	rc = generic_write_checks(iocb, from);
	if (rc <= 0)
		return rc;

	if (!len)
		return 0;

	iov_iter_truncate(from, len);

	INIT_LIST_HEAD(&wdata_list);
	cifs_sb = CIFS_FILE_SB(file);
	open_file = file->private_data;
@@ -2599,8 +2592,8 @@ ssize_t cifs_user_writev(struct kiocb *iocb, struct iov_iter *from)

	memcpy(&saved_from, from, sizeof(struct iov_iter));

	rc = cifs_write_from_iter(iocb->ki_pos, len, from, open_file, cifs_sb,
				  &wdata_list);
	rc = cifs_write_from_iter(iocb->ki_pos, iov_iter_count(from), from,
				  open_file, cifs_sb, &wdata_list);

	/*
	 * If at least one write was successfully sent, then discard any rc
@@ -2674,7 +2667,6 @@ cifs_writev(struct kiocb *iocb, struct iov_iter *from)
	struct cifsInodeInfo *cinode = CIFS_I(inode);
	struct TCP_Server_Info *server = tlink_tcon(cfile->tlink)->ses->server;
	ssize_t rc;
	size_t count;

	/*
	 * We need to hold the sem to be sure nobody modifies lock list
@@ -2683,16 +2675,10 @@ cifs_writev(struct kiocb *iocb, struct iov_iter *from)
	down_read(&cinode->lock_sem);
	mutex_lock(&inode->i_mutex);

	count = iov_iter_count(from);
	rc = generic_write_checks(file, &iocb->ki_pos, &count);
	if (rc)
	rc = generic_write_checks(iocb, from);
	if (rc <= 0)
		goto out;

	if (count == 0)
		goto out;

	iov_iter_truncate(from, count);

	if (!cifs_find_lock_conflict(cfile, iocb->ki_pos, iov_iter_count(from),
				     server->vals->exclusive_lock_type, NULL,
				     CIFS_WRITE_OP))
+6 −14
Original line number Diff line number Diff line
@@ -97,9 +97,7 @@ ext4_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
	struct blk_plug plug;
	int o_direct = io_is_direct(file);
	int overwrite = 0;
	size_t length = iov_iter_count(from);
	ssize_t ret;
	loff_t pos;

	/*
	 * Unaligned direct AIO must be serialized; see comment above
@@ -116,16 +114,10 @@ ext4_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
	}

	mutex_lock(&inode->i_mutex);
	ret = generic_write_checks(file, &iocb->ki_pos, &length);
	if (ret)
		goto out;

	if (length == 0)
	ret = generic_write_checks(iocb, from);
	if (ret <= 0)
		goto out;

	iov_iter_truncate(from, length);
	pos = iocb->ki_pos;

	/*
	 * If we have encountered a bitmap-format file, the size limit
	 * is smaller than s_maxbytes, which is for extent-mapped files.
@@ -133,19 +125,19 @@ ext4_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
	if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))) {
		struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);

		if (pos >= sbi->s_bitmap_maxbytes) {
		if (iocb->ki_pos >= sbi->s_bitmap_maxbytes) {
			ret = -EFBIG;
			goto out;
		}
		iov_iter_truncate(from, sbi->s_bitmap_maxbytes - pos);
		iov_iter_truncate(from, sbi->s_bitmap_maxbytes - iocb->ki_pos);
	}

	iocb->private = &overwrite;
	if (o_direct) {
		length = iov_iter_count(from);
		size_t length = iov_iter_count(from);
		loff_t pos = iocb->ki_pos;
		blk_start_plug(&plug);


		/* check whether we do a DIO overwrite or not */
		if (ext4_should_dioread_nolock(inode) && !aio_mutex &&
		    !file->f_mapping->nrpages && pos + length <= i_size_read(inode)) {
Loading