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

Commit 0d5b0cf2 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Dave Chinner
Browse files

fs: update atime before I/O in generic_file_read_iter



After the call to ->direct_IO the final reference to the file might have
been dropped by aio_complete already, and the call to file_accessed might
cause a use after free.

Instead update the access time before the I/O, similar to how we
update the time stamps before writes.

Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarDave Chinner <dchinner@redhat.com>
Signed-off-by: default avatarDave Chinner <david@fromorbit.com>
parent a447d7cd
Loading
Loading
Loading
Loading
+7 −7
Original line number Diff line number Diff line
@@ -1910,16 +1910,18 @@ generic_file_read_iter(struct kiocb *iocb, struct iov_iter *iter)
	if (iocb->ki_flags & IOCB_DIRECT) {
		struct address_space *mapping = file->f_mapping;
		struct inode *inode = mapping->host;
		struct iov_iter data = *iter;
		loff_t size;

		size = i_size_read(inode);
		retval = filemap_write_and_wait_range(mapping, iocb->ki_pos,
					iocb->ki_pos + count - 1);
		if (!retval) {
			struct iov_iter data = *iter;
			retval = mapping->a_ops->direct_IO(iocb, &data);
		}
		if (retval < 0)
			goto out;

		file_accessed(file);

		retval = mapping->a_ops->direct_IO(iocb, &data);
		if (retval > 0) {
			iocb->ki_pos += retval;
			iov_iter_advance(iter, retval);
@@ -1935,11 +1937,9 @@ generic_file_read_iter(struct kiocb *iocb, struct iov_iter *iter)
		 * DAX files, so don't bother trying.
		 */
		if (retval < 0 || !iov_iter_count(iter) || iocb->ki_pos >= size ||
		    IS_DAX(inode)) {
			file_accessed(file);
		    IS_DAX(inode))
			goto out;
	}
	}

	retval = do_generic_file_read(file, &iocb->ki_pos, iter, retval);
out: