]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
Make sure to pop buffers for a failed read in xfs_check and xfs_metadump (both in...
authorBarry Naujok <bnaujok@sgi.com>
Wed, 27 Aug 2008 04:11:21 +0000 (04:11 +0000)
committerBarry Naujok <bnaujok@sgi.com>
Wed, 27 Aug 2008 04:11:21 +0000 (04:11 +0000)
Merge of master-melb:xfs-cmds:31976a by kenmcd.

  Pop buffers for failed reads

db/check.c
db/metadump.c

index a151c0678a0fe6b78975ea5cd8b2072b50ec0e08..f18dbf82cab106c89fc395f2c5c994235b3e5fe5 100644 (file)
@@ -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++) {
index a5e565f3ccceece42d747de9dcc62a7d29ecc7a0..fe5bd7ba99c54257859f58fe5dd0f9919a04cc7e 100644 (file)
@@ -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;
        }