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

Commit f76ddff6 authored by Liu Bo's avatar Liu Bo Committed by Greg Kroah-Hartman
Browse files

Btrfs: adjust outstanding_extents counter properly when dio write is split




[ Upstream commit c2931667c83ded6504b3857e99cc45b21fa496fb ]

Currently how btrfs dio deals with split dio write is not good
enough if dio write is split into several segments due to the
lack of contiguous space, a large dio write like 'dd bs=1G count=1'
can end up with incorrect outstanding_extents counter and endio
would complain loudly with an assertion.

This fixes the problem by compensating the outstanding_extents
counter in inode if a large dio write gets split.

Reported-by: default avatarAnand Jain <anand.jain@oracle.com>
Tested-by: default avatarAnand Jain <anand.jain@oracle.com>
Signed-off-by: default avatarLiu Bo <bo.li.liu@oracle.com>
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
Signed-off-by: default avatarSasha Levin <alexander.levin@verizon.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 49fc90b4
Loading
Loading
Loading
Loading
+9 −2
Original line number Diff line number Diff line
@@ -7648,11 +7648,18 @@ static void adjust_dio_outstanding_extents(struct inode *inode,
	 * within our reservation, otherwise we need to adjust our inode
	 * counter appropriately.
	 */
	if (dio_data->outstanding_extents) {
	if (dio_data->outstanding_extents >= num_extents) {
		dio_data->outstanding_extents -= num_extents;
	} else {
		/*
		 * If dio write length has been split due to no large enough
		 * contiguous space, we need to compensate our inode counter
		 * appropriately.
		 */
		u64 num_needed = num_extents - dio_data->outstanding_extents;

		spin_lock(&BTRFS_I(inode)->lock);
		BTRFS_I(inode)->outstanding_extents += num_extents;
		BTRFS_I(inode)->outstanding_extents += num_needed;
		spin_unlock(&BTRFS_I(inode)->lock);
	}
}