Commit ee703a70 authored by Zhao Mengmeng's avatar Zhao Mengmeng Committed by Jan Kara
Browse files

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: default avatarZhao Mengmeng <zhaomengmeng@kylinos.cn>
Suggested-by: default avatarJan Kara <jack@suse.cz>
Signed-off-by: default avatarJan Kara <jack@suse.cz>
Link: https://patch.msgid.link/20241001115425.266556-2-zhaomzhao@126.com
parent 9852d85e
Loading
Loading
Loading
Loading
+26 −14
Original line number Diff line number Diff line
@@ -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,
+8 −2
Original line number Diff line number Diff line
@@ -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);
+3 −2
Original line number Diff line number Diff line
@@ -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 */