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:
parent
9852d85ec9
commit
ee703a7068
@ -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,
|
||||||
|
@ -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);
|
||||||
|
@ -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 */
|
||||||
|
Loading…
Reference in New Issue
Block a user