From nobody Thu Nov 28 14:51:48 2024 Received: from m16.mail.126.com (m16.mail.126.com [117.135.210.9]) by smtp.subspace.kernel.org (Postfix) with ESMTP id ED1CB1C1ACF for ; Tue, 1 Oct 2024 11:57:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=117.135.210.9 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727783840; cv=none; b=melK78J/WOopAIpxrZfBItiMnmkekqE04XHWUlMTSZROXJMnffHD+EjMDgQpfPBq+SoE7a27ahY1XZKCi+oAgKwWJ3uQTfPdBvO3wCINCl5/s+Cn4InsAfI1HIGD4ChEZRqF9X1yevBOKVQkQuIeYPy2zq+wWJOkvZNuYFNhEYo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727783840; c=relaxed/simple; bh=2Z9PVmNg/tmv3AYSNZB8QI2JRp2QbWtgYO5ajVK/LRU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=WjKm2/ess4bP8rVni7QU4CeKYS+UcK7gaASzajkd510WQYdIF3UD5LXbJKIDHRENDDJ5mIEnZJAh+lPofgiNEOUKTLUOpmskXskADlCU9d5yEGwfphhIWOso0ibtlTejNOLapTU+Oxv7WmjQtlYSRNmiNyRMpyi99BFrHq0aIlc= 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=RnIZiTpb; arc=none smtp.client-ip=117.135.210.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="RnIZiTpb" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=126.com; s=s110527; h=From:Subject:Date:Message-ID:MIME-Version; bh=xLJEZ i+6vv8jpgVYUKMt79L7sgztdS3mDzDAP7hCxqI=; b=RnIZiTpbaRqhgvBVdvK4d DT9Lq7N8FgJ8L3B2Hc/vol8umdiKAQGAVJAxPlStCENYpgNmZXxF8T4lr6I49F1X yMh53O0R5aOG146INhcKNTRxahmj7p7hJO6IaoSIxGpmfycBO3CCBIxywMoRGI3y kte8kbDSPVPU4oUapyPDmI= Received: from localhost.localdomain (unknown [39.162.142.163]) by gzga-smtp-mtada-g1-2 (Coremail) with SMTP id _____wD33yf24vtm4rdrAA--.18425S4; Tue, 01 Oct 2024 19:54:31 +0800 (CST) From: Zhao Mengmeng To: jack@suse.com, zhaomengmeng@kylinos.cn Cc: linux-kernel@vger.kernel.org Subject: [PATCH v3 2/3] udf: refactor udf_next_aext() to handle error Date: Tue, 1 Oct 2024 19:54:24 +0800 Message-ID: <20241001115425.266556-3-zhaomzhao@126.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241001115425.266556-1-zhaomzhao@126.com> References: <20241001115425.266556-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: _____wD33yf24vtm4rdrAA--.18425S4 X-Coremail-Antispam: 1Uf129KBjvAXoWfJr4fJF4fZw1DJFyxXw1fZwb_yoW8AFWkuo W5Aan8K3Z5XrWfAFW8C348tFyUZ39aka1xJr1Uur909w1xG3y5XwnIg3W5Zay7WrW0grWk Z34xWw45JF4kCrs8n29KB7ZKAUJUUUU8529EdanIXcx71UUUUU7v73VFW2AGmfu7bjvjm3 AaLaJ3UbIYCTnIWIevJa73UjIFyTuYvjxU0xR6DUUUU X-CM-SenderInfo: 52kd0zp2kd0qqrswhudrp/1tbimgZrd2b74GcXdQABs5 Content-Type: text/plain; charset="utf-8" From: Zhao Mengmeng Since udf_current_aext() has error handling, udf_next_aext() should have error handling too. Besides, when too many indirect extents found in one inode, return -EFSCORRUPTED; when reading block failed, return -EIO. Signed-off-by: Zhao Mengmeng Suggested-by: Jan Kara --- fs/udf/balloc.c | 27 ++++++++---- fs/udf/directory.c | 10 ++++- fs/udf/inode.c | 108 ++++++++++++++++++++++++++++++--------------- fs/udf/super.c | 3 +- fs/udf/truncate.c | 25 ++++++++--- fs/udf/udfdecl.h | 5 ++- 6 files changed, 122 insertions(+), 56 deletions(-) diff --git a/fs/udf/balloc.c b/fs/udf/balloc.c index d8fc11765d61..efa110545e59 100644 --- a/fs/udf/balloc.c +++ b/fs/udf/balloc.c @@ -370,6 +370,7 @@ static void udf_table_free_blocks(struct super_block *s= b, struct extent_position oepos, epos; int8_t etype; struct udf_inode_info *iinfo; + int err =3D 0; =20 mutex_lock(&sbi->s_alloc_mutex); iinfo =3D UDF_I(table); @@ -383,8 +384,8 @@ static void udf_table_free_blocks(struct super_block *s= b, epos.block =3D oepos.block =3D iinfo->i_location; epos.bh =3D oepos.bh =3D NULL; =20 - while (count && - (etype =3D udf_next_aext(table, &epos, &eloc, &elen, 1)) !=3D -1) { + while (count && ((err =3D udf_next_aext(table, &epos, &eloc, &elen, + &etype, 1)) =3D=3D 1)) { if (((eloc.logicalBlockNum + (elen >> sb->s_blocksize_bits)) =3D=3D start)) { if ((0x3FFFFFFF - elen) < @@ -435,6 +436,9 @@ static void udf_table_free_blocks(struct super_block *s= b, } } =20 + if (err < 0) + goto error_return; + if (count) { /* * NOTE: we CANNOT use udf_add_aext here, as it can try to @@ -460,8 +464,6 @@ static void udf_table_free_blocks(struct super_block *s= b, else if (iinfo->i_alloc_type =3D=3D ICBTAG_FLAG_AD_LONG) adsize =3D sizeof(struct long_ad); else { - brelse(oepos.bh); - brelse(epos.bh); goto error_return; } =20 @@ -479,10 +481,10 @@ static void udf_table_free_blocks(struct super_block = *sb, __udf_add_aext(table, &epos, &eloc, elen, 1); } =20 +error_return: brelse(epos.bh); brelse(oepos.bh); =20 -error_return: mutex_unlock(&sbi->s_alloc_mutex); return; } @@ -498,6 +500,7 @@ static int udf_table_prealloc_blocks(struct super_block= *sb, struct extent_position epos; int8_t etype =3D -1; struct udf_inode_info *iinfo; + int err =3D 0; =20 if (first_block >=3D sbi->s_partmaps[partition].s_partition_len) return 0; @@ -517,12 +520,16 @@ static int udf_table_prealloc_blocks(struct super_blo= ck *sb, eloc.logicalBlockNum =3D 0xFFFFFFFF; =20 while (first_block !=3D eloc.logicalBlockNum && - (etype =3D udf_next_aext(table, &epos, &eloc, &elen, 1)) !=3D -1) { + (err =3D udf_next_aext(table, &epos, &eloc, + &elen, &etype, 1)) =3D=3D 1) { udf_debug("eloc=3D%u, elen=3D%u, first_block=3D%u\n", eloc.logicalBlockNum, elen, first_block); ; /* empty loop body */ } =20 + if (err < 0) + goto err_out; + if (first_block =3D=3D eloc.logicalBlockNum) { epos.offset -=3D adsize; =20 @@ -539,6 +546,7 @@ static int udf_table_prealloc_blocks(struct super_block= *sb, alloc_count =3D 0; } =20 +err_out: brelse(epos.bh); =20 if (alloc_count) @@ -560,6 +568,7 @@ static udf_pblk_t udf_table_new_block(struct super_bloc= k *sb, struct extent_position epos, goal_epos; int8_t etype; struct udf_inode_info *iinfo =3D UDF_I(table); + int ret =3D 0; =20 *err =3D -ENOSPC; =20 @@ -583,8 +592,8 @@ static udf_pblk_t udf_table_new_block(struct super_bloc= k *sb, epos.block =3D iinfo->i_location; epos.bh =3D goal_epos.bh =3D NULL; =20 - while (spread && - (etype =3D udf_next_aext(table, &epos, &eloc, &elen, 1)) !=3D -1) { + while (spread && (ret =3D udf_next_aext(table, &epos, &eloc, &elen, + &etype, 1)) =3D=3D 1) { if (goal >=3D eloc.logicalBlockNum) { if (goal < eloc.logicalBlockNum + (elen >> sb->s_blocksize_bits)) @@ -612,7 +621,7 @@ static udf_pblk_t udf_table_new_block(struct super_bloc= k *sb, =20 brelse(epos.bh); =20 - if (spread =3D=3D 0xFFFFFFFF) { + if (ret < 0 || spread =3D=3D 0xFFFFFFFF) { brelse(goal_epos.bh); mutex_unlock(&sbi->s_alloc_mutex); return 0; diff --git a/fs/udf/directory.c b/fs/udf/directory.c index 93153665eb37..c6950050e7ae 100644 --- a/fs/udf/directory.c +++ b/fs/udf/directory.c @@ -166,13 +166,19 @@ 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 =3D -1; + 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 < 0) + return err; + else if (err =3D=3D 0 || 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 70a27d2bfd29..84093f9c71c7 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); @@ -554,8 +555,12 @@ 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) - udf_next_aext(inode, last_pos, &tmploc, &tmplen, 0); + if (new_block_bytes) { + err =3D udf_next_aext(inode, last_pos, &tmploc, &tmplen, + &tmptype, 0); + if (err < 0) + goto out_err; + } } iinfo->i_lenExtents +=3D add; =20 @@ -674,8 +679,10 @@ 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); + err =3D udf_next_aext(inode, &epos, &extent.extLocation, + &extent.extLength, &etype, 0); + if (err !=3D 1) + goto out; extent.extLength |=3D etype << 30; } =20 @@ -712,11 +719,11 @@ static int inode_getblk(struct inode *inode, struct u= df_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; - bool isBeyondEOF; + bool isBeyondEOF =3D false; int ret =3D 0; =20 prev_epos.offset =3D udf_file_entry_alloc_offset(inode); @@ -748,9 +755,13 @@ static int inode_getblk(struct inode *inode, struct ud= f_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 < 0) + goto out_free; + else if (ret =3D=3D 0) { + isBeyondEOF =3D true; break; + } =20 c =3D !c; =20 @@ -771,13 +782,17 @@ static int inode_getblk(struct inode *inode, struct u= df_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); + if (udf_next_aext(inode, &prev_epos, &tmpeloc, + &tmpelen, &tmpetype, 0) < 0) + goto out_free; + if (udf_next_aext(inode, &cur_epos, &tmpeloc, + &tmpelen, &tmpetype, 0) < 0) + goto out_free; =20 /* if the extent is allocated and recorded, return the block if the extent is not a multiple of the blocksize, round up */ =20 - if (etype =3D=3D (EXT_RECORDED_ALLOCATED >> 30)) { + if (ret =3D=3D 1 && etype =3D=3D (EXT_RECORDED_ALLOCATED >> 30)) { if (elen & (inode->i_sb->s_blocksize - 1)) { elen =3D EXT_RECORDED_ALLOCATED | ((elen + inode->i_sb->s_blocksize - 1) & @@ -793,10 +808,9 @@ static int inode_getblk(struct inode *inode, struct ud= f_map_rq *map) } =20 /* Are we beyond EOF and preallocated extent? */ - if (etype =3D=3D -1) { + if (isBeyondEOF) { loff_t hole_len; =20 - isBeyondEOF =3D true; if (count) { if (c) laarr[0] =3D laarr[1]; @@ -832,7 +846,6 @@ static int inode_getblk(struct inode *inode, struct udf= _map_rq *map) endnum =3D c + 1; lastblock =3D 1; } else { - isBeyondEOF =3D false; endnum =3D startnum =3D ((count > 2) ? 2 : count); =20 /* if the current extent is in position 0, @@ -846,15 +859,17 @@ static int inode_getblk(struct inode *inode, struct u= df_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) { + ret =3D udf_next_aext(inode, &next_epos, &eloc, &elen, &etype, 0); + if (ret =3D=3D 1) { laarr[c + 1].extLength =3D (etype << 30) | elen; laarr[c + 1].extLocation =3D eloc; count++; startnum++; endnum++; - } else + } else if (ret =3D=3D 0) lastblock =3D 1; + else + goto out_free; } =20 /* if the current extent is not recorded but allocated, get the @@ -1172,6 +1187,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 tmpetype; int err; =20 if (startnum > endnum) { @@ -1189,14 +1205,19 @@ 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); + err =3D udf_next_aext(inode, epos, &laarr[i].extLocation, + &laarr[i].extLength, &tmpetype, 1); + if (err < 0) + return err; start++; } } =20 for (i =3D start; i < endnum; i++) { - udf_next_aext(inode, epos, &tmploc, &tmplen, 0); + err =3D udf_next_aext(inode, epos, &tmploc, &tmplen, &tmpetype, 0); + if (err < 0) + return err; + udf_write_aext(inode, epos, &laarr[i].extLocation, laarr[i].extLength, 1); } @@ -2168,16 +2189,19 @@ 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) +/* + * Returns 1 on success, -errno on error, 0 on hit EOF. + */ +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)) =3D=3D 1) { - if (etype !=3D (EXT_NEXT_EXTENT_ALLOCDESCS >> 30)) + etype, inc)) =3D=3D 1) { + if (*etype !=3D (EXT_NEXT_EXTENT_ALLOCDESCS >> 30)) break; udf_pblk_t block; =20 @@ -2185,7 +2209,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,11 +2219,11 @@ int8_t udf_next_aext(struct inode *inode, struct ex= tent_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 - return err =3D=3D 1 ? etype : -1; + return err; } =20 /* @@ -2270,12 +2294,14 @@ static int udf_insert_aext(struct inode *inode, str= uct 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 ((err =3D udf_next_aext(inode, &epos, &oeloc, + &oelen, &etype, 0)) =3D=3D 1) { udf_write_aext(inode, &epos, &neloc, nelen, 1); neloc =3D oeloc; nelen =3D (etype << 30) | oelen; } - err =3D udf_add_aext(inode, &epos, &neloc, nelen, 1); + if (err =3D=3D 0) + err =3D udf_add_aext(inode, &epos, &neloc, nelen, 1); brelse(epos.bh); =20 return err; @@ -2290,6 +2316,7 @@ int8_t udf_delete_aext(struct inode *inode, struct ex= tent_position epos) struct udf_inode_info *iinfo; struct kernel_lb_addr eloc; uint32_t elen; + int err =3D 0; =20 if (epos.bh) { get_bh(epos.bh); @@ -2305,10 +2332,11 @@ 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) <=3D 0) return -1; =20 - while ((etype =3D udf_next_aext(inode, &epos, &eloc, &elen, 1)) !=3D -1) { + while ((err =3D udf_next_aext(inode, &epos, &eloc, + &elen, &etype, 1)) =3D=3D 1) { udf_write_aext(inode, &oepos, &eloc, (etype << 30) | elen, 1); if (oepos.bh !=3D epos.bh) { oepos.block =3D epos.block; @@ -2318,6 +2346,11 @@ int8_t udf_delete_aext(struct inode *inode, struct e= xtent_position epos) oepos.offset =3D epos.offset - adsize; } } + if (err < 0) { + brelse(epos.bh); + brelse(oepos.bh); + return -1; + } memset(&eloc, 0x00, sizeof(struct kernel_lb_addr)); elen =3D 0; =20 @@ -2373,6 +2406,7 @@ int8_t inode_bmap(struct inode *inode, sector_t block, 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)) { @@ -2382,10 +2416,12 @@ int8_t inode_bmap(struct inode *inode, sector_t blo= ck, } *elen =3D 0; do { - etype =3D udf_next_aext(inode, pos, eloc, elen, 1); - if (etype =3D=3D -1) { - *offset =3D (bcount - lbcount) >> blocksize_bits; - iinfo->i_lenExtents =3D lbcount; + err =3D udf_next_aext(inode, pos, eloc, elen, &etype, 1); + if (err <=3D 0) { + if (err =3D=3D 0) { + *offset =3D (bcount - lbcount) >> blocksize_bits; + iinfo->i_lenExtents =3D lbcount; + } return -1; } lbcount +=3D *elen; diff --git a/fs/udf/super.c b/fs/udf/super.c index 3460ecc826d1..4bb7f600b99f 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) =3D=3D 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 76186b211efe..b91876a7b53a 100644 --- a/fs/udf/truncate.c +++ b/fs/udf/truncate.c @@ -69,6 +69,7 @@ void udf_truncate_tail_extent(struct inode *inode) int8_t etype =3D -1, netype; 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_IN_ICB || inode->i_size =3D=3D iinfo->i_lenExtents) @@ -85,7 +86,8 @@ 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 ((err =3D udf_next_aext(inode, &epos, &eloc, + &elen, &netype, 1)) =3D=3D 1) { etype =3D netype; lbcount +=3D elen; if (lbcount > inode->i_size) { @@ -101,7 +103,8 @@ 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) =3D=3D 1) udf_err(inode->i_sb, "Extent after EOF in inode %u\n", (unsigned)inode->i_ino); @@ -110,7 +113,8 @@ void udf_truncate_tail_extent(struct inode *inode) } /* This inode entry is in-memory only and thus we don't have to mark * the inode dirty */ - iinfo->i_lenExtents =3D inode->i_size; + if (err =3D=3D 0) + iinfo->i_lenExtents =3D inode->i_size; brelse(epos.bh); } =20 @@ -124,6 +128,8 @@ void udf_discard_prealloc(struct inode *inode) int8_t etype =3D -1; struct udf_inode_info *iinfo =3D UDF_I(inode); int bsize =3D i_blocksize(inode); + int8_t tmpetype =3D -1; + int err =3D 0; =20 if (iinfo->i_alloc_type =3D=3D ICBTAG_FLAG_AD_IN_ICB || ALIGN(inode->i_size, bsize) =3D=3D ALIGN(iinfo->i_lenExtents, bsize)) @@ -132,16 +138,22 @@ 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 ((err =3D udf_next_aext(inode, &epos, &eloc, + &elen, &tmpetype, 0)) =3D=3D 1) { 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); + err =3D udf_next_aext(inode, &epos, &eloc, &elen, &etype, 1); + if (err <=3D 0) + break; lbcount +=3D elen; } - if (etype =3D=3D (EXT_NOT_RECORDED_ALLOCATED >> 30)) { + if (err < 0) + goto out; + + if (err =3D=3D 1 && etype =3D=3D (EXT_NOT_RECORDED_ALLOCATED >> 30)) { lbcount -=3D elen; udf_delete_aext(inode, prev_epos); udf_free_blocks(inode->i_sb, inode, &eloc, 0, @@ -150,6 +162,7 @@ void udf_discard_prealloc(struct inode *inode) /* This inode entry is in-memory only and thus we don't have to mark * the inode dirty */ iinfo->i_lenExtents =3D lbcount; +out: brelse(epos.bh); brelse(prev_epos.bh); } 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