UPSTREAM: gfs2: Prevent endless loops in gfs2_file_buffered_write
[ Upstream commit 554c577cee95bdc1d03d9f457e57dc96eb791845 ]
Currently, instead of performing a short write,
iomap_file_buffered_write will fail when part of its iov iterator cannot
be read. In contrast, gfs2_file_buffered_write will loop around if it
can read part of the iov iterator, so we can end up in an endless loop.
This should be fixed in iomap_file_buffered_write (and also
generic_perform_write), but this comes a bit late in the 5.16
development cycle, so work around it in the filesystem by
trimming the iov iterator to the known-good size for now.
Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
(cherry picked from commit e4ea3286b1)
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
Change-Id: Ib2aa1ff71fa20cb8248508238900f444207c8858
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
fe33dcd072
commit
e971e5b5fc
@@ -1023,6 +1023,7 @@ static ssize_t gfs2_file_buffered_write(struct kiocb *iocb,
|
||||
struct gfs2_sbd *sdp = GFS2_SB(inode);
|
||||
struct gfs2_holder *statfs_gh = NULL;
|
||||
size_t prev_count = 0, window_size = 0;
|
||||
size_t orig_count = iov_iter_count(from);
|
||||
size_t read = 0;
|
||||
ssize_t ret;
|
||||
|
||||
@@ -1067,6 +1068,7 @@ retry_under_glock:
|
||||
if (inode == sdp->sd_rindex)
|
||||
gfs2_glock_dq_uninit(statfs_gh);
|
||||
|
||||
from->count = orig_count - read;
|
||||
if (should_fault_in_pages(ret, from, &prev_count, &window_size)) {
|
||||
size_t leftover;
|
||||
|
||||
@@ -1074,6 +1076,7 @@ retry_under_glock:
|
||||
leftover = fault_in_iov_iter_readable(from, window_size);
|
||||
gfs2_holder_disallow_demote(gh);
|
||||
if (leftover != window_size) {
|
||||
from->count = min(from->count, window_size - leftover);
|
||||
if (!gfs2_holder_queued(gh)) {
|
||||
if (read)
|
||||
goto out_uninit;
|
||||
|
||||
Reference in New Issue
Block a user