Skip to content

Commit

Permalink
udf: refactor udf_next_aext() to handle error
Browse files Browse the repository at this point in the history
Since udf_current_aext() has error handling, udf_next_aext() should have
error handling too. Besides, when too many indirect extents found in one
inode, return -EFSCORRUPTED; when reading block failed, return -EIO.

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-3-zhaomzhao@126.com
  • Loading branch information
Zhao Mengmeng authored and Jan Kara committed Oct 2, 2024
1 parent ee703a7 commit b405c1e
Show file tree
Hide file tree
Showing 6 changed files with 143 additions and 65 deletions.
38 changes: 25 additions & 13 deletions fs/udf/balloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,7 @@ static void udf_table_free_blocks(struct super_block *sb,
struct extent_position oepos, epos;
int8_t etype;
struct udf_inode_info *iinfo;
int ret = 0;

mutex_lock(&sbi->s_alloc_mutex);
iinfo = UDF_I(table);
Expand All @@ -383,8 +384,12 @@ static void udf_table_free_blocks(struct super_block *sb,
epos.block = oepos.block = iinfo->i_location;
epos.bh = oepos.bh = NULL;

while (count &&
(etype = udf_next_aext(table, &epos, &eloc, &elen, 1)) != -1) {
while (count) {
ret = udf_next_aext(table, &epos, &eloc, &elen, &etype, 1);
if (ret < 0)
goto error_return;
if (ret == 0)
break;
if (((eloc.logicalBlockNum +
(elen >> sb->s_blocksize_bits)) == start)) {
if ((0x3FFFFFFF - elen) <
Expand Down Expand Up @@ -459,11 +464,8 @@ static void udf_table_free_blocks(struct super_block *sb,
adsize = sizeof(struct short_ad);
else if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG)
adsize = sizeof(struct long_ad);
else {
brelse(oepos.bh);
brelse(epos.bh);
else
goto error_return;
}

if (epos.offset + (2 * adsize) > sb->s_blocksize) {
/* Steal a block from the extent being free'd */
Expand All @@ -479,10 +481,10 @@ static void udf_table_free_blocks(struct super_block *sb,
__udf_add_aext(table, &epos, &eloc, elen, 1);
}

error_return:
brelse(epos.bh);
brelse(oepos.bh);

error_return:
mutex_unlock(&sbi->s_alloc_mutex);
return;
}
Expand All @@ -498,6 +500,7 @@ static int udf_table_prealloc_blocks(struct super_block *sb,
struct extent_position epos;
int8_t etype = -1;
struct udf_inode_info *iinfo;
int ret = 0;

if (first_block >= sbi->s_partmaps[partition].s_partition_len)
return 0;
Expand All @@ -516,11 +519,14 @@ static int udf_table_prealloc_blocks(struct super_block *sb,
epos.bh = NULL;
eloc.logicalBlockNum = 0xFFFFFFFF;

while (first_block != eloc.logicalBlockNum &&
(etype = udf_next_aext(table, &epos, &eloc, &elen, 1)) != -1) {
while (first_block != eloc.logicalBlockNum) {
ret = udf_next_aext(table, &epos, &eloc, &elen, &etype, 1);
if (ret < 0)
goto err_out;
if (ret == 0)
break;
udf_debug("eloc=%u, elen=%u, first_block=%u\n",
eloc.logicalBlockNum, elen, first_block);
; /* empty loop body */
}

if (first_block == eloc.logicalBlockNum) {
Expand All @@ -539,6 +545,7 @@ static int udf_table_prealloc_blocks(struct super_block *sb,
alloc_count = 0;
}

err_out:
brelse(epos.bh);

if (alloc_count)
Expand All @@ -560,6 +567,7 @@ static udf_pblk_t udf_table_new_block(struct super_block *sb,
struct extent_position epos, goal_epos;
int8_t etype;
struct udf_inode_info *iinfo = UDF_I(table);
int ret = 0;

*err = -ENOSPC;

Expand All @@ -583,8 +591,10 @@ static udf_pblk_t udf_table_new_block(struct super_block *sb,
epos.block = iinfo->i_location;
epos.bh = goal_epos.bh = NULL;

while (spread &&
(etype = udf_next_aext(table, &epos, &eloc, &elen, 1)) != -1) {
while (spread) {
ret = udf_next_aext(table, &epos, &eloc, &elen, &etype, 1);
if (ret <= 0)
break;
if (goal >= eloc.logicalBlockNum) {
if (goal < eloc.logicalBlockNum +
(elen >> sb->s_blocksize_bits))
Expand Down Expand Up @@ -612,9 +622,11 @@ static udf_pblk_t udf_table_new_block(struct super_block *sb,

brelse(epos.bh);

if (spread == 0xFFFFFFFF) {
if (ret < 0 || spread == 0xFFFFFFFF) {
brelse(goal_epos.bh);
mutex_unlock(&sbi->s_alloc_mutex);
if (ret < 0)
*err = ret;
return 0;
}

Expand Down
10 changes: 8 additions & 2 deletions fs/udf/directory.c
Original file line number Diff line number Diff line change
Expand Up @@ -166,13 +166,19 @@ static struct buffer_head *udf_fiiter_bread_blk(struct udf_fileident_iter *iter)
*/
static int udf_fiiter_advance_blk(struct udf_fileident_iter *iter)
{
int8_t etype = -1;
int err = 0;

iter->loffset++;
if (iter->loffset < DIV_ROUND_UP(iter->elen, 1<<iter->dir->i_blkbits))
return 0;

iter->loffset = 0;
if (udf_next_aext(iter->dir, &iter->epos, &iter->eloc, &iter->elen, 1)
!= (EXT_RECORDED_ALLOCATED >> 30)) {
err = udf_next_aext(iter->dir, &iter->epos, &iter->eloc,
&iter->elen, &etype, 1);
if (err < 0)
return err;
else if (err == 0 || etype != (EXT_RECORDED_ALLOCATED >> 30)) {
if (iter->pos == iter->dir->i_size) {
iter->elen = 0;
return 0;
Expand Down
Loading

0 comments on commit b405c1e

Please sign in to comment.