1

udf: refactor udf_current_aext() to handle error

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
This commit is contained in:
Zhao Mengmeng 2024-10-01 19:54:23 +08:00 committed by Jan Kara
parent 9852d85ec9
commit ee703a7068
3 changed files with 37 additions and 18 deletions

View File

@ -1953,6 +1953,7 @@ int udf_setup_indirect_aext(struct inode *inode, udf_pblk_t block,
struct extent_position nepos; struct extent_position nepos;
struct kernel_lb_addr neloc; struct kernel_lb_addr neloc;
int ver, adsize; int ver, adsize;
int err = 0;
if (UDF_I(inode)->i_alloc_type == ICBTAG_FLAG_AD_SHORT) if (UDF_I(inode)->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
adsize = sizeof(struct short_ad); 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) { if (epos->offset + adsize > sb->s_blocksize) {
struct kernel_lb_addr cp_loc; struct kernel_lb_addr cp_loc;
uint32_t cp_len; uint32_t cp_len;
int cp_type; int8_t cp_type;
epos->offset -= adsize; 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; cp_len |= ((uint32_t)cp_type) << 30;
__udf_add_aext(inode, &nepos, &cp_loc, cp_len, 1); __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; *epos = nepos;
return 0; 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; int8_t etype;
unsigned int indirections = 0; unsigned int indirections = 0;
int ret = 0;
while ((etype = udf_current_aext(inode, epos, eloc, elen, inc)) == while ((ret = udf_current_aext(inode, epos, eloc, elen,
(EXT_NEXT_EXTENT_ALLOCDESCS >> 30)) { &etype, inc)) > 0) {
if (etype != (EXT_NEXT_EXTENT_ALLOCDESCS >> 30))
break;
udf_pblk_t block; udf_pblk_t block;
if (++indirections > UDF_MAX_INDIR_EXTS) { 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; int alen;
int8_t etype;
uint8_t *ptr; uint8_t *ptr;
struct short_ad *sad; struct short_ad *sad;
struct long_ad *lad; 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: case ICBTAG_FLAG_AD_SHORT:
sad = udf_get_fileshortad(ptr, alen, &epos->offset, inc); sad = udf_get_fileshortad(ptr, alen, &epos->offset, inc);
if (!sad) if (!sad)
return -1; return 0;
etype = le32_to_cpu(sad->extLength) >> 30; *etype = le32_to_cpu(sad->extLength) >> 30;
eloc->logicalBlockNum = le32_to_cpu(sad->extPosition); eloc->logicalBlockNum = le32_to_cpu(sad->extPosition);
eloc->partitionReferenceNum = eloc->partitionReferenceNum =
iinfo->i_location.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: case ICBTAG_FLAG_AD_LONG:
lad = udf_get_filelongad(ptr, alen, &epos->offset, inc); lad = udf_get_filelongad(ptr, alen, &epos->offset, inc);
if (!lad) if (!lad)
return -1; return 0;
etype = le32_to_cpu(lad->extLength) >> 30; *etype = le32_to_cpu(lad->extLength) >> 30;
*eloc = lelb_to_cpu(lad->extLocation); *eloc = lelb_to_cpu(lad->extLocation);
*elen = le32_to_cpu(lad->extLength) & UDF_EXTENT_LENGTH_MASK; *elen = le32_to_cpu(lad->extLength) & UDF_EXTENT_LENGTH_MASK;
break; break;
default: default:
udf_debug("alloc_type = %u unsupported\n", iinfo->i_alloc_type); 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, static int udf_insert_aext(struct inode *inode, struct extent_position epos,

View File

@ -188,6 +188,7 @@ int udf_truncate_extents(struct inode *inode)
loff_t byte_offset; loff_t byte_offset;
int adsize; int adsize;
struct udf_inode_info *iinfo = UDF_I(inode); struct udf_inode_info *iinfo = UDF_I(inode);
int ret = 0;
if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
adsize = sizeof(struct short_ad); adsize = sizeof(struct short_ad);
@ -217,8 +218,8 @@ int udf_truncate_extents(struct inode *inode)
else else
lenalloc -= sizeof(struct allocExtDesc); lenalloc -= sizeof(struct allocExtDesc);
while ((etype = udf_current_aext(inode, &epos, &eloc, while ((ret = udf_current_aext(inode, &epos, &eloc,
&elen, 0)) != -1) { &elen, &etype, 0)) > 0) {
if (etype == (EXT_NEXT_EXTENT_ALLOCDESCS >> 30)) { if (etype == (EXT_NEXT_EXTENT_ALLOCDESCS >> 30)) {
udf_write_aext(inode, &epos, &neloc, nelen, 0); udf_write_aext(inode, &epos, &neloc, nelen, 0);
if (indirect_ext_len) { 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) { if (indirect_ext_len) {
BUG_ON(!epos.bh); BUG_ON(!epos.bh);
udf_free_blocks(sb, NULL, &epos.block, 0, indirect_ext_len); udf_free_blocks(sb, NULL, &epos.block, 0, indirect_ext_len);

View 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_delete_aext(struct inode *, struct extent_position);
extern int8_t udf_next_aext(struct inode *, struct extent_position *, extern int8_t udf_next_aext(struct inode *, struct extent_position *,
struct kernel_lb_addr *, uint32_t *, int); struct kernel_lb_addr *, uint32_t *, int);
extern int8_t udf_current_aext(struct inode *, struct extent_position *, extern int udf_current_aext(struct inode *inode, struct extent_position *epos,
struct kernel_lb_addr *, uint32_t *, int); 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); extern void udf_update_extra_perms(struct inode *inode, umode_t mode);
/* misc.c */ /* misc.c */