Skip to content

Commit b405c1e

Browse files
Zhao Mengmengjankara
authored andcommitted
udf: refactor udf_next_aext() to handle error
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 <[email protected]> Suggested-by: Jan Kara <[email protected]> Signed-off-by: Jan Kara <[email protected]> Link: https://patch.msgid.link/[email protected]
1 parent ee703a7 commit b405c1e

File tree

6 files changed

+143
-65
lines changed

6 files changed

+143
-65
lines changed

fs/udf/balloc.c

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,7 @@ static void udf_table_free_blocks(struct super_block *sb,
370370
struct extent_position oepos, epos;
371371
int8_t etype;
372372
struct udf_inode_info *iinfo;
373+
int ret = 0;
373374

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

386-
while (count &&
387-
(etype = udf_next_aext(table, &epos, &eloc, &elen, 1)) != -1) {
387+
while (count) {
388+
ret = udf_next_aext(table, &epos, &eloc, &elen, &etype, 1);
389+
if (ret < 0)
390+
goto error_return;
391+
if (ret == 0)
392+
break;
388393
if (((eloc.logicalBlockNum +
389394
(elen >> sb->s_blocksize_bits)) == start)) {
390395
if ((0x3FFFFFFF - elen) <
@@ -459,11 +464,8 @@ static void udf_table_free_blocks(struct super_block *sb,
459464
adsize = sizeof(struct short_ad);
460465
else if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG)
461466
adsize = sizeof(struct long_ad);
462-
else {
463-
brelse(oepos.bh);
464-
brelse(epos.bh);
467+
else
465468
goto error_return;
466-
}
467469

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

484+
error_return:
482485
brelse(epos.bh);
483486
brelse(oepos.bh);
484487

485-
error_return:
486488
mutex_unlock(&sbi->s_alloc_mutex);
487489
return;
488490
}
@@ -498,6 +500,7 @@ static int udf_table_prealloc_blocks(struct super_block *sb,
498500
struct extent_position epos;
499501
int8_t etype = -1;
500502
struct udf_inode_info *iinfo;
503+
int ret = 0;
501504

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

519-
while (first_block != eloc.logicalBlockNum &&
520-
(etype = udf_next_aext(table, &epos, &eloc, &elen, 1)) != -1) {
522+
while (first_block != eloc.logicalBlockNum) {
523+
ret = udf_next_aext(table, &epos, &eloc, &elen, &etype, 1);
524+
if (ret < 0)
525+
goto err_out;
526+
if (ret == 0)
527+
break;
521528
udf_debug("eloc=%u, elen=%u, first_block=%u\n",
522529
eloc.logicalBlockNum, elen, first_block);
523-
; /* empty loop body */
524530
}
525531

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

548+
err_out:
542549
brelse(epos.bh);
543550

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

564572
*err = -ENOSPC;
565573

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

586-
while (spread &&
587-
(etype = udf_next_aext(table, &epos, &eloc, &elen, 1)) != -1) {
594+
while (spread) {
595+
ret = udf_next_aext(table, &epos, &eloc, &elen, &etype, 1);
596+
if (ret <= 0)
597+
break;
588598
if (goal >= eloc.logicalBlockNum) {
589599
if (goal < eloc.logicalBlockNum +
590600
(elen >> sb->s_blocksize_bits))
@@ -612,9 +622,11 @@ static udf_pblk_t udf_table_new_block(struct super_block *sb,
612622

613623
brelse(epos.bh);
614624

615-
if (spread == 0xFFFFFFFF) {
625+
if (ret < 0 || spread == 0xFFFFFFFF) {
616626
brelse(goal_epos.bh);
617627
mutex_unlock(&sbi->s_alloc_mutex);
628+
if (ret < 0)
629+
*err = ret;
618630
return 0;
619631
}
620632

fs/udf/directory.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -166,13 +166,19 @@ static struct buffer_head *udf_fiiter_bread_blk(struct udf_fileident_iter *iter)
166166
*/
167167
static int udf_fiiter_advance_blk(struct udf_fileident_iter *iter)
168168
{
169+
int8_t etype = -1;
170+
int err = 0;
171+
169172
iter->loffset++;
170173
if (iter->loffset < DIV_ROUND_UP(iter->elen, 1<<iter->dir->i_blkbits))
171174
return 0;
172175

173176
iter->loffset = 0;
174-
if (udf_next_aext(iter->dir, &iter->epos, &iter->eloc, &iter->elen, 1)
175-
!= (EXT_RECORDED_ALLOCATED >> 30)) {
177+
err = udf_next_aext(iter->dir, &iter->epos, &iter->eloc,
178+
&iter->elen, &etype, 1);
179+
if (err < 0)
180+
return err;
181+
else if (err == 0 || etype != (EXT_RECORDED_ALLOCATED >> 30)) {
176182
if (iter->pos == iter->dir->i_size) {
177183
iter->elen = 0;
178184
return 0;

0 commit comments

Comments
 (0)