]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
udf: refactor udf_current_aext() to handle error
authorZhao Mengmeng <zhaomengmeng@kylinos.cn>
Tue, 1 Oct 2024 11:54:23 +0000 (19:54 +0800)
committerJan Kara <jack@suse.cz>
Wed, 2 Oct 2024 10:37:01 +0000 (12:37 +0200)
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
fs/udf/inode.c
fs/udf/truncate.c
fs/udf/udfdecl.h

index eaee57b91c6c6a82c9718d7658c0206d3a907e6c..295145b583b4432421bdd121c0bc7bf42c78cdd0 100644 (file)
@@ -1953,6 +1953,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);
@@ -1997,10 +1998,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);
@@ -2015,6 +2018,9 @@ int udf_setup_indirect_aext(struct inode *inode, udf_pblk_t block,
        *epos = nepos;
 
        return 0;
+err_out:
+       brelse(bh);
+       return err;
 }
 
 /*
@@ -2165,9 +2171,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) {
@@ -2188,14 +2197,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;
@@ -2222,8 +2234,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;
@@ -2232,17 +2244,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,
index a686c10fd709d18f5ba5842e4fa5b0b96a5cd29d..4758ba7b5f51c5729b305264ae5aec0fc8f8807d 100644 (file)
@@ -188,6 +188,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);
@@ -217,8 +218,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) {
@@ -253,6 +254,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);
index 88692512a466871409e861dd9daaf60488a18bee..d893db95ac70efb1b700d6078220976fac71b4a1 100644 (file)
@@ -171,8 +171,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 */