From nobody Fri Nov 29 14:52:51 2024 Received: from m16.mail.126.com (m16.mail.126.com [117.135.210.6]) by smtp.subspace.kernel.org (Postfix) with ESMTP id E7BEB178377 for ; Wed, 18 Sep 2024 09:41:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=117.135.210.6 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726652523; cv=none; b=aa04X6i8mQs0azXwWYxLNtRMGDERVSrJo/JGDt6y3U91G9/VZkU1jmacHlk/Fp1WGHm5hA8S0KospRJHioc6M2NJzzq9XdP1AAH/06vitklpKSzz4wCIKOS9bZf46qy2wxtSYBitOObSjEQ0bybuakD0c9arl0iq9UJm8lq/qqY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726652523; c=relaxed/simple; bh=VQ/Y0teW8Qsj0SVJ/e7JuI4FUHMS3eQMkCqkSVzSkiM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Q1C5vhNkViXgrJIdHKctpBkVDQJRZYrLKWGxV+/VFO0NOaiWwyPopXrSDvJ8syz+H+g3PSUyiajKCjdW+fYWVI5tgsLwpLVMr+a/cf01zJRPJUGqNoTQmw9kz27+hI3aXfNkQdkoAhYkj6b7Id3/K9fSYeqYaDDMEmqn8OQCubk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=126.com; spf=pass smtp.mailfrom=126.com; dkim=pass (1024-bit key) header.d=126.com header.i=@126.com header.b=PQ4300hq; arc=none smtp.client-ip=117.135.210.6 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=126.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=126.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=126.com header.i=@126.com header.b="PQ4300hq" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=126.com; s=s110527; h=From:Subject:Date:Message-ID:MIME-Version; bh=3oMAn UeqM5iB/KTwRi2tsIgbHERfZiSx6XRy1OEUILE=; b=PQ4300hqcCupb/eVEps3A KTtbI4WhQKgK1YuaanNoVrl9zApbQyuICRuvpWttQuxQB6HcNDpfT+iHmuWqWl9u 0aXO8IQPVbTRPgjxLpk+rlXCOMsyPcnfFchA2IjywYNGfeM6jAJPqoW6YfSlXJ1Y 7DWFxr1ElWokJejqgn1vJM= Received: from localhost.localdomain (unknown [1.198.30.207]) by gzga-smtp-mta-g2-1 (Coremail) with SMTP id _____wDnLyAsn+pm2TCHAA--.46011S3; Wed, 18 Sep 2024 17:36:46 +0800 (CST) From: Zhao Mengmeng To: jack@suse.com, zhaomengmeng@kylinos.cn Cc: linux-kernel@vger.kernel.org Subject: [PATCH 1/3] udf: refactor udf_current_aext() to handle error Date: Wed, 18 Sep 2024 17:36:32 +0800 Message-ID: <20240918093634.12906-2-zhaomzhao@126.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240918093634.12906-1-zhaomzhao@126.com> References: <20240918093634.12906-1-zhaomzhao@126.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: _____wDnLyAsn+pm2TCHAA--.46011S3 X-Coremail-Antispam: 1Uf129KBjvJXoW3Xr13Ar15tw48Jry3Ww43GFg_yoW7Ww45pF W2k3sFkw43XrWxur4IqF4DZ3Waqa93Gr4UGr12q34ftF409r15t3WUtr4I9FyUKrs5Ww42 vrs8tryq9w42y3DanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDUYxBIdaVFxhVjvjDU0xZFpf9x07U8xhLUUUUU= X-CM-SenderInfo: 52kd0zp2kd0qqrswhudrp/1tbimh1ed2bqixWx0QADsf Content-Type: text/plain; charset="utf-8" From: Zhao Mengmeng As Jan suggested in links below, refactor udf_current_aext() to differentiate between error and "hit EOF", it now takes pointer to etype to store the extent type, return 0 when get etype success; return -ENODATA when hit EOF; return -EINVAL when i_alloc_type invalid. Link: https://lore.kernel.org/all/20240912111235.6nr3wuqvktecy3vh@quack3/ Signed-off-by: Zhao Mengmeng --- fs/udf/inode.c | 37 +++++++++++++++++++++++-------------- fs/udf/truncate.c | 3 +-- fs/udf/udfdecl.h | 5 +++-- 3 files changed, 27 insertions(+), 18 deletions(-) diff --git a/fs/udf/inode.c b/fs/udf/inode.c index 4726a4d014b6..6d41ca0e7dba 100644 --- a/fs/udf/inode.c +++ b/fs/udf/inode.c @@ -1955,6 +1955,7 @@ int udf_setup_indirect_aext(struct inode *inode, udf_= pblk_t block, struct extent_position nepos; struct kernel_lb_addr neloc; int ver, adsize; + int err =3D 0; =20 if (UDF_I(inode)->i_alloc_type =3D=3D ICBTAG_FLAG_AD_SHORT) adsize =3D sizeof(struct short_ad); @@ -1999,10 +2000,12 @@ int udf_setup_indirect_aext(struct inode *inode, ud= f_pblk_t block, if (epos->offset + adsize > sb->s_blocksize) { struct kernel_lb_addr cp_loc; uint32_t cp_len; - int cp_type; + int8_t cp_type; =20 epos->offset -=3D adsize; - cp_type =3D udf_current_aext(inode, epos, &cp_loc, &cp_len, 0); + err =3D udf_current_aext(inode, epos, &cp_loc, &cp_len, &cp_type, 0); + if (err < 0) + goto err_out; cp_len |=3D ((uint32_t)cp_type) << 30; =20 __udf_add_aext(inode, &nepos, &cp_loc, cp_len, 1); @@ -2017,6 +2020,9 @@ int udf_setup_indirect_aext(struct inode *inode, udf_= pblk_t block, *epos =3D nepos; =20 return 0; +err_out: + brelse(epos->bh); + return err; } =20 /* @@ -2167,9 +2173,12 @@ int8_t udf_next_aext(struct inode *inode, struct ext= ent_position *epos, { int8_t etype; unsigned int indirections =3D 0; + int err =3D 0; + + while ((err =3D udf_current_aext(inode, epos, eloc, elen, &etype, inc))) { + if (err || etype !=3D (EXT_NEXT_EXTENT_ALLOCDESCS >> 30)) + break; =20 - while ((etype =3D udf_current_aext(inode, epos, eloc, elen, inc)) =3D=3D - (EXT_NEXT_EXTENT_ALLOCDESCS >> 30)) { udf_pblk_t block; =20 if (++indirections > UDF_MAX_INDIR_EXTS) { @@ -2190,14 +2199,14 @@ int8_t udf_next_aext(struct inode *inode, struct ex= tent_position *epos, } } =20 - return etype; + return err; } =20 -int8_t udf_current_aext(struct inode *inode, struct extent_position *epos, - struct kernel_lb_addr *eloc, uint32_t *elen, int inc) +int udf_current_aext(struct inode *inode, struct extent_position *epos, + struct kernel_lb_addr *eloc, uint32_t *elen, int8_t *etype, + int inc) { int alen; - int8_t etype; uint8_t *ptr; struct short_ad *sad; struct long_ad *lad; @@ -2224,8 +2233,8 @@ int8_t udf_current_aext(struct inode *inode, struct e= xtent_position *epos, case ICBTAG_FLAG_AD_SHORT: sad =3D udf_get_fileshortad(ptr, alen, &epos->offset, inc); if (!sad) - return -1; - etype =3D le32_to_cpu(sad->extLength) >> 30; + return -ENODATA; + *etype =3D le32_to_cpu(sad->extLength) >> 30; eloc->logicalBlockNum =3D le32_to_cpu(sad->extPosition); eloc->partitionReferenceNum =3D iinfo->i_location.partitionReferenceNum; @@ -2234,17 +2243,17 @@ int8_t udf_current_aext(struct inode *inode, struct= extent_position *epos, case ICBTAG_FLAG_AD_LONG: lad =3D udf_get_filelongad(ptr, alen, &epos->offset, inc); if (!lad) - return -1; - etype =3D le32_to_cpu(lad->extLength) >> 30; + return -ENODATA; + *etype =3D le32_to_cpu(lad->extLength) >> 30; *eloc =3D lelb_to_cpu(lad->extLocation); *elen =3D le32_to_cpu(lad->extLength) & UDF_EXTENT_LENGTH_MASK; break; default: udf_debug("alloc_type =3D %u unsupported\n", iinfo->i_alloc_type); - return -1; + return -EINVAL; } =20 - return etype; + return 0; } =20 static int udf_insert_aext(struct inode *inode, struct extent_position epo= s, diff --git a/fs/udf/truncate.c b/fs/udf/truncate.c index a686c10fd709..91b6e2698e7e 100644 --- a/fs/udf/truncate.c +++ b/fs/udf/truncate.c @@ -217,8 +217,7 @@ int udf_truncate_extents(struct inode *inode) else lenalloc -=3D sizeof(struct allocExtDesc); =20 - while ((etype =3D udf_current_aext(inode, &epos, &eloc, - &elen, 0)) !=3D -1) { + while (!udf_current_aext(inode, &epos, &eloc, &elen, &etype, 0)) { if (etype =3D=3D (EXT_NEXT_EXTENT_ALLOCDESCS >> 30)) { udf_write_aext(inode, &epos, &neloc, nelen, 0); if (indirect_ext_len) { diff --git a/fs/udf/udfdecl.h b/fs/udf/udfdecl.h index 88692512a466..d893db95ac70 100644 --- a/fs/udf/udfdecl.h +++ b/fs/udf/udfdecl.h @@ -171,8 +171,9 @@ extern void udf_write_aext(struct inode *, struct exten= t_position *, extern int8_t udf_delete_aext(struct inode *, struct extent_position); extern int8_t udf_next_aext(struct inode *, struct extent_position *, struct kernel_lb_addr *, uint32_t *, int); -extern int8_t udf_current_aext(struct inode *, struct extent_position *, - struct kernel_lb_addr *, uint32_t *, int); +extern int udf_current_aext(struct inode *inode, struct extent_position *e= pos, + struct kernel_lb_addr *eloc, uint32_t *elen, + int8_t *etype, int inc); extern void udf_update_extra_perms(struct inode *inode, umode_t mode); =20 /* misc.c */ --=20 2.43.0 From nobody Fri Nov 29 14:52:51 2024 Received: from m16.mail.126.com (m16.mail.126.com [220.197.31.9]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 1718E175D54 for ; Wed, 18 Sep 2024 10:32:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=220.197.31.9 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726655542; cv=none; b=gUE8xHbZ+w7z4O3IuWOGVEQ5vpEMiYPho71fw5lBHE8sAJ8eZ6mlImnnFGcSxxft7oqx1xYYcId57DJ1vL0gI1A2F1YoDURlvL1qsu2wuInYwl+IcwpK16bN/fO1ZED0P65a6XaMpr7w5toEzpnQ6hao9faFWlP5Qv0Gi5S1kFk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726655542; c=relaxed/simple; bh=iEgFLG+KoHI4HRLF/CNf+jA0zaa1OKtL1Gvt8Zfn7pY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=EfNz/MLFmPe6IQCoLuy+JCo9OqwnGPE2TB5wijYmi/nzNdv32KjNnxj6Atd3z4CHfO8aycCJVHSUpcR8zEDpG2G9fghETFfKXw21xy6kSeraZqjJOM9ZRpvCCUZYHXw8BH+qiVOJ/LvGpEPS7ByfW8/puIWM/pcHhn/edprxM9U= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=126.com; spf=pass smtp.mailfrom=126.com; dkim=pass (1024-bit key) header.d=126.com header.i=@126.com header.b=mE33o964; arc=none smtp.client-ip=220.197.31.9 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=126.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=126.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=126.com header.i=@126.com header.b="mE33o964" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=126.com; s=s110527; h=From:Subject:Date:Message-ID:MIME-Version; bh=swiNN 3cyAG6SEu+a4uyrFOj0upovoKeCEUXK27Sc5WU=; b=mE33o964qHiRkN9TYST6Y xu4GaTHbvARIPr/71Y0moJH3SyUeukSaMbO1KroUZV2y7XoHYheaauAURwrqGvyc iBvFQgua/ERK+tTmU/wVJDN9AXLziG4DSrQYIIGrbZL1tAm9lBiKe0T3EncrwjGT cqf1aYtj3j9vcvESEo2Swc= Received: from localhost.localdomain (unknown [1.198.30.207]) by gzga-smtp-mta-g2-1 (Coremail) with SMTP id _____wDnLyAsn+pm2TCHAA--.46011S4; Wed, 18 Sep 2024 17:36:47 +0800 (CST) From: Zhao Mengmeng To: jack@suse.com, zhaomengmeng@kylinos.cn Cc: linux-kernel@vger.kernel.org Subject: [PATCH 2/3] udf: refactor udf_next_aext() to handle error Date: Wed, 18 Sep 2024 17:36:33 +0800 Message-ID: <20240918093634.12906-3-zhaomzhao@126.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240918093634.12906-1-zhaomzhao@126.com> References: <20240918093634.12906-1-zhaomzhao@126.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: _____wDnLyAsn+pm2TCHAA--.46011S4 X-Coremail-Antispam: 1Uf129KBjvJXoWfGrW5tryxJw1xtr4DGFyUZFb_yoWktr1Upr y7Kas7t343WFW7ur4Iqr4kZr1Sga97CF47Cr1Fq3s3tF40gr15tF1Fyry29F1UWrs5Ww4a qw4rK34qkw4xKrDanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDUYxBIdaVFxhVjvjDU0xZFpf9x07UI4EiUUUUU= X-CM-SenderInfo: 52kd0zp2kd0qqrswhudrp/1tbimh1ed2bqixWx0QAEsY Content-Type: text/plain; charset="utf-8" From: Zhao Mengmeng Same as udf_current_aext(), take pointer to etype to store the extent type, while return 0 for success and <0 on error. Signed-off-by: Zhao Mengmeng --- fs/udf/balloc.c | 6 +++--- fs/udf/directory.c | 7 +++++-- fs/udf/inode.c | 50 +++++++++++++++++++++++----------------------- fs/udf/super.c | 3 ++- fs/udf/truncate.c | 8 ++++---- fs/udf/udfdecl.h | 5 +++-- 6 files changed, 42 insertions(+), 37 deletions(-) diff --git a/fs/udf/balloc.c b/fs/udf/balloc.c index d8fc11765d61..b216c43cf433 100644 --- a/fs/udf/balloc.c +++ b/fs/udf/balloc.c @@ -384,7 +384,7 @@ static void udf_table_free_blocks(struct super_block *s= b, epos.bh =3D oepos.bh =3D NULL; =20 while (count && - (etype =3D udf_next_aext(table, &epos, &eloc, &elen, 1)) !=3D -1) { + !udf_next_aext(table, &epos, &eloc, &elen, &etype, 1)) { if (((eloc.logicalBlockNum + (elen >> sb->s_blocksize_bits)) =3D=3D start)) { if ((0x3FFFFFFF - elen) < @@ -517,7 +517,7 @@ static int udf_table_prealloc_blocks(struct super_block= *sb, eloc.logicalBlockNum =3D 0xFFFFFFFF; =20 while (first_block !=3D eloc.logicalBlockNum && - (etype =3D udf_next_aext(table, &epos, &eloc, &elen, 1)) !=3D -1) { + !udf_next_aext(table, &epos, &eloc, &elen, &etype, 1)) { udf_debug("eloc=3D%u, elen=3D%u, first_block=3D%u\n", eloc.logicalBlockNum, elen, first_block); ; /* empty loop body */ @@ -584,7 +584,7 @@ static udf_pblk_t udf_table_new_block(struct super_bloc= k *sb, epos.bh =3D goal_epos.bh =3D NULL; =20 while (spread && - (etype =3D udf_next_aext(table, &epos, &eloc, &elen, 1)) !=3D -1) { + !udf_next_aext(table, &epos, &eloc, &elen, &etype, 1)) { if (goal >=3D eloc.logicalBlockNum) { if (goal < eloc.logicalBlockNum + (elen >> sb->s_blocksize_bits)) diff --git a/fs/udf/directory.c b/fs/udf/directory.c index 93153665eb37..f865538c985d 100644 --- a/fs/udf/directory.c +++ b/fs/udf/directory.c @@ -166,13 +166,16 @@ static struct buffer_head *udf_fiiter_bread_blk(struc= t udf_fileident_iter *iter) */ static int udf_fiiter_advance_blk(struct udf_fileident_iter *iter) { + int8_t etype; + int err =3D 0; iter->loffset++; if (iter->loffset < DIV_ROUND_UP(iter->elen, 1<dir->i_blkbits)) return 0; =20 iter->loffset =3D 0; - if (udf_next_aext(iter->dir, &iter->epos, &iter->eloc, &iter->elen, 1) - !=3D (EXT_RECORDED_ALLOCATED >> 30)) { + err =3D udf_next_aext(iter->dir, &iter->epos, &iter->eloc, &iter->elen, + &etype, 1); + if (err || etype !=3D (EXT_RECORDED_ALLOCATED >> 30)) { if (iter->pos =3D=3D iter->dir->i_size) { iter->elen =3D 0; return 0; diff --git a/fs/udf/inode.c b/fs/udf/inode.c index 6d41ca0e7dba..ba980ce5e13a 100644 --- a/fs/udf/inode.c +++ b/fs/udf/inode.c @@ -545,6 +545,7 @@ static int udf_do_extend_file(struct inode *inode, } else { struct kernel_lb_addr tmploc; uint32_t tmplen; + int8_t tmptype; =20 udf_write_aext(inode, last_pos, &last_ext->extLocation, last_ext->extLength, 1); @@ -555,7 +556,7 @@ static int udf_do_extend_file(struct inode *inode, * empty indirect extent. */ if (new_block_bytes) - udf_next_aext(inode, last_pos, &tmploc, &tmplen, 0); + udf_next_aext(inode, last_pos, &tmploc, &tmplen, &tmptype, 0); } iinfo->i_lenExtents +=3D add; =20 @@ -674,8 +675,8 @@ static int udf_extend_file(struct inode *inode, loff_t = newsize) extent.extLength =3D EXT_NOT_RECORDED_NOT_ALLOCATED; } else { epos.offset -=3D adsize; - etype =3D udf_next_aext(inode, &epos, &extent.extLocation, - &extent.extLength, 0); + udf_next_aext(inode, &epos, &extent.extLocation, + &extent.extLength, &etype, 0); extent.extLength |=3D etype << 30; } =20 @@ -712,7 +713,7 @@ static int inode_getblk(struct inode *inode, struct udf= _map_rq *map) loff_t lbcount =3D 0, b_off =3D 0; udf_pblk_t newblocknum; sector_t offset =3D 0; - int8_t etype; + int8_t etype, tmpetype; struct udf_inode_info *iinfo =3D UDF_I(inode); udf_pblk_t goal =3D 0, pgoal =3D iinfo->i_location.logicalBlockNum; int lastblock =3D 0; @@ -748,8 +749,8 @@ static int inode_getblk(struct inode *inode, struct udf= _map_rq *map) prev_epos.offset =3D cur_epos.offset; cur_epos.offset =3D next_epos.offset; =20 - etype =3D udf_next_aext(inode, &next_epos, &eloc, &elen, 1); - if (etype =3D=3D -1) + ret =3D udf_next_aext(inode, &next_epos, &eloc, &elen, &etype, 1); + if (ret) break; =20 c =3D !c; @@ -771,8 +772,8 @@ static int inode_getblk(struct inode *inode, struct udf= _map_rq *map) * Move prev_epos and cur_epos into indirect extent if we are at * the pointer to it */ - udf_next_aext(inode, &prev_epos, &tmpeloc, &tmpelen, 0); - udf_next_aext(inode, &cur_epos, &tmpeloc, &tmpelen, 0); + udf_next_aext(inode, &prev_epos, &tmpeloc, &tmpelen, &tmpetype, 0); + udf_next_aext(inode, &cur_epos, &tmpeloc, &tmpelen, &tmpetype, 0); =20 /* if the extent is allocated and recorded, return the block if the extent is not a multiple of the blocksize, round up */ @@ -793,7 +794,7 @@ static int inode_getblk(struct inode *inode, struct udf= _map_rq *map) } =20 /* Are we beyond EOF and preallocated extent? */ - if (etype =3D=3D -1) { + if (ret < 0) { loff_t hole_len; =20 isBeyondEOF =3D true; @@ -846,8 +847,7 @@ static int inode_getblk(struct inode *inode, struct udf= _map_rq *map) =20 /* if the current block is located in an extent, read the next extent */ - etype =3D udf_next_aext(inode, &next_epos, &eloc, &elen, 0); - if (etype !=3D -1) { + if (!udf_next_aext(inode, &next_epos, &eloc, &elen, &etype, 0)) { laarr[c + 1].extLength =3D (etype << 30) | elen; laarr[c + 1].extLocation =3D eloc; count++; @@ -1172,6 +1172,7 @@ static int udf_update_extents(struct inode *inode, st= ruct kernel_long_ad *laarr, int start =3D 0, i; struct kernel_lb_addr tmploc; uint32_t tmplen; + int8_t tmptype; int err; =20 if (startnum > endnum) { @@ -1190,13 +1191,13 @@ static int udf_update_extents(struct inode *inode, = struct kernel_long_ad *laarr, if (err < 0) return err; udf_next_aext(inode, epos, &laarr[i].extLocation, - &laarr[i].extLength, 1); + &laarr[i].extLength, &tmptype, 1); start++; } } =20 for (i =3D start; i < endnum; i++) { - udf_next_aext(inode, epos, &tmploc, &tmplen, 0); + udf_next_aext(inode, epos, &tmploc, &tmplen, &tmptype, 0); udf_write_aext(inode, epos, &laarr[i].extLocation, laarr[i].extLength, 1); } @@ -2168,15 +2169,15 @@ void udf_write_aext(struct inode *inode, struct ext= ent_position *epos, */ #define UDF_MAX_INDIR_EXTS 16 =20 -int8_t udf_next_aext(struct inode *inode, struct extent_position *epos, - struct kernel_lb_addr *eloc, uint32_t *elen, int inc) +int udf_next_aext(struct inode *inode, struct extent_position *epos, + struct kernel_lb_addr *eloc, uint32_t *elen, int8_t *etype, + int inc) { - int8_t etype; unsigned int indirections =3D 0; int err =3D 0; =20 - while ((err =3D udf_current_aext(inode, epos, eloc, elen, &etype, inc))) { - if (err || etype !=3D (EXT_NEXT_EXTENT_ALLOCDESCS >> 30)) + while ((err =3D udf_current_aext(inode, epos, eloc, elen, etype, inc))) { + if (err || *etype !=3D (EXT_NEXT_EXTENT_ALLOCDESCS >> 30)) break; =20 udf_pblk_t block; @@ -2185,7 +2186,7 @@ int8_t udf_next_aext(struct inode *inode, struct exte= nt_position *epos, udf_err(inode->i_sb, "too many indirect extents in inode %lu\n", inode->i_ino); - return -1; + return -EFSCORRUPTED; } =20 epos->block =3D *eloc; @@ -2195,7 +2196,7 @@ int8_t udf_next_aext(struct inode *inode, struct exte= nt_position *epos, epos->bh =3D sb_bread(inode->i_sb, block); if (!epos->bh) { udf_debug("reading block %u failed!\n", block); - return -1; + return -EIO; } } =20 @@ -2267,7 +2268,7 @@ static int udf_insert_aext(struct inode *inode, struc= t extent_position epos, if (epos.bh) get_bh(epos.bh); =20 - while ((etype =3D udf_next_aext(inode, &epos, &oeloc, &oelen, 0)) !=3D -1= ) { + while (!udf_next_aext(inode, &epos, &oeloc, &oelen, &etype, 0)) { udf_write_aext(inode, &epos, &neloc, nelen, 1); neloc =3D oeloc; nelen =3D (etype << 30) | oelen; @@ -2302,10 +2303,10 @@ int8_t udf_delete_aext(struct inode *inode, struct = extent_position epos) adsize =3D 0; =20 oepos =3D epos; - if (udf_next_aext(inode, &epos, &eloc, &elen, 1) =3D=3D -1) + if (udf_next_aext(inode, &epos, &eloc, &elen, &etype, 1)) return -1; =20 - while ((etype =3D udf_next_aext(inode, &epos, &eloc, &elen, 1)) !=3D -1) { + while (!udf_next_aext(inode, &epos, &eloc, &elen, &etype, 1)) { udf_write_aext(inode, &oepos, &eloc, (etype << 30) | elen, 1); if (oepos.bh !=3D epos.bh) { oepos.block =3D epos.block; @@ -2379,8 +2380,7 @@ int8_t inode_bmap(struct inode *inode, sector_t block, } *elen =3D 0; do { - etype =3D udf_next_aext(inode, pos, eloc, elen, 1); - if (etype =3D=3D -1) { + if (udf_next_aext(inode, pos, eloc, elen, &etype, 1)) { *offset =3D (bcount - lbcount) >> blocksize_bits; iinfo->i_lenExtents =3D lbcount; return -1; diff --git a/fs/udf/super.c b/fs/udf/super.c index 3460ecc826d1..8c34224e1aee 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c @@ -2482,13 +2482,14 @@ static unsigned int udf_count_free_table(struct sup= er_block *sb, uint32_t elen; struct kernel_lb_addr eloc; struct extent_position epos; + int8_t etype; =20 mutex_lock(&UDF_SB(sb)->s_alloc_mutex); epos.block =3D UDF_I(table)->i_location; epos.offset =3D sizeof(struct unallocSpaceEntry); epos.bh =3D NULL; =20 - while (udf_next_aext(table, &epos, &eloc, &elen, 1) !=3D -1) + while (!udf_next_aext(table, &epos, &eloc, &elen, &etype, 1)) accum +=3D (elen >> table->i_sb->s_blocksize_bits); =20 brelse(epos.bh); diff --git a/fs/udf/truncate.c b/fs/udf/truncate.c index 91b6e2698e7e..b7361222f988 100644 --- a/fs/udf/truncate.c +++ b/fs/udf/truncate.c @@ -85,7 +85,7 @@ void udf_truncate_tail_extent(struct inode *inode) BUG(); =20 /* Find the last extent in the file */ - while ((netype =3D udf_next_aext(inode, &epos, &eloc, &elen, 1)) !=3D -1)= { + while (!udf_next_aext(inode, &epos, &eloc, &elen, &netype, 1)) { etype =3D netype; lbcount +=3D elen; if (lbcount > inode->i_size) { @@ -101,7 +101,7 @@ void udf_truncate_tail_extent(struct inode *inode) epos.offset -=3D adsize; extent_trunc(inode, &epos, &eloc, etype, elen, nelen); epos.offset +=3D adsize; - if (udf_next_aext(inode, &epos, &eloc, &elen, 1) !=3D -1) + if (!udf_next_aext(inode, &epos, &eloc, &elen, &netype, 1)) udf_err(inode->i_sb, "Extent after EOF in inode %u\n", (unsigned)inode->i_ino); @@ -132,13 +132,13 @@ void udf_discard_prealloc(struct inode *inode) epos.block =3D iinfo->i_location; =20 /* Find the last extent in the file */ - while (udf_next_aext(inode, &epos, &eloc, &elen, 0) !=3D -1) { + while (!udf_next_aext(inode, &epos, &eloc, &elen, &etype, 0)) { brelse(prev_epos.bh); prev_epos =3D epos; if (prev_epos.bh) get_bh(prev_epos.bh); =20 - etype =3D udf_next_aext(inode, &epos, &eloc, &elen, 1); + udf_next_aext(inode, &epos, &eloc, &elen, &etype, 1); lbcount +=3D elen; } if (etype =3D=3D (EXT_NOT_RECORDED_ALLOCATED >> 30)) { diff --git a/fs/udf/udfdecl.h b/fs/udf/udfdecl.h index d893db95ac70..5067ed68a8b4 100644 --- a/fs/udf/udfdecl.h +++ b/fs/udf/udfdecl.h @@ -169,8 +169,9 @@ extern int udf_add_aext(struct inode *, struct extent_p= osition *, extern void udf_write_aext(struct inode *, struct extent_position *, struct kernel_lb_addr *, uint32_t, int); extern int8_t udf_delete_aext(struct inode *, struct extent_position); -extern int8_t udf_next_aext(struct inode *, struct extent_position *, - struct kernel_lb_addr *, uint32_t *, int); +extern int udf_next_aext(struct inode *inode, struct extent_position *epos, + struct kernel_lb_addr *eloc, uint32_t *elen, + int8_t *etype, int inc); extern int udf_current_aext(struct inode *inode, struct extent_position *e= pos, struct kernel_lb_addr *eloc, uint32_t *elen, int8_t *etype, int inc); --=20 2.43.0 From nobody Fri Nov 29 14:52:51 2024 Received: from m16.mail.126.com (m16.mail.126.com [220.197.31.7]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 401C615C150 for ; Wed, 18 Sep 2024 09:41:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=220.197.31.7 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726652522; cv=none; b=ZvMDBVAxOC6/8IB57EpTxdEJ5s3acdcRtaKzzParAFrbWMslPu8lEU2ipZ+c8T9NMWyNOAmjXiW3eIU5hbhSEgx6x3q3mTeWIw4xNWXWqvBDnj7FhTiI8K39sB30J9HuT9IAYiCUhz/pFW1556ngXoF7++GiYGw7yYA8HmitUC0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726652522; c=relaxed/simple; bh=o2s2bG1SZhgxcuh4iQVSHqpNoiT8wFAGfCKoKy9QDEI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=J69u7QWvdHyQMzR20Pa0d1tgpTuVjgBpogEqTI/vPODQ+O47zvjxtjFQOuFtV7z8dZcZadNG0i4Q8gb6XQlZH9XCi/sfirokrUe3tFwYvqeyP/S9WbIgc/hgurI0Y7ASTW3sSUNcIbzRZ32kzzXqtKlZXsyHELgyrZ03J24c72E= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=126.com; spf=pass smtp.mailfrom=126.com; dkim=pass (1024-bit key) header.d=126.com header.i=@126.com header.b=CuqgpTzZ; arc=none smtp.client-ip=220.197.31.7 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=126.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=126.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=126.com header.i=@126.com header.b="CuqgpTzZ" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=126.com; s=s110527; h=From:Subject:Date:Message-ID:MIME-Version; bh=zr/// QynWF49C7UazH7BA3F6E/XqkNgjR8scwptDljA=; b=CuqgpTzZWvvWbphD0Cz6s iy/rUH0c7iZsC7WYY56P2qIHfNBzeAHYEz2cNkUF7hn0RPUEYjYVUj6Cq1m9M10u KfFJeLLISUyF97Q6vXlIlw86kFnSo/8Qkb/kUp6796wtt6mEC08f6lDYPGh4QHwi Zysb59scAwI41I3oUuL4ro= Received: from localhost.localdomain (unknown [1.198.30.207]) by gzga-smtp-mta-g2-1 (Coremail) with SMTP id _____wDnLyAsn+pm2TCHAA--.46011S5; Wed, 18 Sep 2024 17:36:50 +0800 (CST) From: Zhao Mengmeng To: jack@suse.com, zhaomengmeng@kylinos.cn Cc: linux-kernel@vger.kernel.org Subject: [PATCH 3/3] udf: refactor inode_bmap() to handle error Date: Wed, 18 Sep 2024 17:36:34 +0800 Message-ID: <20240918093634.12906-4-zhaomzhao@126.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240918093634.12906-1-zhaomzhao@126.com> References: <20240918093634.12906-1-zhaomzhao@126.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: _____wDnLyAsn+pm2TCHAA--.46011S5 X-Coremail-Antispam: 1Uf129KBjvJXoW3AFy3CrW8ZFy3ArW7ur43GFg_yoW3AFWkpr 9rKFyjkw4rXrWxWF4IqF1kZw1Sga92kr47GryIv34SyrWvgr1rKa40yry29F15KFs5Cw4a qa15K3yUuw17J3DanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDUYxBIdaVFxhVjvjDU0xZFpf9x07UpKZJUUUUU= X-CM-SenderInfo: 52kd0zp2kd0qqrswhudrp/1tbiEBded2bqmPlnEwAAs3 Content-Type: text/plain; charset="utf-8" From: Zhao Mengmeng Same as udf_current_aext(), take pointer to etype to store the extent type, while return 0 for success and <0 on error. On situations like ftruncate, udf_extend_file() can detect errors and bail out early without resorting to checking for particular offsets and assuming internal behavior of these functions. Reported-by: syzbot+7a4842f0b1801230a989@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=3D7a4842f0b1801230a989 Tested-by: syzbot+7a4842f0b1801230a989@syzkaller.appspotmail.com Signed-off-by: Zhao Mengmeng --- fs/udf/directory.c | 13 ++++++++----- fs/udf/inode.c | 31 ++++++++++++++++++++----------- fs/udf/partition.c | 6 ++++-- fs/udf/truncate.c | 5 +++-- fs/udf/udfdecl.h | 5 +++-- 5 files changed, 38 insertions(+), 22 deletions(-) diff --git a/fs/udf/directory.c b/fs/udf/directory.c index f865538c985d..cb40e1ade9f6 100644 --- a/fs/udf/directory.c +++ b/fs/udf/directory.c @@ -243,6 +243,7 @@ int udf_fiiter_init(struct udf_fileident_iter *iter, st= ruct inode *dir, { struct udf_inode_info *iinfo =3D UDF_I(dir); int err =3D 0; + int8_t etype; =20 iter->dir =3D dir; iter->bh[0] =3D iter->bh[1] =3D NULL; @@ -262,9 +263,9 @@ int udf_fiiter_init(struct udf_fileident_iter *iter, st= ruct inode *dir, goto out; } =20 - if (inode_bmap(dir, iter->pos >> dir->i_blkbits, &iter->epos, - &iter->eloc, &iter->elen, &iter->loffset) !=3D - (EXT_RECORDED_ALLOCATED >> 30)) { + err =3D inode_bmap(dir, iter->pos >> dir->i_blkbits, &iter->epos, &iter->= eloc, + &iter->elen, &iter->loffset, &etype); + if (err || etype !=3D (EXT_RECORDED_ALLOCATED >> 30)) { if (pos =3D=3D dir->i_size) return 0; udf_err(dir->i_sb, @@ -460,6 +461,7 @@ int udf_fiiter_append_blk(struct udf_fileident_iter *it= er) sector_t block; uint32_t old_elen =3D iter->elen; int err; + int8_t etype; =20 if (WARN_ON_ONCE(iinfo->i_alloc_type =3D=3D ICBTAG_FLAG_AD_IN_ICB)) return -EINVAL; @@ -474,8 +476,9 @@ int udf_fiiter_append_blk(struct udf_fileident_iter *it= er) udf_fiiter_update_elen(iter, old_elen); return err; } - if (inode_bmap(iter->dir, block, &iter->epos, &iter->eloc, &iter->elen, - &iter->loffset) !=3D (EXT_RECORDED_ALLOCATED >> 30)) { + err =3D inode_bmap(iter->dir, block, &iter->epos, &iter->eloc, &iter->ele= n, + &iter->loffset, &etype); + if (err || etype !=3D (EXT_RECORDED_ALLOCATED >> 30)) { udf_err(iter->dir->i_sb, "block %llu not allocated in directory (ino %lu)\n", (unsigned long long)block, iter->dir->i_ino); diff --git a/fs/udf/inode.c b/fs/udf/inode.c index ba980ce5e13a..f1b8f0a0d202 100644 --- a/fs/udf/inode.c +++ b/fs/udf/inode.c @@ -418,10 +418,11 @@ static int udf_map_block(struct inode *inode, struct = udf_map_rq *map) uint32_t elen; sector_t offset; struct extent_position epos =3D {}; + int8_t etype; =20 down_read(&iinfo->i_data_sem); - if (inode_bmap(inode, map->lblk, &epos, &eloc, &elen, &offset) - =3D=3D (EXT_RECORDED_ALLOCATED >> 30)) { + inode_bmap(inode, map->lblk, &epos, &eloc, &elen, &offset, &etype); + if (etype =3D=3D (EXT_RECORDED_ALLOCATED >> 30)) { map->pblk =3D udf_get_lb_pblock(inode->i_sb, &eloc, offset); map->oflags |=3D UDF_BLK_MAPPED; @@ -660,8 +661,10 @@ static int udf_extend_file(struct inode *inode, loff_t= newsize) */ udf_discard_prealloc(inode); =20 - etype =3D inode_bmap(inode, first_block, &epos, &eloc, &elen, &offset); - within_last_ext =3D (etype !=3D -1); + err =3D inode_bmap(inode, first_block, &epos, &eloc, &elen, &offset, &ety= pe); + if (err < 0 && err !=3D -ENODATA) + goto out; + within_last_ext =3D (!err); /* We don't expect extents past EOF... */ WARN_ON_ONCE(within_last_ext && elen > ((loff_t)offset + 1) << inode->i_blkbits); @@ -2363,14 +2366,19 @@ int8_t udf_delete_aext(struct inode *inode, struct = extent_position epos) return (elen >> 30); } =20 -int8_t inode_bmap(struct inode *inode, sector_t block, - struct extent_position *pos, struct kernel_lb_addr *eloc, - uint32_t *elen, sector_t *offset) +/* + * return 0 when iudf_next_aext() loop success. + * return err < 0 and err !=3D -ENODATA indicates error. + * return err =3D=3D -ENODATA indicates hit EOF. + */ +int inode_bmap(struct inode *inode, sector_t block, struct extent_position= *pos, + struct kernel_lb_addr *eloc, uint32_t *elen, sector_t *offset, + int8_t *etype) { unsigned char blocksize_bits =3D inode->i_sb->s_blocksize_bits; loff_t lbcount =3D 0, bcount =3D (loff_t) block << blocksize_bits; - int8_t etype; struct udf_inode_info *iinfo; + int err =3D 0; =20 iinfo =3D UDF_I(inode); if (!udf_read_extent_cache(inode, bcount, &lbcount, pos)) { @@ -2380,10 +2388,11 @@ int8_t inode_bmap(struct inode *inode, sector_t blo= ck, } *elen =3D 0; do { - if (udf_next_aext(inode, pos, eloc, elen, &etype, 1)) { + err =3D udf_next_aext(inode, pos, eloc, elen, etype, 1); + if (err < 0) { *offset =3D (bcount - lbcount) >> blocksize_bits; iinfo->i_lenExtents =3D lbcount; - return -1; + return err; } lbcount +=3D *elen; } while (lbcount <=3D bcount); @@ -2391,5 +2400,5 @@ int8_t inode_bmap(struct inode *inode, sector_t block, udf_update_extent_cache(inode, lbcount - *elen, pos); *offset =3D (bcount + *elen - lbcount) >> blocksize_bits; =20 - return etype; + return 0; } diff --git a/fs/udf/partition.c b/fs/udf/partition.c index af877991edc1..c441d4ae1f96 100644 --- a/fs/udf/partition.c +++ b/fs/udf/partition.c @@ -282,9 +282,11 @@ static uint32_t udf_try_read_meta(struct inode *inode,= uint32_t block, sector_t ext_offset; struct extent_position epos =3D {}; uint32_t phyblock; + int8_t etype; + int err =3D 0; =20 - if (inode_bmap(inode, block, &epos, &eloc, &elen, &ext_offset) !=3D - (EXT_RECORDED_ALLOCATED >> 30)) + err =3D inode_bmap(inode, block, &epos, &eloc, &elen, &ext_offset, &etype= ); + if (err || etype !=3D (EXT_RECORDED_ALLOCATED >> 30)) phyblock =3D 0xFFFFFFFF; else { map =3D &UDF_SB(sb)->s_partmaps[partition]; diff --git a/fs/udf/truncate.c b/fs/udf/truncate.c index b7361222f988..a70b6ae4ab8a 100644 --- a/fs/udf/truncate.c +++ b/fs/udf/truncate.c @@ -188,6 +188,7 @@ int udf_truncate_extents(struct inode *inode) loff_t byte_offset; int adsize; struct udf_inode_info *iinfo =3D UDF_I(inode); + int err =3D 0; =20 if (iinfo->i_alloc_type =3D=3D ICBTAG_FLAG_AD_SHORT) adsize =3D sizeof(struct short_ad); @@ -196,10 +197,10 @@ int udf_truncate_extents(struct inode *inode) else BUG(); =20 - etype =3D inode_bmap(inode, first_block, &epos, &eloc, &elen, &offset); + err =3D inode_bmap(inode, first_block, &epos, &eloc, &elen, &offset, &ety= pe); byte_offset =3D (offset << sb->s_blocksize_bits) + (inode->i_size & (sb->s_blocksize - 1)); - if (etype =3D=3D -1) { + if (err < 0) { /* We should extend the file? */ WARN_ON(byte_offset); return 0; diff --git a/fs/udf/udfdecl.h b/fs/udf/udfdecl.h index 5067ed68a8b4..d159f20d61e8 100644 --- a/fs/udf/udfdecl.h +++ b/fs/udf/udfdecl.h @@ -157,8 +157,9 @@ extern struct buffer_head *udf_bread(struct inode *inod= e, udf_pblk_t block, extern int udf_setsize(struct inode *, loff_t); extern void udf_evict_inode(struct inode *); extern int udf_write_inode(struct inode *, struct writeback_control *wbc); -extern int8_t inode_bmap(struct inode *, sector_t, struct extent_position = *, - struct kernel_lb_addr *, uint32_t *, sector_t *); +extern int inode_bmap(struct inode *inode, sector_t block, + struct extent_position *pos, struct kernel_lb_addr *eloc, + uint32_t *elen, sector_t *offset, int8_t *etype); int udf_get_block(struct inode *, sector_t, struct buffer_head *, int); extern int udf_setup_indirect_aext(struct inode *inode, udf_pblk_t block, struct extent_position *epos); --=20 2.43.0