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

Commit 7ed07ba8 authored by Theodore Ts'o's avatar Theodore Ts'o
Browse files

ext4: factor out common code in ext4_file_write()



This shouldn't change any logic flow; just delete duplicated code.

Signed-off-by: default avatar"Theodore Ts'o" <tytso@mit.edu>
Reviewed-by: default avatarJan Kara <jack@suse.cz>
parent 8ad2850f
Loading
Loading
Loading
Loading
+22 −34
Original line number Original line Diff line number Diff line
@@ -97,8 +97,9 @@ ext4_file_write(struct kiocb *iocb, const struct iovec *iov,
{
{
	struct file *file = iocb->ki_filp;
	struct file *file = iocb->ki_filp;
	struct inode *inode = file_inode(iocb->ki_filp);
	struct inode *inode = file_inode(iocb->ki_filp);
	struct mutex *aio_mutex = NULL;
	struct blk_plug plug;
	struct blk_plug plug;
	int unaligned_aio = 0;
	int o_direct = file->f_flags & O_DIRECT;
	int overwrite = 0;
	int overwrite = 0;
	size_t length = iov_length(iov, nr_segs);
	size_t length = iov_length(iov, nr_segs);
	ssize_t ret;
	ssize_t ret;
@@ -123,15 +124,13 @@ ext4_file_write(struct kiocb *iocb, const struct iovec *iov,
		}
		}
	}
	}


	if (unlikely(iocb->ki_filp->f_flags & O_DIRECT)) {
	if (o_direct) {
		if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS) &&
		    !is_sync_kiocb(iocb))
			unaligned_aio = ext4_unaligned_aio(inode, iov,
							   nr_segs, pos);

		/* Unaligned direct AIO must be serialized; see comment above */
		/* Unaligned direct AIO must be serialized; see comment above */
		if (unaligned_aio) {
		if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS) &&
			mutex_lock(ext4_aio_mutex(inode));
		    !is_sync_kiocb(iocb) &&
		    ext4_unaligned_aio(inode, iov, nr_segs, pos)) {
			aio_mutex = ext4_aio_mutex(inode);
			mutex_lock(aio_mutex);
			ext4_unwritten_wait(inode);
			ext4_unwritten_wait(inode);
		}
		}


@@ -141,7 +140,7 @@ ext4_file_write(struct kiocb *iocb, const struct iovec *iov,
		iocb->private = &overwrite;
		iocb->private = &overwrite;


		/* check whether we do a DIO overwrite or not */
		/* check whether we do a DIO overwrite or not */
		if (ext4_should_dioread_nolock(inode) && !unaligned_aio &&
		if (ext4_should_dioread_nolock(inode) && !aio_mutex &&
		    !file->f_mapping->nrpages && pos + length <= i_size_read(inode)) {
		    !file->f_mapping->nrpages && pos + length <= i_size_read(inode)) {
			struct ext4_map_blocks map;
			struct ext4_map_blocks map;
			unsigned int blkbits = inode->i_blkbits;
			unsigned int blkbits = inode->i_blkbits;
@@ -168,6 +167,8 @@ ext4_file_write(struct kiocb *iocb, const struct iovec *iov,
			if (err == len && (map.m_flags & EXT4_MAP_MAPPED))
			if (err == len && (map.m_flags & EXT4_MAP_MAPPED))
				overwrite = 1;
				overwrite = 1;
		}
		}
	} else
		mutex_lock(&inode->i_mutex);


	ret = __generic_file_aio_write(iocb, iov, nr_segs);
	ret = __generic_file_aio_write(iocb, iov, nr_segs);
	mutex_unlock(&inode->i_mutex);
	mutex_unlock(&inode->i_mutex);
@@ -179,24 +180,11 @@ ext4_file_write(struct kiocb *iocb, const struct iovec *iov,
		if (err < 0)
		if (err < 0)
			ret = err;
			ret = err;
	}
	}
	if (o_direct)
		blk_finish_plug(&plug);
		blk_finish_plug(&plug);


		if (unaligned_aio)
	if (aio_mutex)
			mutex_unlock(ext4_aio_mutex(inode));
		mutex_unlock(aio_mutex);
	} else {
		mutex_lock(&inode->i_mutex);
		ret = __generic_file_aio_write(iocb, iov, nr_segs);
		mutex_unlock(&inode->i_mutex);

		if (ret > 0) {
			ssize_t err;

			err = generic_write_sync(file, iocb->ki_pos - ret, ret);
			if (err < 0)
				ret = err;
		}
	}

	return ret;
	return ret;
}
}