Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b36c4a73 authored by Jan Kara's avatar Jan Kara Committed by Greg Kroah-Hartman
Browse files

udf: Handle error when adding extent to a file



commit 19fd80de0a8b5170ef34704c8984cca920dffa59 upstream.

When adding extent to a file fails, so far we've silently squelshed the
error. Make sure to propagate it up properly.

Signed-off-by: default avatarJan Kara <jack@suse.cz>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 7648ea98
Loading
Loading
Loading
Loading
+27 −14
Original line number Diff line number Diff line
@@ -57,14 +57,14 @@ static int udf_update_inode(struct inode *, int);
static int udf_sync_inode(struct inode *inode);
static int udf_alloc_i_data(struct inode *inode, size_t size);
static sector_t inode_getblk(struct inode *, sector_t, int *, int *);
static int8_t udf_insert_aext(struct inode *, struct extent_position,
static int udf_insert_aext(struct inode *, struct extent_position,
			   struct kernel_lb_addr, uint32_t);
static void udf_split_extents(struct inode *, int *, int, udf_pblk_t,
			      struct kernel_long_ad *, int *);
static void udf_prealloc_extents(struct inode *, int, int,
				 struct kernel_long_ad *, int *);
static void udf_merge_extents(struct inode *, struct kernel_long_ad *, int *);
static void udf_update_extents(struct inode *, struct kernel_long_ad *, int,
static int udf_update_extents(struct inode *, struct kernel_long_ad *, int,
			      int, struct extent_position *);
static int udf_get_block(struct inode *, sector_t, struct buffer_head *, int);

@@ -890,7 +890,9 @@ static sector_t inode_getblk(struct inode *inode, sector_t block,
	/* write back the new extents, inserting new extents if the new number
	 * of extents is greater than the old number, and deleting extents if
	 * the new number of extents is less than the old number */
	udf_update_extents(inode, laarr, startnum, endnum, &prev_epos);
	*err = udf_update_extents(inode, laarr, startnum, endnum, &prev_epos);
	if (*err < 0)
		goto out_free;

	newblock = udf_get_pblock(inode->i_sb, newblocknum,
				iinfo->i_location.partitionReferenceNum, 0);
@@ -1158,21 +1160,30 @@ static void udf_merge_extents(struct inode *inode, struct kernel_long_ad *laarr,
	}
}

static void udf_update_extents(struct inode *inode, struct kernel_long_ad *laarr,
static int udf_update_extents(struct inode *inode, struct kernel_long_ad *laarr,
			      int startnum, int endnum,
			      struct extent_position *epos)
{
	int start = 0, i;
	struct kernel_lb_addr tmploc;
	uint32_t tmplen;
	int err;

	if (startnum > endnum) {
		for (i = 0; i < (startnum - endnum); i++)
			udf_delete_aext(inode, *epos);
	} else if (startnum < endnum) {
		for (i = 0; i < (endnum - startnum); i++) {
			udf_insert_aext(inode, *epos, laarr[i].extLocation,
			err = udf_insert_aext(inode, *epos,
					      laarr[i].extLocation,
					      laarr[i].extLength);
			/*
			 * If we fail here, we are likely corrupting the extent
			 * list and leaking blocks. At least stop early to
			 * limit the damage.
			 */
			if (err < 0)
				return err;
			udf_next_aext(inode, epos, &laarr[i].extLocation,
				      &laarr[i].extLength, 1);
			start++;
@@ -1184,6 +1195,7 @@ static void udf_update_extents(struct inode *inode, struct kernel_long_ad *laarr
		udf_write_aext(inode, epos, &laarr[i].extLocation,
			       laarr[i].extLength, 1);
	}
	return 0;
}

struct buffer_head *udf_bread(struct inode *inode, udf_pblk_t block,
@@ -2218,12 +2230,13 @@ int8_t udf_current_aext(struct inode *inode, struct extent_position *epos,
	return etype;
}

static int8_t udf_insert_aext(struct inode *inode, struct extent_position epos,
static int udf_insert_aext(struct inode *inode, struct extent_position epos,
			   struct kernel_lb_addr neloc, uint32_t nelen)
{
	struct kernel_lb_addr oeloc;
	uint32_t oelen;
	int8_t etype;
	int err;

	if (epos.bh)
		get_bh(epos.bh);
@@ -2233,10 +2246,10 @@ static int8_t udf_insert_aext(struct inode *inode, struct extent_position epos,
		neloc = oeloc;
		nelen = (etype << 30) | oelen;
	}
	udf_add_aext(inode, &epos, &neloc, nelen, 1);
	err = udf_add_aext(inode, &epos, &neloc, nelen, 1);
	brelse(epos.bh);

	return (nelen >> 30);
	return err;
}

int8_t udf_delete_aext(struct inode *inode, struct extent_position epos)