From patchwork Thu Dec 8 13:15:48 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Kara X-Patchwork-Id: 13068395 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6C964C6370C for ; Thu, 8 Dec 2022 13:16:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229791AbiLHNQG (ORCPT ); Thu, 8 Dec 2022 08:16:06 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38704 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230055AbiLHNQB (ORCPT ); Thu, 8 Dec 2022 08:16:01 -0500 Received: from smtp-out2.suse.de (smtp-out2.suse.de [IPv6:2001:67c:2178:6::1d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C977992A3B; Thu, 8 Dec 2022 05:16:00 -0800 (PST) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out2.suse.de (Postfix) with ESMTPS id 4F2CC208C8; Thu, 8 Dec 2022 13:15:59 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.cz; s=susede2_rsa; t=1670505359; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=3LMNHaFogcKAiq3PV7qT2chrlGfUwbcE2YSyFrK3yQA=; b=bY1VEDghte1H1uQAr45NWvGB44/YXT79dXIBZ1HbAGEfqHgmjBQKB+n0ucPp/C9hyEoGcM wMOit7cXlJg8TjMmbXbPrOrVdmcWKWcpKHDnFmSURPiMIg7hGb2JVLPWUuZ7I0cQEpXn83 dfqv3IT8Z2f/GFLxL2BuZKji509ksAA= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.cz; s=susede2_ed25519; t=1670505359; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=3LMNHaFogcKAiq3PV7qT2chrlGfUwbcE2YSyFrK3yQA=; b=wY56DyIanqXBRI12P2gwcCx0s3cjMJDDtX49QSF2MB7nKco5EAA2Z65XeRQw/68vn5sjaH NRfmfJFhp7AVFvDw== Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id 428A6138E1; Thu, 8 Dec 2022 13:15:59 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id D2Q6EI/jkWNSTQAAMHmgww (envelope-from ); Thu, 08 Dec 2022 13:15:59 +0000 Received: by quack3.suse.cz (Postfix, from userid 1000) id B9C25A0723; Thu, 8 Dec 2022 14:15:58 +0100 (CET) From: Jan Kara To: Cc: Jan Kara , stable@vger.kernel.org Subject: [PATCH 1/4] udf: Fix preallocation discarding at indirect extent boundary Date: Thu, 8 Dec 2022 14:15:48 +0100 Message-Id: <20221208131558.27298-1-jack@suse.cz> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20221208131111.29134-1-jack@suse.cz> References: <20221208131111.29134-1-jack@suse.cz> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=2941; i=jack@suse.cz; h=from:subject; bh=C9GMRZKW48EwB2J6ZdnueBYWIFNB9lXLbG85zpb9yiI=; b=owGbwMvMwME4Z+4qdvsUh5uMp9WSGJInPm6OXOi1eWnu/AP2Qe/Uvsgqz2SJdHJRCl3LZaH2QaTn 0oPDnYzGLAyMHAyyYoosqyMval+bZ9S1NVRDBmYQKxPIFAYuTgGYyIWrHAwHfpVNTNn5jUP2RPaJLe UvC5nuZFTt+/Ihdh/TKcuNbje928rd+aOtHTOO7ejMPhsYxByc7naTtWPSpvMOl2brdssIVmz+dq/r Q8D6vMW5VUcmLF0RKn9F0vp5wS8PoYMtm/+o+F2Il5PqZVq5kpMnQDhcNL2czzRObOJXu57tjV+U/R 8lnD6w5rWJMzP3m3X7CpRX/WiU7d2f6X3ZVUy9MbunQylKJY2zOnvepjm2Pdy60+tlfFec987RmVKc dne/wlEe5didITNEmQ78M+MzKrSd4n/ux9lFAVGTG5id2C1Dnv22XeqWOP0AV290QLV5ilSeUf9nw5 ZrjlvZvb167HYn1LSnuPpOWpwBAA== X-Developer-Key: i=jack@suse.cz; a=openpgp; fpr=93C6099A142276A28BBE35D815BC833443038D8C Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org When preallocation extent is the first one in the extent block, the code would corrupt extent tree header instead. Fix the problem and use udf_delete_aext() for deleting extent to avoid some code duplication. CC: stable@vger.kernel.org Signed-off-by: Jan Kara --- fs/udf/truncate.c | 45 +++++++++++++-------------------------------- 1 file changed, 13 insertions(+), 32 deletions(-) diff --git a/fs/udf/truncate.c b/fs/udf/truncate.c index 532cda99644e..a9790fb32f5f 100644 --- a/fs/udf/truncate.c +++ b/fs/udf/truncate.c @@ -120,60 +120,41 @@ void udf_truncate_tail_extent(struct inode *inode) void udf_discard_prealloc(struct inode *inode) { - struct extent_position epos = { NULL, 0, {0, 0} }; + struct extent_position epos = {}; + struct extent_position prev_epos = {}; struct kernel_lb_addr eloc; uint32_t elen; uint64_t lbcount = 0; int8_t etype = -1, netype; - int adsize; struct udf_inode_info *iinfo = UDF_I(inode); if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB || inode->i_size == iinfo->i_lenExtents) return; - if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) - adsize = sizeof(struct short_ad); - else if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG) - adsize = sizeof(struct long_ad); - else - adsize = 0; - epos.block = iinfo->i_location; /* Find the last extent in the file */ - while ((netype = udf_next_aext(inode, &epos, &eloc, &elen, 1)) != -1) { - etype = netype; + while ((netype = udf_next_aext(inode, &epos, &eloc, &elen, 0)) != -1) { + brelse(prev_epos.bh); + prev_epos = epos; + if (prev_epos.bh) + get_bh(prev_epos.bh); + + etype = udf_next_aext(inode, &epos, &eloc, &elen, 1); lbcount += elen; } if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30)) { - epos.offset -= adsize; lbcount -= elen; - extent_trunc(inode, &epos, &eloc, etype, elen, 0); - if (!epos.bh) { - iinfo->i_lenAlloc = - epos.offset - - udf_file_entry_alloc_offset(inode); - mark_inode_dirty(inode); - } else { - struct allocExtDesc *aed = - (struct allocExtDesc *)(epos.bh->b_data); - aed->lengthAllocDescs = - cpu_to_le32(epos.offset - - sizeof(struct allocExtDesc)); - if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || - UDF_SB(inode->i_sb)->s_udfrev >= 0x0201) - udf_update_tag(epos.bh->b_data, epos.offset); - else - udf_update_tag(epos.bh->b_data, - sizeof(struct allocExtDesc)); - mark_buffer_dirty_inode(epos.bh, inode); - } + udf_delete_aext(inode, prev_epos); + udf_free_blocks(inode->i_sb, inode, &eloc, 0, + DIV_ROUND_UP(elen, 1 << inode->i_blkbits)); } /* This inode entry is in-memory only and thus we don't have to mark * the inode dirty */ iinfo->i_lenExtents = lbcount; brelse(epos.bh); + brelse(prev_epos.bh); } static void udf_update_alloc_ext_desc(struct inode *inode, From patchwork Thu Dec 8 13:15:49 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Kara X-Patchwork-Id: 13068393 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 48121C63703 for ; Thu, 8 Dec 2022 13:16:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230042AbiLHNQE (ORCPT ); Thu, 8 Dec 2022 08:16:04 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38690 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229908AbiLHNQB (ORCPT ); Thu, 8 Dec 2022 08:16:01 -0500 Received: from smtp-out1.suse.de (smtp-out1.suse.de [195.135.220.28]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B130E92FE6; Thu, 8 Dec 2022 05:16:00 -0800 (PST) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out1.suse.de (Postfix) with ESMTPS id 416BC3397C; Thu, 8 Dec 2022 13:15:59 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.cz; s=susede2_rsa; t=1670505359; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=tAVfV1xr3w2V1VuVqoxH5wiVVWcokkBFdzfcpikrNZM=; b=Rhfyc9uCbAaLTJRF9aSoXGDjXG9sh8iYo102C6wCO7d2UG8WQOTU1hbt3WaROP5YfIOf0E vEbCcZEw7dkD5Ohlfpv0qWCFM2JG3vt4lLHD3Dw4qdoyQR9GSH6wMG9zpxG6SzuB0v075o 52CwDYqWdrg0J/tRj/f2IxDlBNQX3rQ= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.cz; s=susede2_ed25519; t=1670505359; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=tAVfV1xr3w2V1VuVqoxH5wiVVWcokkBFdzfcpikrNZM=; b=TRHk6LWpWcGip46gfgT7a2F2KFyhZxx8KqJxNrO6cceRdd34kFw2R/JBj5jKUby8FijaG5 GRhbR7coriw31vBw== Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id 34AA0138E0; Thu, 8 Dec 2022 13:15:59 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id gvjXDI/jkWNRTQAAMHmgww (envelope-from ); Thu, 08 Dec 2022 13:15:59 +0000 Received: by quack3.suse.cz (Postfix, from userid 1000) id BFDEBA0728; Thu, 8 Dec 2022 14:15:58 +0100 (CET) From: Jan Kara To: Cc: Jan Kara , stable@vger.kernel.org Subject: [PATCH 2/4] udf: Do not bother looking for prealloc extents if i_lenExtents matches i_size Date: Thu, 8 Dec 2022 14:15:49 +0100 Message-Id: <20221208131558.27298-2-jack@suse.cz> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20221208131111.29134-1-jack@suse.cz> References: <20221208131111.29134-1-jack@suse.cz> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=895; i=jack@suse.cz; h=from:subject; bh=j6SpR+GLjZrfxyoy0lAfqMG1FSsd3rc+mDmoPSNgE3Y=; b=owEBbQGS/pANAwAIAZydqgc/ZEDZAcsmYgBjkeOE8a+rg/yn+8UgR13XOlgHNcFY0n91N90F6YEm W7FY416JATMEAAEIAB0WIQSrWdEr1p4yirVVKBycnaoHP2RA2QUCY5HjhAAKCRCcnaoHP2RA2VcUB/ 0fke2/D7sJgZNgDDBBqsLBFNLjJu4pgVeyBbakprkNDzALmf3U76y05qskoIcM1SiEaGc5HNNJ4V9O EnjMzW1w1yVVcQXAv+R7YFAWo7U2vbuIQcOrXndMsiiDIAc8HRphuVJKx0bQk39CF3H3b3gn3w3bjO mkwRp0kD7CU3hw9WUzOzJk7Ns8Xw9R69PA7lbDei1j2LqeShnKHmhgUS5BpdkpC3eVz0XVYGUjQ3hj PrPzJlclodLo9PLaa4woR/60MMQ7btV/vEjYk4E/4ApFad0A18CSXJKnA/Lvg6rH8X/yayHHKpYvLL w+mcBCCSt+dJX0HWAnmXsdRrWXWTWD X-Developer-Key: i=jack@suse.cz; a=openpgp; fpr=93C6099A142276A28BBE35D815BC833443038D8C Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org If rounded block-rounded i_lenExtents matches block rounded i_size, there are no preallocation extents. Do not bother walking extent linked list. CC: stable@vger.kernel.org Signed-off-by: Jan Kara --- fs/udf/truncate.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/udf/truncate.c b/fs/udf/truncate.c index a9790fb32f5f..036ebd892b85 100644 --- a/fs/udf/truncate.c +++ b/fs/udf/truncate.c @@ -127,9 +127,10 @@ void udf_discard_prealloc(struct inode *inode) uint64_t lbcount = 0; int8_t etype = -1, netype; struct udf_inode_info *iinfo = UDF_I(inode); + int bsize = 1 << inode->i_blkbits; if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB || - inode->i_size == iinfo->i_lenExtents) + ALIGN(inode->i_size, bsize) == ALIGN(iinfo->i_lenExtents, bsize)) return; epos.block = iinfo->i_location; From patchwork Thu Dec 8 13:15:50 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Kara X-Patchwork-Id: 13068396 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 70D06C63703 for ; Thu, 8 Dec 2022 13:16:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230055AbiLHNQH (ORCPT ); Thu, 8 Dec 2022 08:16:07 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38760 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229966AbiLHNQC (ORCPT ); Thu, 8 Dec 2022 08:16:02 -0500 Received: from smtp-out2.suse.de (smtp-out2.suse.de [195.135.220.29]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C992692FEA; Thu, 8 Dec 2022 05:16:00 -0800 (PST) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out2.suse.de (Postfix) with ESMTPS id 561C6208DE; Thu, 8 Dec 2022 13:15:59 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.cz; s=susede2_rsa; t=1670505359; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=5mtrRWkeif0u1cMY0mFFaMoCXncrrP1/K5/WlVw5nJc=; b=zKeJkJcAcZAPzjMoS8S/cEJq0OXJYI+hbvuP4d3qCuaJQEHMGUGGr6VkqlH7A6Oqp1MXXl QTLIXIm1nH6YsU+LaLXp/TUU45mW4sMIcIdTHEyI9S0HYQVAB0vZLrHEgL/4wauQY1Eea2 T8I8raL6WWPcqNI7sbhPSJ/tfoyDDCk= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.cz; s=susede2_ed25519; t=1670505359; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=5mtrRWkeif0u1cMY0mFFaMoCXncrrP1/K5/WlVw5nJc=; b=p6iCyLXitJuOpwxR8fYLN8QtbYL8Qo/YLIRPD9MLviMsw+5DbI73mkOUB5/0GUkaetV/wB nhDWSrW2qjRusYAg== Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id 4B00D138E2; Thu, 8 Dec 2022 13:15:59 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id Vn3nEY/jkWNaTQAAMHmgww (envelope-from ); Thu, 08 Dec 2022 13:15:59 +0000 Received: by quack3.suse.cz (Postfix, from userid 1000) id C615CA0729; Thu, 8 Dec 2022 14:15:58 +0100 (CET) From: Jan Kara To: Cc: Jan Kara , stable@vger.kernel.org Subject: [PATCH 3/4] udf: Discard preallocation before extending file with a hole Date: Thu, 8 Dec 2022 14:15:50 +0100 Message-Id: <20221208131558.27298-3-jack@suse.cz> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20221208131111.29134-1-jack@suse.cz> References: <20221208131111.29134-1-jack@suse.cz> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=4355; i=jack@suse.cz; h=from:subject; bh=XAAAnca7wXicVWpc8NCWeUwmmzDiNPQvC3+MibdJerY=; b=owEBbQGS/pANAwAIAZydqgc/ZEDZAcsmYgBjkeOFMDbnmQtXLFKTdPFDIaSATWVdkrWAN6/9py+Q UXV/PAyJATMEAAEIAB0WIQSrWdEr1p4yirVVKBycnaoHP2RA2QUCY5HjhQAKCRCcnaoHP2RA2XjpB/ 4v8wb5NYhXGff7TSbIyxFf2Xev4ETSh3u+fScRLvfiSyIa2gYdZPAW4wdyhrjCNHVeZ0axGyWplP50 ef7p1mdKeWVVXqu28OMfxlbDpi2IVgYuSGpglqsSCNscVfo94QjfaRySEUZNe7Ri7l+tYk48pl+b36 BJRt5q1Ku7UpSAczo1tYwZD7WVsIfaQS3WBWLdbAvt0bbJ+MoU5OMZyZvbdRyxooBU2aUdx6XrJz5G arJYxO2Ha4RrNVtqqBCd5hOd1IapjSGULV5GYy20jJWzV7oQJBb/znWaASUUSi6KNnjVY71WD0VrL+ H6Cj+ymwS1NS/izHZpLoK/IvZYYm79 X-Developer-Key: i=jack@suse.cz; a=openpgp; fpr=93C6099A142276A28BBE35D815BC833443038D8C Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org When extending file with a hole, we tried to preserve existing preallocation for the file. However that is not very useful and complicates code because the previous extent may need to be rounded to block boundary as well (which we forgot to do thus causing data corruption for sequence like: xfs_io -f -c "pwrite 0x75e63 11008" -c "truncate 0x7b24b" \ -c "truncate 0xabaa3" -c "pwrite 0xac70b 22954" \ -c "pwrite 0x93a43 11358" -c "pwrite 0xb8e65 52211" file with 512-byte block size. Just discard preallocation before extending file to simplify things and also fix this data corruption. CC: stable@vger.kernel.org Signed-off-by: Jan Kara --- fs/udf/inode.c | 46 ++++++++++++++++++---------------------------- 1 file changed, 18 insertions(+), 28 deletions(-) diff --git a/fs/udf/inode.c b/fs/udf/inode.c index 6db2ef047f1c..d09ca6db14a0 100644 --- a/fs/udf/inode.c +++ b/fs/udf/inode.c @@ -349,6 +349,12 @@ static int udf_get_block(struct inode *inode, sector_t block, iinfo->i_next_alloc_goal++; } + /* + * Block beyond EOF and prealloc extents? Just discard preallocation + * as it is not useful and complicates things. + */ + if (((loff_t)block) << inode->i_blkbits > iinfo->i_lenExtents) + udf_discard_prealloc(inode); udf_clear_extent_cache(inode); phys = inode_getblk(inode, block, &err, &new); if (!phys) @@ -398,8 +404,6 @@ static int udf_do_extend_file(struct inode *inode, uint32_t add; int count = 0, fake = !(last_ext->extLength & UDF_EXTENT_LENGTH_MASK); struct super_block *sb = inode->i_sb; - struct kernel_lb_addr prealloc_loc = {}; - uint32_t prealloc_len = 0; struct udf_inode_info *iinfo; int err; @@ -420,19 +424,6 @@ static int udf_do_extend_file(struct inode *inode, ~(sb->s_blocksize - 1); } - /* Last extent are just preallocated blocks? */ - if ((last_ext->extLength & UDF_EXTENT_FLAG_MASK) == - EXT_NOT_RECORDED_ALLOCATED) { - /* Save the extent so that we can reattach it to the end */ - prealloc_loc = last_ext->extLocation; - prealloc_len = last_ext->extLength; - /* Mark the extent as a hole */ - last_ext->extLength = EXT_NOT_RECORDED_NOT_ALLOCATED | - (last_ext->extLength & UDF_EXTENT_LENGTH_MASK); - last_ext->extLocation.logicalBlockNum = 0; - last_ext->extLocation.partitionReferenceNum = 0; - } - /* Can we merge with the previous extent? */ if ((last_ext->extLength & UDF_EXTENT_FLAG_MASK) == EXT_NOT_RECORDED_NOT_ALLOCATED) { @@ -460,7 +451,7 @@ static int udf_do_extend_file(struct inode *inode, * more extents, we may need to enter possible following * empty indirect extent. */ - if (new_block_bytes || prealloc_len) + if (new_block_bytes) udf_next_aext(inode, last_pos, &tmploc, &tmplen, 0); } @@ -494,17 +485,6 @@ static int udf_do_extend_file(struct inode *inode, } out: - /* Do we have some preallocated blocks saved? */ - if (prealloc_len) { - err = udf_add_aext(inode, last_pos, &prealloc_loc, - prealloc_len, 1); - if (err) - return err; - last_ext->extLocation = prealloc_loc; - last_ext->extLength = prealloc_len; - count++; - } - /* last_pos should point to the last written extent... */ if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) last_pos->offset -= sizeof(struct short_ad); @@ -557,8 +537,17 @@ static int udf_extend_file(struct inode *inode, loff_t newsize) else BUG(); + /* + * When creating hole in file, just don't bother with preserving + * preallocation. It likely won't be very useful anyway. + */ + udf_discard_prealloc(inode); + etype = inode_bmap(inode, first_block, &epos, &eloc, &elen, &offset); within_final_block = (etype != -1); + /* We don't expect extents past EOF... */ + WARN_ON_ONCE(etype != -1 && + elen > ((loff_t)offset + 1) << inode->i_blkbits); if ((!epos.bh && epos.offset == udf_file_entry_alloc_offset(inode)) || (epos.bh && epos.offset == sizeof(struct allocExtDesc))) { @@ -687,10 +676,11 @@ static sector_t inode_getblk(struct inode *inode, sector_t block, goto out_free; } - /* Are we beyond EOF? */ + /* Are we beyond EOF and preallocated extent? */ if (etype == -1) { int ret; loff_t hole_len; + isBeyondEOF = true; if (count) { if (c) From patchwork Thu Dec 8 13:15:51 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Kara X-Patchwork-Id: 13068397 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id D7643C3A5A7 for ; Thu, 8 Dec 2022 13:16:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230149AbiLHNQI (ORCPT ); Thu, 8 Dec 2022 08:16:08 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38766 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229988AbiLHNQC (ORCPT ); Thu, 8 Dec 2022 08:16:02 -0500 Received: from smtp-out2.suse.de (smtp-out2.suse.de [195.135.220.29]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C98D592FE2; Thu, 8 Dec 2022 05:16:00 -0800 (PST) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out2.suse.de (Postfix) with ESMTPS id 6007C20904; Thu, 8 Dec 2022 13:15:59 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.cz; s=susede2_rsa; t=1670505359; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=iPFMHOnurXJKsZDknaM1534eKF2Z3PShZjb8nsALLlE=; b=wxfRE0N/hEpV6HWaO8g7QmhroGa+SECZjcYFm/KHZoTnb6jRp3odfPmRb5LptdTqkvB3yU 2Ku9jWSfqnnmBs3wbcx5gI93B28R7IUAc9QW/r/43FN1QSgv/T3/Szsm+vcnk4+bLp8T0a KOwmas3Wk2Q9eWw+vzVLIRD6h1gTIm8= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.cz; s=susede2_ed25519; t=1670505359; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=iPFMHOnurXJKsZDknaM1534eKF2Z3PShZjb8nsALLlE=; b=QRuYkg+JpvF4rRjcJEgHRA5HKeLkBm1xaWwXEMNP0kD+2regTLR0gpxwZk/6lFymrFrEIY HUWaoxv9gnwMMtBA== Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id 5317F138E1; Thu, 8 Dec 2022 13:15:59 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id fzFEFI/jkWNdTQAAMHmgww (envelope-from ); Thu, 08 Dec 2022 13:15:59 +0000 Received: by quack3.suse.cz (Postfix, from userid 1000) id CBE03A072B; Thu, 8 Dec 2022 14:15:58 +0100 (CET) From: Jan Kara To: Cc: Jan Kara , stable@vger.kernel.org Subject: [PATCH 4/4] udf: Fix extending file within last block Date: Thu, 8 Dec 2022 14:15:51 +0100 Message-Id: <20221208131558.27298-4-jack@suse.cz> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20221208131111.29134-1-jack@suse.cz> References: <20221208131111.29134-1-jack@suse.cz> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=3464; i=jack@suse.cz; h=from:subject; bh=AU/lHCrgIprNH5pPhEr/sAK5FDWApMHlmRpcV7/DMQI=; b=owEBbQGS/pANAwAIAZydqgc/ZEDZAcsmYgBjkeOGWVCHlJTO4D2yEnxlCjopqEclk7RUAt4GTQtn 6wO6b4CJATMEAAEIAB0WIQSrWdEr1p4yirVVKBycnaoHP2RA2QUCY5HjhgAKCRCcnaoHP2RA2ZqyB/ 0eMAPLpWGFVbVWp8I4izW3eLdPwZdNuOhBJkIBHBpDZKOM+BrGpKl1BdVQ9tt7eeiNA0dOtzSvWuwr p8CPWmX/q4J6d+WlhFZfINN71guSMW6vlDoeS6gQ98HeT2AQWBkieUwkJZpK1fAKkO9tehYhcgyJ5l 4lQ7Ehk0xAjtHl2SN8LfFc+91kChDFuED9jh5wRsUcaB9Rqkoah2+WtBKZW21xRR4XxpNEnd5pZQ+E a/GMFj9BLMczHt1Y49gv4p4UJ6XYqMJEn+tkW4jY1JngOShdHDCIT721/4yMMmyniGM8NUvXgHLz4a 7kb//3uKvHyBbS5t6yD+D0p/5w31uA X-Developer-Key: i=jack@suse.cz; a=openpgp; fpr=93C6099A142276A28BBE35D815BC833443038D8C Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org When extending file within last block it can happen that the extent is already rounded to the blocksize and thus contains the offset we want to grow up to. In such case we would mistakenly expand the last extent and make it one block longer than it should be, exposing unallocated block in a file and causing data corruption. Fix the problem by properly detecting this case and bailing out. CC: stable@vger.kernel.org Signed-off-by: Jan Kara --- fs/udf/inode.c | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/fs/udf/inode.c b/fs/udf/inode.c index d09ca6db14a0..1e5d37f6c689 100644 --- a/fs/udf/inode.c +++ b/fs/udf/inode.c @@ -500,13 +500,17 @@ static int udf_do_extend_file(struct inode *inode, static void udf_do_extend_final_block(struct inode *inode, struct extent_position *last_pos, struct kernel_long_ad *last_ext, - uint32_t final_block_len) + uint32_t new_elen) { - struct super_block *sb = inode->i_sb; uint32_t added_bytes; - added_bytes = final_block_len - - (last_ext->extLength & (sb->s_blocksize - 1)); + /* + * Extent already large enough? It may be already rounded up to block + * size... + */ + if (new_elen <= (last_ext->extLength & UDF_EXTENT_LENGTH_MASK)) + return; + added_bytes = (last_ext->extLength & UDF_EXTENT_LENGTH_MASK) - new_elen; last_ext->extLength += added_bytes; UDF_I(inode)->i_lenExtents += added_bytes; @@ -523,12 +527,12 @@ static int udf_extend_file(struct inode *inode, loff_t newsize) int8_t etype; struct super_block *sb = inode->i_sb; sector_t first_block = newsize >> sb->s_blocksize_bits, offset; - unsigned long partial_final_block; + loff_t new_elen; int adsize; struct udf_inode_info *iinfo = UDF_I(inode); struct kernel_long_ad extent; int err = 0; - int within_final_block; + bool within_last_ext; if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) adsize = sizeof(struct short_ad); @@ -544,9 +548,9 @@ static int udf_extend_file(struct inode *inode, loff_t newsize) udf_discard_prealloc(inode); etype = inode_bmap(inode, first_block, &epos, &eloc, &elen, &offset); - within_final_block = (etype != -1); + within_last_ext = (etype != -1); /* We don't expect extents past EOF... */ - WARN_ON_ONCE(etype != -1 && + WARN_ON_ONCE(within_last_ext && elen > ((loff_t)offset + 1) << inode->i_blkbits); if ((!epos.bh && epos.offset == udf_file_entry_alloc_offset(inode)) || @@ -563,19 +567,17 @@ static int udf_extend_file(struct inode *inode, loff_t newsize) extent.extLength |= etype << 30; } - partial_final_block = newsize & (sb->s_blocksize - 1); + new_elen = ((loff_t)offset << inode->i_blkbits) | + (newsize & (sb->s_blocksize - 1)); /* File has extent covering the new size (could happen when extending * inside a block)? */ - if (within_final_block) { + if (within_last_ext) { /* Extending file within the last file block */ - udf_do_extend_final_block(inode, &epos, &extent, - partial_final_block); + udf_do_extend_final_block(inode, &epos, &extent, new_elen); } else { - loff_t add = ((loff_t)offset << sb->s_blocksize_bits) | - partial_final_block; - err = udf_do_extend_file(inode, &epos, &extent, add); + err = udf_do_extend_file(inode, &epos, &extent, new_elen); } if (err < 0)