From patchwork Fri Oct 18 23:19:02 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Al Viro X-Patchwork-Id: 13842484 Received: from zeniv.linux.org.uk (zeniv.linux.org.uk [62.89.141.173]) (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 936E118C337 for ; Fri, 18 Oct 2024 23:19:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=62.89.141.173 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729293561; cv=none; b=CkGTU7RB4mr3Np2Y0ASVLV3aJPgjJX5obNi7T8upmbpiOAXAFCvPuHIxuf18HKaKMfBDLigPV9+XdvnK1WBcsUG2rcZJxhSW+/wfZHKkPLS5gt3BpNiwJPE5SisUFcCgpCgggGNJRF+suFC4YJH82eqdoOvTe+KObk6E4DNQkFk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729293561; c=relaxed/simple; bh=vnzIg5kE7r+4SApsjTYWZ4HjRybsWwSHpA2t5Yptf8E=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=kN4mKwmD+0DJeriwu34drObLqUIWIaT6ufKQWa+7BuHTSRSpGy6ci+VkphPoe8nqihQkF8f07FmsI97rrTBJDmB3wFnH1B5edDEY/rYHDobQMp64lzA7oh7vHRSKeMrrk1Zj6vplOmqnjL0LML/RubulSNaPi6MvFadnOjOeA28= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zeniv.linux.org.uk; spf=none smtp.mailfrom=ftp.linux.org.uk; dkim=pass (2048-bit key) header.d=linux.org.uk header.i=@linux.org.uk header.b=CGOcPkEU; arc=none smtp.client-ip=62.89.141.173 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zeniv.linux.org.uk Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=ftp.linux.org.uk Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linux.org.uk header.i=@linux.org.uk header.b="CGOcPkEU" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=linux.org.uk; s=zeniv-20220401; h=Sender:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description; bh=cnMrUTWevv3MUskMWw1NuhwP3T0nyvE0W8GADW2xL5Q=; b=CGOcPkEUaqO4XOVvVRVMrGP1x1 QGeAQMwUxQ+95yQPxTlV3720ePadzDer3BLRTUJUrMmCnqIbJzRHedOMDSct3N0VxRSPx1XoZrfbk Wf+h5p1rTN0L9m+ATt8CRWUtBorYZr6nQFVR8QPMYyclT6WSKXDuI2fgZSh1oT3qU/EFnlFBqJBGO LvMJ1+p0cHOB3q5MGoDihNhoZ29VG0wb3lMOhWiLBOTbU2Ib36yy11qTS2fGxFJJUVQVeC42HoMRc qwBbey3/wwtG0dWDjl/Ngw12PUT+osMJ3mmxxO7nViS5PLalCVrpAbuxoU5P5sc44I6fflwY3RcJo bX79Zc3w==; Received: from viro by zeniv.linux.org.uk with local (Exim 4.98 #2 (Red Hat Linux)) id 1t1wFZ-00000005E6J-0IPe; Fri, 18 Oct 2024 23:19:17 +0000 From: Al Viro To: linux-fsdevel@vger.kernel.org Cc: Evgeniy Dushistov , Matthew Wilcox , Christian Brauner , Jan Kara Subject: [PATCH 03/17] ufs: fix ufs_read_cylinder() failure handling Date: Sat, 19 Oct 2024 00:19:02 +0100 Message-ID: <20241018231916.1245836-3-viro@zeniv.linux.org.uk> X-Mailer: git-send-email 2.46.2 In-Reply-To: <20241018231916.1245836-1-viro@zeniv.linux.org.uk> References: <20241018231428.GC1172273@ZenIV> <20241018231916.1245836-1-viro@zeniv.linux.org.uk> Precedence: bulk X-Mailing-List: linux-fsdevel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Sender: Al Viro 1) ufs_load_cylinder() should return NULL on ufs_read_cylinder() failures. ufs_error() is not enough. As it is, IO failure on attempt to read a part of cylinder group metadata is likely to end up with an oops. 2) we drop the wrong buffer heads when undoing sb_bread() on IO failure halfway through the read - we need to brelse() what we've got from sb_bread(), TYVM... Signed-off-by: Al Viro --- fs/ufs/cylinder.c | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/fs/ufs/cylinder.c b/fs/ufs/cylinder.c index 1abe5454de47..a2813270c303 100644 --- a/fs/ufs/cylinder.c +++ b/fs/ufs/cylinder.c @@ -26,7 +26,7 @@ * Read cylinder group into cache. The memory space for ufs_cg_private_info * structure is already allocated during ufs_read_super. */ -static void ufs_read_cylinder (struct super_block * sb, +static bool ufs_read_cylinder(struct super_block *sb, unsigned cgno, unsigned bitmap_nr) { struct ufs_sb_info * sbi = UFS_SB(sb); @@ -46,9 +46,11 @@ static void ufs_read_cylinder (struct super_block * sb, * We have already the first fragment of cylinder group block in buffer */ UCPI_UBH(ucpi)->bh[0] = sbi->s_ucg[cgno]; - for (i = 1; i < UCPI_UBH(ucpi)->count; i++) - if (!(UCPI_UBH(ucpi)->bh[i] = sb_bread(sb, UCPI_UBH(ucpi)->fragment + i))) + for (i = 1; i < UCPI_UBH(ucpi)->count; i++) { + UCPI_UBH(ucpi)->bh[i] = sb_bread(sb, UCPI_UBH(ucpi)->fragment + i); + if (!UCPI_UBH(ucpi)->bh[i]) goto failed; + } sbi->s_cgno[bitmap_nr] = cgno; ucpi->c_cgx = fs32_to_cpu(sb, ucg->cg_cgx); @@ -67,13 +69,14 @@ static void ufs_read_cylinder (struct super_block * sb, ucpi->c_clusteroff = fs32_to_cpu(sb, ucg->cg_u.cg_44.cg_clusteroff); ucpi->c_nclusterblks = fs32_to_cpu(sb, ucg->cg_u.cg_44.cg_nclusterblks); UFSD("EXIT\n"); - return; + return true; failed: for (j = 1; j < i; j++) - brelse (sbi->s_ucg[j]); + brelse(UCPI_UBH(ucpi)->bh[j]); sbi->s_cgno[bitmap_nr] = UFS_CGNO_EMPTY; ufs_error (sb, "ufs_read_cylinder", "can't read cylinder group block %u", cgno); + return false; } /* @@ -156,15 +159,14 @@ struct ufs_cg_private_info * ufs_load_cylinder ( UFSD("EXIT (FAILED)\n"); return NULL; } - else { - UFSD("EXIT\n"); - return sbi->s_ucpi[cgno]; - } } else { - ufs_read_cylinder (sb, cgno, cgno); - UFSD("EXIT\n"); - return sbi->s_ucpi[cgno]; + if (unlikely(!ufs_read_cylinder (sb, cgno, cgno))) { + UFSD("EXIT (FAILED)\n"); + return NULL; + } } + UFSD("EXIT\n"); + return sbi->s_ucpi[cgno]; } /* * Cylinder group number cg is in cache but it was not last used, @@ -195,7 +197,10 @@ struct ufs_cg_private_info * ufs_load_cylinder ( sbi->s_ucpi[j] = sbi->s_ucpi[j-1]; } sbi->s_ucpi[0] = ucpi; - ufs_read_cylinder (sb, cgno, 0); + if (unlikely(!ufs_read_cylinder (sb, cgno, 0))) { + UFSD("EXIT (FAILED)\n"); + return NULL; + } } UFSD("EXIT\n"); return sbi->s_ucpi[0];