From: Barry Naujok Date: Wed, 27 Aug 2008 04:11:21 +0000 (+0000) Subject: Make sure to pop buffers for a failed read in xfs_check and xfs_metadump (both in... X-Git-Tag: v3.0.0~65 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=d24c0a9050dc40972d36abe45aba123c25027ccb;p=thirdparty%2Fxfsprogs-dev.git Make sure to pop buffers for a failed read in xfs_check and xfs_metadump (both in xfs_db) Merge of master-melb:xfs-cmds:31976a by kenmcd. Pop buffers for failed reads --- diff --git a/db/check.c b/db/check.c index a151c0678..f18dbf82c 100644 --- a/db/check.c +++ b/db/check.c @@ -1991,6 +1991,7 @@ process_block_dir_v2( "%lld\n", id->ino); error++; + pop_cur(); return 0; } dir_hash_init(); @@ -2951,6 +2952,7 @@ process_leaf_dir_v1( "%lld\n", id->ino); error++; + pop_cur(); return 0; } parent = process_leaf_dir_v1_int(dot, dotdot, id); @@ -3322,6 +3324,7 @@ process_node_dir_v1( v = verbose || id->ilist; parent = 0; dbno = NULLFILEOFF; + push_cur(); while ((dbno = blkmap_next_off(blkmap, dbno, &t)) != NULLFILEOFF) { bno = blkmap_get(blkmap, dbno); v2 = bno != NULLFSBLOCK && CHECK_BLIST(bno); @@ -3337,6 +3340,7 @@ process_node_dir_v1( (__uint32_t)dbno, (xfs_dfsbno_t)bno); if (bno == NULLFSBLOCK) continue; + pop_cur(); push_cur(); set_cur(&typtab[TYP_DIR], XFS_FSB_TO_DADDR(mp, bno), blkbb, DB_RING_IGN, NULL); @@ -3353,10 +3357,7 @@ process_node_dir_v1( #else if (INT_GET(node->hdr.info.magic, ARCH_CONVERT) == XFS_DIR_NODE_MAGIC) #endif - { - pop_cur(); continue; - } lino = process_leaf_dir_v1_int(dot, dotdot, id); if (lino) { if (parent) { @@ -3368,8 +3369,8 @@ process_node_dir_v1( } else parent = lino; } - pop_cur(); } + pop_cur(); return parent; } @@ -3411,8 +3412,7 @@ process_quota( perblock = (uint)(mp->m_sb.sb_blocksize / sizeof(*dqb)); dqid = 0; qbno = NULLFILEOFF; - while ((qbno = blkmap_next_off(blkmap, qbno, &t)) != - NULLFILEOFF) { + while ((qbno = blkmap_next_off(blkmap, qbno, &t)) != NULLFILEOFF) { bno = blkmap_get(blkmap, qbno); dqid = (xfs_dqid_t)qbno * perblock; cb = CHECK_BLIST(bno); @@ -3421,13 +3421,13 @@ process_quota( set_cur(&typtab[TYP_DQBLK], XFS_FSB_TO_DADDR(mp, bno), blkbb, DB_RING_IGN, NULL); if ((dqb = iocur_top->data) == NULL) { - pop_cur(); if (scicb) dbprintf("can't read block %lld for %s quota " "inode (fsblock %lld)\n", (xfs_dfiloff_t)qbno, s, (xfs_dfsbno_t)bno); error++; + pop_cur(); continue; } for (i = 0; i < perblock; i++, dqid++, dqb++) { @@ -3525,12 +3525,12 @@ process_rtbitmap( set_cur(&typtab[TYP_RTBITMAP], XFS_FSB_TO_DADDR(mp, bno), blkbb, DB_RING_IGN, NULL); if ((words = iocur_top->data) == NULL) { - pop_cur(); if (!sflag) dbprintf("can't read block %lld for rtbitmap " "inode\n", (xfs_dfiloff_t)bmbno); error++; + pop_cur(); continue; } for (bit = 0; @@ -3578,8 +3578,7 @@ process_rtsummary( int t; sumbno = NULLFILEOFF; - while ((sumbno = blkmap_next_off(blkmap, sumbno, &t)) != - NULLFILEOFF) { + while ((sumbno = blkmap_next_off(blkmap, sumbno, &t)) != NULLFILEOFF) { bno = blkmap_get(blkmap, sumbno); if (bno == NULLFSBLOCK) { if (!sflag) @@ -3598,6 +3597,7 @@ process_rtsummary( "inode\n", (xfs_dfiloff_t)sumbno); error++; + pop_cur(); continue; } memcpy((char *)sumfile + sumbno * mp->m_sb.sb_blocksize, bytes, @@ -3906,16 +3906,15 @@ scan_ag( agffreeblks = agflongest = 0; agfbtreeblks = -2; agicount = agifreecount = 0; - push_cur(); + push_cur(); /* 1 pushed */ set_cur(&typtab[TYP_SB], XFS_AG_DADDR(mp, agno, XFS_SB_DADDR), XFS_FSS_TO_BB(mp, 1), DB_RING_IGN, NULL); if (!iocur_top->data) { dbprintf("can't read superblock for ag %u\n", agno); - pop_cur(); serious_error++; - return; + goto pop1_out; } libxfs_xlate_sb(iocur_top->data, sb, 1, XFS_SB_ALL_BITS); @@ -3945,16 +3944,14 @@ scan_ag( if (sb->sb_logstart && XFS_FSB_TO_AGNO(mp, sb->sb_logstart) == agno) set_dbmap(agno, XFS_FSB_TO_AGBNO(mp, sb->sb_logstart), sb->sb_logblocks, DBM_LOG, agno, XFS_SB_BLOCK(mp)); - push_cur(); + push_cur(); /* 2 pushed */ set_cur(&typtab[TYP_AGF], XFS_AG_DADDR(mp, agno, XFS_AGF_DADDR(mp)), XFS_FSS_TO_BB(mp, 1), DB_RING_IGN, NULL); if ((agf = iocur_top->data) == NULL) { dbprintf("can't read agf block for ag %u\n", agno); - pop_cur(); - pop_cur(); serious_error++; - return; + goto pop2_out; } if (INT_GET(agf->agf_magicnum, ARCH_CONVERT) != XFS_AGF_MAGIC) { if (!sflag) @@ -3975,17 +3972,14 @@ scan_ag( set_dbmap(agno, INT_GET(agf->agf_length, ARCH_CONVERT), sb->sb_agblocks - INT_GET(agf->agf_length, ARCH_CONVERT), DBM_MISSING, agno, XFS_SB_BLOCK(mp)); - push_cur(); + push_cur(); /* 3 pushed */ set_cur(&typtab[TYP_AGI], XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)), XFS_FSS_TO_BB(mp, 1), DB_RING_IGN, NULL); if ((agi = iocur_top->data) == NULL) { dbprintf("can't read agi block for ag %u\n", agno); serious_error++; - pop_cur(); - pop_cur(); - pop_cur(); - return; + goto pop3_out; } if (INT_GET(agi->agi_magicnum, ARCH_CONVERT) != XFS_AGI_MAGIC) { if (!sflag) @@ -4066,8 +4060,11 @@ scan_ag( error++; } } +pop3_out: pop_cur(); +pop2_out: pop_cur(); +pop1_out: pop_cur(); } @@ -4095,6 +4092,7 @@ scan_freelist( if ((agfl = iocur_top->data) == NULL) { dbprintf("can't read agfl block for ag %u\n", seqno); serious_error++; + pop_cur(); return; } i = INT_GET(agf->agf_flfirst, ARCH_CONVERT); @@ -4144,6 +4142,7 @@ scan_lbtree( XFS_FSB_TO_AGNO(mp, root), XFS_FSB_TO_AGBNO(mp, root)); error++; + pop_cur(); return; } (*func)(iocur_top->data, nlevels - 1, type, root, id, totd, toti, nex, @@ -4169,6 +4168,7 @@ scan_sbtree( if (!sflag) dbprintf("can't read btree block %u/%u\n", seqno, root); error++; + pop_cur(); return; } (*func)(iocur_top->data, nlevels - 1, agf, root, isroot); @@ -4484,6 +4484,7 @@ scanfunc_ino( seqno, XFS_AGINO_TO_AGBNO(mp, agino)); error++; + pop_cur(); continue; } for (j = 0, nfree = 0; j < XFS_INODES_PER_CHUNK; j++) { diff --git a/db/metadump.c b/db/metadump.c index a5e565f3c..fe5bd7ba9 100644 --- a/db/metadump.c +++ b/db/metadump.c @@ -186,22 +186,26 @@ scan_btree( typnm_t btype, void *arg)) { + int rval = 0; + push_cur(); set_cur(&typtab[btype], XFS_AGB_TO_DADDR(mp, agno, agbno), blkbb, DB_RING_IGN, NULL); if (iocur_top->data == NULL) { print_warning("cannot read %s block %u/%u", typtab[btype].name, agno, agbno); - return !stop_on_read_error; + rval = !stop_on_read_error; + goto pop_out; } if (!write_buf(iocur_top)) - return 0; + goto pop_out; if (!(*func)(iocur_top->data, agno, agbno, level - 1, btype, arg)) - return 0; - + goto pop_out; + rval = 1; +pop_out: pop_cur(); - return 1; + return rval; } /* free space tree copy routines */ @@ -949,8 +953,10 @@ process_bmbt_reclist( if (iocur_top->data == NULL) { print_warning("cannot read %s block %u/%u (%llu)", typtab[btype].name, agno, agbno, s); - if (stop_on_read_error) + if (stop_on_read_error) { + pop_cur(); return 0; + } } else { if (!dont_obfuscate) switch (btype) { @@ -973,8 +979,10 @@ process_bmbt_reclist( default: ; } - if (!write_buf(iocur_top)) + if (!write_buf(iocur_top)) { + pop_cur(); return 0; + } } pop_cur(); } @@ -1238,6 +1246,7 @@ copy_inode_chunk( int off; xfs_agblock_t agbno; int i; + int rval = 0; agino = be32_to_cpu(rp->ir_startino); agbno = XFS_AGINO_TO_AGBNO(mp, agino); @@ -1258,7 +1267,8 @@ copy_inode_chunk( DB_RING_IGN, NULL); if (iocur_top->data == NULL) { print_warning("cannot read inode block %u/%u", agno, agbno); - return !stop_on_read_error; + rval = !stop_on_read_error; + goto pop_out; } /* @@ -1291,11 +1301,11 @@ copy_inode_chunk( ((off + i) << mp->m_sb.sb_inodelog)); if (!process_inode(agno, agino + i, dip)) - return 0; + goto pop_out; } skip_processing: if (!write_buf(iocur_top)) - return 0; + goto pop_out; inodes_copied += XFS_INODES_PER_CHUNK; @@ -1303,10 +1313,10 @@ skip_processing: print_progress("Copied %u of %u inodes (%u of %u AGs)", inodes_copied, mp->m_sb.sb_icount, agno, mp->m_sb.sb_agcount); - + rval = 1; +pop_out: pop_cur(); - - return 1; + return rval; } static int @@ -1401,61 +1411,66 @@ scan_ag( { xfs_agf_t *agf; xfs_agi_t *agi; + int stack_count = 0; + int rval = 0; /* copy the superblock of the AG */ push_cur(); + stack_count++; set_cur(&typtab[TYP_SB], XFS_AG_DADDR(mp, agno, XFS_SB_DADDR), XFS_FSS_TO_BB(mp, 1), DB_RING_IGN, NULL); if (!iocur_top->data) { print_warning("cannot read superblock for ag %u", agno); if (stop_on_read_error) - return 0; + goto pop_out; } else { if (!write_buf(iocur_top)) - return 0; + goto pop_out; } /* copy the AG free space btree root */ push_cur(); + stack_count++; set_cur(&typtab[TYP_AGF], XFS_AG_DADDR(mp, agno, XFS_AGF_DADDR(mp)), XFS_FSS_TO_BB(mp, 1), DB_RING_IGN, NULL); agf = iocur_top->data; if (iocur_top->data == NULL) { print_warning("cannot read agf block for ag %u", agno); if (stop_on_read_error) - return 0; + goto pop_out; } else { if (!write_buf(iocur_top)) - return 0; + goto pop_out; } /* copy the AG inode btree root */ push_cur(); + stack_count++; set_cur(&typtab[TYP_AGI], XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)), XFS_FSS_TO_BB(mp, 1), DB_RING_IGN, NULL); agi = iocur_top->data; if (iocur_top->data == NULL) { print_warning("cannot read agi block for ag %u", agno); if (stop_on_read_error) - return 0; + goto pop_out; } else { if (!write_buf(iocur_top)) - return 0; + goto pop_out; } /* copy the AG free list header */ push_cur(); + stack_count++; set_cur(&typtab[TYP_AGFL], XFS_AG_DADDR(mp, agno, XFS_AGFL_DADDR(mp)), XFS_FSS_TO_BB(mp, 1), DB_RING_IGN, NULL); if (iocur_top->data == NULL) { print_warning("cannot read agfl block for ag %u", agno); if (stop_on_read_error) - return 0; + goto pop_out; } else { if (!write_buf(iocur_top)) - return 0; + goto pop_out; } - pop_cur(); /* copy AG free space btrees */ if (agf) { @@ -1463,22 +1478,21 @@ scan_ag( print_progress("Copying free space trees of AG %u", agno); if (!copy_free_bno_btree(agno, agf)) - return 0; + goto pop_out; if (!copy_free_cnt_btree(agno, agf)) - return 0; + goto pop_out; } /* copy inode btrees and the inodes and their associated metadata */ if (agi) { if (!copy_inodes(agno, agi)) - return 0; + goto pop_out; } - - pop_cur(); - pop_cur(); - pop_cur(); - - return 1; + rval = 1; +pop_out: + while (stack_count--) + pop_cur(); + return rval; } static int @@ -1492,6 +1506,7 @@ copy_ino( xfs_dinode_t *dip; xfs_dinode_core_t tdic; int offset; + int rval = 0; if (ino == 0) return 1; @@ -1515,7 +1530,8 @@ copy_ino( if (iocur_top->data == NULL) { print_warning("cannot read %s inode %lld", typtab[itype].name, (long long)ino); - return !stop_on_read_error; + rval = !stop_on_read_error; + goto pop_out; } off_cur(offset << mp->m_sb.sb_inodelog, mp->m_sb.sb_inodesize); @@ -1524,7 +1540,10 @@ copy_ino( memcpy(&dip->di_core, &tdic, sizeof(xfs_dinode_core_t)); cur_ino = ino; - return process_inode_data(dip, itype); + rval = process_inode_data(dip, itype); +pop_out: + pop_cur(); + return rval; } @@ -1553,6 +1572,7 @@ copy_log(void) set_cur(&typtab[TYP_LOG], XFS_FSB_TO_DADDR(mp, mp->m_sb.sb_logstart), mp->m_sb.sb_logblocks * blkbb, DB_RING_IGN, NULL); if (iocur_top->data == NULL) { + pop_cur(); print_warning("cannot read log"); return !stop_on_read_error; }