From 95dff16b19bc7320ae28eda791c24d14e2e225ea Mon Sep 17 00:00:00 2001 From: Barry Naujok Date: Thu, 21 Sep 2006 15:49:20 +0000 Subject: [PATCH] Fixed three issues in v2 directory checks in phase 6. Merge of master-melb:xfs-cmds:27015a by kenmcd. Fixed three issues in v2 directory checks in phase 6. --- doc/CHANGES | 4 ++++ repair/phase6.c | 25 ++++++++++++++++++------- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/doc/CHANGES b/doc/CHANGES index 89b08c2de..04a7c6ac7 100644 --- a/doc/CHANGES +++ b/doc/CHANGES @@ -1,3 +1,7 @@ +xfsprogs-2.8.x + - Fix v2 directory checking with holes and unreadable blocks. + - Fix a memory leak in dir2 checking. + xfsprogs-2.8.12 (29 August 2006) - Multi-thread modifications to xfs_repair. - Updated Polish translation, thanks to Jakub Bogusz. diff --git a/repair/phase6.c b/repair/phase6.c index c56250058..1dbdc7630 100644 --- a/repair/phase6.c +++ b/repair/phase6.c @@ -2557,12 +2557,14 @@ longform_dir2_entry_check(xfs_mount_t *mp, xfs_dir2_block_tail_t *btp; xfs_dablk_t da_bno; freetab_t *freetab; + int num_bps; int i; int isblock; int isleaf; xfs_fileoff_t next_da_bno; int seeval; int fixit; + xfs_dir2_db_t db; *need_dot = 1; freetab = malloc(FREETAB_SIZE(ip->i_d.di_size / mp->m_dirblksize)); @@ -2578,7 +2580,8 @@ longform_dir2_entry_check(xfs_mount_t *mp, freetab->ents[i].v = NULLDATAOFF; freetab->ents[i].s = 0; } - bplist = calloc(freetab->naents, sizeof(xfs_dabuf_t*)); + num_bps = freetab->naents; + bplist = calloc(num_bps, sizeof(xfs_dabuf_t*)); /* is this a block, leaf, or node directory? */ libxfs_dir2_isblock(NULL, ip, &isblock); libxfs_dir2_isleaf(NULL, ip, &isleaf); @@ -2591,21 +2594,28 @@ longform_dir2_entry_check(xfs_mount_t *mp, next_da_bno != NULLFILEOFF && da_bno < mp->m_dirleafblk; da_bno = (xfs_dablk_t)next_da_bno) { next_da_bno = da_bno + mp->m_dirblkfsbs - 1; - ASSERT(XFS_DIR2_DA_TO_DB(mp, da_bno) < freetab->naents); if (libxfs_bmap_next_offset(NULL, ip, &next_da_bno, XFS_DATA_FORK)) break; - if (libxfs_da_read_bufr(NULL, ip, da_bno, -1, - &bplist[XFS_DIR2_DA_TO_DB(mp, da_bno)], + db = XFS_DIR2_DA_TO_DB(mp, da_bno); + if (db >= num_bps) { + /* more data blocks than expected */ + num_bps = db + 1; + bplist = realloc(bplist, num_bps * sizeof(xfs_dabuf_t*)); + if (!bplist) + do_error( + _("realloc failed in longform_dir2_entry_check (%u bytes)\n"), + num_bps * sizeof(xfs_dabuf_t*)); + } + if (libxfs_da_read_bufr(NULL, ip, da_bno, -1, &bplist[db], XFS_DATA_FORK)) { do_warn(_( "can't read data block %u for directory inode %llu\n"), da_bno, ino); - *num_illegal++; + *num_illegal += 1; continue; /* try and read all "data" blocks */ } longform_dir2_entry_check_data(mp, ip, num_illegal, need_dot, - stack, irec, ino_offset, - &bplist[XFS_DIR2_DA_TO_DB(mp, da_bno)], hashtab, + stack, irec, ino_offset, &bplist[db], hashtab, &freetab, da_bno, isblock); } fixit = (*num_illegal != 0) || dir2_is_badino(ino); @@ -2638,6 +2648,7 @@ longform_dir2_entry_check(xfs_mount_t *mp, libxfs_da_brelse(NULL, bplist[i]); } + free(bplist); free(freetab); } -- 2.39.5