+++ /dev/null
-From 29a1ad6e9d5f6e43b6d735f0c4c6074d789db03b Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Tue, 1 Oct 2024 19:54:23 +0800
-Subject: udf: refactor udf_current_aext() to handle error
-
-From: Zhao Mengmeng <zhaomengmeng@kylinos.cn>
-
-[ Upstream commit ee703a7068f95764cfb62b57db1d36e465cb9b26 ]
-
-As Jan suggested in links below, refactor udf_current_aext() to
-differentiate between error, hit EOF and success, it now takes pointer to
-etype to store the extent type, return 1 when getting etype success,
-return 0 when hitting EOF and return -errno when err.
-
-Link: https://lore.kernel.org/all/20240912111235.6nr3wuqvktecy3vh@quack3/
-Signed-off-by: Zhao Mengmeng <zhaomengmeng@kylinos.cn>
-Suggested-by: Jan Kara <jack@suse.cz>
-Signed-off-by: Jan Kara <jack@suse.cz>
-Link: https://patch.msgid.link/20241001115425.266556-2-zhaomzhao@126.com
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- fs/udf/inode.c | 40 ++++++++++++++++++++++++++--------------
- fs/udf/truncate.c | 10 ++++++++--
- fs/udf/udfdecl.h | 5 +++--
- 3 files changed, 37 insertions(+), 18 deletions(-)
-
-diff --git a/fs/udf/inode.c b/fs/udf/inode.c
-index e68490991f5c6..443d747bcec2e 100644
---- a/fs/udf/inode.c
-+++ b/fs/udf/inode.c
-@@ -1843,6 +1843,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 = 0;
-
- if (UDF_I(inode)->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
- adsize = sizeof(struct short_ad);
-@@ -1887,10 +1888,12 @@ int udf_setup_indirect_aext(struct inode *inode, udf_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;
-
- epos->offset -= adsize;
-- cp_type = udf_current_aext(inode, epos, &cp_loc, &cp_len, 0);
-+ err = udf_current_aext(inode, epos, &cp_loc, &cp_len, &cp_type, 0);
-+ if (err <= 0)
-+ goto err_out;
- cp_len |= ((uint32_t)cp_type) << 30;
-
- __udf_add_aext(inode, &nepos, &cp_loc, cp_len, 1);
-@@ -1905,6 +1908,9 @@ int udf_setup_indirect_aext(struct inode *inode, udf_pblk_t block,
- *epos = nepos;
-
- return 0;
-+err_out:
-+ brelse(bh);
-+ return err;
- }
-
- /*
-@@ -2055,9 +2061,12 @@ int8_t udf_next_aext(struct inode *inode, struct extent_position *epos,
- {
- int8_t etype;
- unsigned int indirections = 0;
-+ int ret = 0;
-
-- while ((etype = udf_current_aext(inode, epos, eloc, elen, inc)) ==
-- (EXT_NEXT_EXTENT_ALLOCDESCS >> 30)) {
-+ while ((ret = udf_current_aext(inode, epos, eloc, elen,
-+ &etype, inc)) > 0) {
-+ if (etype != (EXT_NEXT_EXTENT_ALLOCDESCS >> 30))
-+ break;
- udf_pblk_t block;
-
- if (++indirections > UDF_MAX_INDIR_EXTS) {
-@@ -2078,14 +2087,17 @@ int8_t udf_next_aext(struct inode *inode, struct extent_position *epos,
- }
- }
-
-- return etype;
-+ return ret > 0 ? etype : -1;
- }
-
--int8_t udf_current_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_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;
-@@ -2112,8 +2124,8 @@ int8_t udf_current_aext(struct inode *inode, struct extent_position *epos,
- case ICBTAG_FLAG_AD_SHORT:
- sad = udf_get_fileshortad(ptr, alen, &epos->offset, inc);
- if (!sad)
-- return -1;
-- etype = le32_to_cpu(sad->extLength) >> 30;
-+ return 0;
-+ *etype = le32_to_cpu(sad->extLength) >> 30;
- eloc->logicalBlockNum = le32_to_cpu(sad->extPosition);
- eloc->partitionReferenceNum =
- iinfo->i_location.partitionReferenceNum;
-@@ -2122,17 +2134,17 @@ int8_t udf_current_aext(struct inode *inode, struct extent_position *epos,
- case ICBTAG_FLAG_AD_LONG:
- lad = udf_get_filelongad(ptr, alen, &epos->offset, inc);
- if (!lad)
-- return -1;
-- etype = le32_to_cpu(lad->extLength) >> 30;
-+ return 0;
-+ *etype = le32_to_cpu(lad->extLength) >> 30;
- *eloc = lelb_to_cpu(lad->extLocation);
- *elen = le32_to_cpu(lad->extLength) & UDF_EXTENT_LENGTH_MASK;
- break;
- default:
- udf_debug("alloc_type = %u unsupported\n", iinfo->i_alloc_type);
-- return -1;
-+ return -EINVAL;
- }
-
-- return etype;
-+ return 1;
- }
-
- static int udf_insert_aext(struct inode *inode, struct extent_position epos,
-diff --git a/fs/udf/truncate.c b/fs/udf/truncate.c
-index 036ebd892b852..f0de6e106ce65 100644
---- a/fs/udf/truncate.c
-+++ b/fs/udf/truncate.c
-@@ -192,6 +192,7 @@ int udf_truncate_extents(struct inode *inode)
- loff_t byte_offset;
- int adsize;
- struct udf_inode_info *iinfo = UDF_I(inode);
-+ int ret = 0;
-
- if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
- adsize = sizeof(struct short_ad);
-@@ -221,8 +222,8 @@ int udf_truncate_extents(struct inode *inode)
- else
- lenalloc -= sizeof(struct allocExtDesc);
-
-- while ((etype = udf_current_aext(inode, &epos, &eloc,
-- &elen, 0)) != -1) {
-+ while ((ret = udf_current_aext(inode, &epos, &eloc,
-+ &elen, &etype, 0)) > 0) {
- if (etype == (EXT_NEXT_EXTENT_ALLOCDESCS >> 30)) {
- udf_write_aext(inode, &epos, &neloc, nelen, 0);
- if (indirect_ext_len) {
-@@ -257,6 +258,11 @@ int udf_truncate_extents(struct inode *inode)
- }
- }
-
-+ if (ret < 0) {
-+ brelse(epos.bh);
-+ return ret;
-+ }
-+
- if (indirect_ext_len) {
- BUG_ON(!epos.bh);
- udf_free_blocks(sb, NULL, &epos.block, 0, indirect_ext_len);
-diff --git a/fs/udf/udfdecl.h b/fs/udf/udfdecl.h
-index f764b4d15094d..aa0e17d81b06e 100644
---- a/fs/udf/udfdecl.h
-+++ b/fs/udf/udfdecl.h
-@@ -174,8 +174,9 @@ extern void udf_write_aext(struct inode *, struct extent_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 *epos,
-+ 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);
-
- /* misc.c */
---
-2.43.0
-