From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 516F13EA60 for ; Mon, 19 Feb 2024 16:17:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708359460; cv=none; b=G6JX2647U7ETjck3Ub4wOVfXkcszAf7FfFZ9qyDdbOZm0n2ZQoj2R7VYPGyUV1ZcWwtWRkVABl1dzYNogsKwcu5F3RuJ4AEEgjc5iOKsaPhIg0B0qU0QYEQHcINCWYVVdJVDBg1ym9tnw4fdJud6TEF7hMvzMPxVAtFFySyHqPk= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708359460; c=relaxed/simple; bh=bEXjpRqmJu0C3MsiQ00/HW4W8fYQVNkJYEdJgkhYlCQ=; h=Subject:To:Cc:From:Date:Message-ID:MIME-Version:Content-Type; b=T52WCnMSB/3dv0P7rh/48GDTTd3JbLO67Mf6vjbo1IEzYQaf1n0zBLIiBO6bpagB4GvpUXMXrVaoQv6F3bYTW2UtYjy3rLDtlGblsK8jjXIBJw1KT9WHVu9CLMXgex8mgz2cS0+V8fJC8f4azRH4SX0OVGrEfTAFPHqv0LaIls8= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b=h2IiMF2a; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b="h2IiMF2a" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 6E6D7C43390; Mon, 19 Feb 2024 16:17:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1708359459; bh=bEXjpRqmJu0C3MsiQ00/HW4W8fYQVNkJYEdJgkhYlCQ=; h=Subject:To:Cc:From:Date:From; b=h2IiMF2av7alXzgNqMGAaPxZ97VcWw2rt6VKQqU9vq+Qyx7+uMDalNQSwlAC0c+Tr wMDOJma9nKarEjHJCsk33eVRmuij8zN1L0R9pE8tO40nJKhnEZG8mSOOD+uDTkapv4 jQcVmUvl7/3PY22Z0P8elywu7sZUdLysrLjvJXRk= Subject: FAILED: patch "[PATCH] ext4: convert to exclusive lock while inserting delalloc" failed to apply to 5.15-stable tree To: yi.zhang@huawei.com,jack@suse.cz,tytso@mit.edu Cc: From: Date: Mon, 19 Feb 2024 17:17:26 +0100 Message-ID: <2024021925-sultry-pointer-db19@gregkh> Precedence: bulk X-Mailing-List: stable@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=ANSI_X3.4-1968 Content-Transfer-Encoding: 8bit The patch below does not apply to the 5.15-stable tree. If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to . To reproduce the conflict and resubmit, you may use the following commands: git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-5.15.y git checkout FETCH_HEAD git cherry-pick -x acf795dc161f3cf481db20f05db4250714e375e5 # git commit -s git send-email --to '' --in-reply-to '2024021925-sultry-pointer-db19@gregkh' --subject-prefix 'PATCH 5.15.y' HEAD^.. Possible dependencies: acf795dc161f ("ext4: convert to exclusive lock while inserting delalloc extents") 3fcc2b887a1b ("ext4: refactor ext4_da_map_blocks()") 6c120399cde6 ("ext4: make ext4_es_insert_extent() return void") 2a69c450083d ("ext4: using nofail preallocation in ext4_es_insert_extent()") bda3efaf774f ("ext4: use pre-allocated es in __es_remove_extent()") 95f0b320339a ("ext4: use pre-allocated es in __es_insert_extent()") 73a2f033656b ("ext4: factor out __es_alloc_extent() and __es_free_extent()") 9649eb18c628 ("ext4: add a new helper to check if es must be kept") thanks, greg k-h ------------------ original commit in Linus's tree ------------------ >From acf795dc161f3cf481db20f05db4250714e375e5 Mon Sep 17 00:00:00 2001 From: Zhang Yi Date: Sat, 27 Jan 2024 09:58:01 +0800 Subject: [PATCH] ext4: convert to exclusive lock while inserting delalloc extents ext4_da_map_blocks() only hold i_data_sem in shared mode and i_rwsem when inserting delalloc extents, it could be raced by another querying path of ext4_map_blocks() without i_rwsem, .e.g buffered read path. Suppose we buffered read a file containing just a hole, and without any cached extents tree, then it is raced by another delayed buffered write to the same area or the near area belongs to the same hole, and the new delalloc extent could be overwritten to a hole extent. pread() pwrite() filemap_read_folio() ext4_mpage_readpages() ext4_map_blocks() down_read(i_data_sem) ext4_ext_determine_hole() //find hole ext4_ext_put_gap_in_cache() ext4_es_find_extent_range() //no delalloc extent ext4_da_map_blocks() down_read(i_data_sem) ext4_insert_delayed_block() //insert delalloc extent ext4_es_insert_extent() //overwrite delalloc extent to hole This race could lead to inconsistent delalloc extents tree and incorrect reserved space counter. Fix this by converting to hold i_data_sem in exclusive mode when adding a new delalloc extent in ext4_da_map_blocks(). Cc: stable@vger.kernel.org Signed-off-by: Zhang Yi Suggested-by: Jan Kara Reviewed-by: Jan Kara Link: https://lore.kernel.org/r/20240127015825.1608160-3-yi.zhang@huaweicloud.com Signed-off-by: Theodore Ts'o diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index bbd5ee6dd3f3..b040337501e3 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -1703,10 +1703,8 @@ static int ext4_da_map_blocks(struct inode *inode, sector_t iblock, /* Lookup extent status tree firstly */ if (ext4_es_lookup_extent(inode, iblock, NULL, &es)) { - if (ext4_es_is_hole(&es)) { - down_read(&EXT4_I(inode)->i_data_sem); + if (ext4_es_is_hole(&es)) goto add_delayed; - } /* * Delayed extent could be allocated by fallocate. @@ -1748,8 +1746,10 @@ static int ext4_da_map_blocks(struct inode *inode, sector_t iblock, retval = ext4_ext_map_blocks(NULL, inode, map, 0); else retval = ext4_ind_map_blocks(NULL, inode, map, 0); - if (retval < 0) - goto out_unlock; + if (retval < 0) { + up_read(&EXT4_I(inode)->i_data_sem); + return retval; + } if (retval > 0) { unsigned int status; @@ -1765,24 +1765,21 @@ static int ext4_da_map_blocks(struct inode *inode, sector_t iblock, EXTENT_STATUS_UNWRITTEN : EXTENT_STATUS_WRITTEN; ext4_es_insert_extent(inode, map->m_lblk, map->m_len, map->m_pblk, status); - goto out_unlock; + up_read(&EXT4_I(inode)->i_data_sem); + return retval; } + up_read(&EXT4_I(inode)->i_data_sem); add_delayed: - /* - * XXX: __block_prepare_write() unmaps passed block, - * is it OK? - */ + down_write(&EXT4_I(inode)->i_data_sem); retval = ext4_insert_delayed_block(inode, map->m_lblk); + up_write(&EXT4_I(inode)->i_data_sem); if (retval) - goto out_unlock; + return retval; map_bh(bh, inode->i_sb, invalid_block); set_buffer_new(bh); set_buffer_delay(bh); - -out_unlock: - up_read((&EXT4_I(inode)->i_data_sem)); return retval; }