void phase3(xfs_mount_t *mp) { int i, j; do_log(_("Phase 3 - for each AG...\n")); if (!no_modify) do_log(_(" - scan and clear agi unlinked lists...\n")); else do_log(_(" - scan (but don't clear) agi unlinked lists...\n")); set_progress_msg(PROG_FMT_AGI_UNLINKED, (__uint64_t) glob_agcount); /* first clear the agi unlinked AGI list */ if (!no_modify) { for (i = 0; i < mp->m_sb.sb_agcount; i++) process_agi_unlinked(mp, i); } /* now look at possibly bogus inodes */ for (i = 0; i < mp->m_sb.sb_agcount; i++) { check_uncertain_aginodes(mp, i); PROG_RPT_INC(prog_rpt_done[i], 1); } print_final_rpt(); /* ok, now that the tree's ok, let's take a good look */ do_log(_( " - process known inodes and perform inode discovery...\n")); set_progress_msg(PROG_FMT_PROCESS_INO, (__uint64_t) mp->m_sb.sb_icount); process_ags(mp); print_final_rpt(); /* * process newly discovered inode chunks */ do_log(_(" - process newly discovered inodes...\n")); set_progress_msg(PROG_FMT_NEW_INODES, (__uint64_t) glob_agcount); do { /* * have to loop until no ag has any uncertain * inodes */ j = 0; for (i = 0; i < mp->m_sb.sb_agcount; i++) { j += process_uncertain_aginodes(mp, i); #ifdef XR_INODE_TRACE fprintf(stderr, "\t\t phase 3 - process_uncertain_inodes returns %d\n", j); #endif PROG_RPT_INC(prog_rpt_done[i], 1); } } while (j != 0); print_final_rpt(); }
static void do_uncertain_aginodes( work_queue_t *wq, xfs_agnumber_t agno, void *arg) { int *count = arg; *count = process_uncertain_aginodes(wq->mp, agno); #ifdef XR_INODE_TRACE fprintf(stderr, "\t\t phase 3 - ag %d process_uncertain_inodes returns %d\n", *count, j); #endif PROG_RPT_INC(prog_rpt_done[agno], 1); }
void phase3( struct xfs_mount *mp, int scan_threads) { int i, j; int *counts; work_queue_t wq; do_log(_("Phase 3 - for each AG...\n")); if (!no_modify) do_log(_(" - scan and clear agi unlinked lists...\n")); else do_log(_(" - scan (but don't clear) agi unlinked lists...\n")); set_progress_msg(PROG_FMT_AGI_UNLINKED, (__uint64_t) glob_agcount); /* first clear the agi unlinked AGI list */ if (!no_modify) { for (i = 0; i < mp->m_sb.sb_agcount; i++) process_agi_unlinked(mp, i); } /* now look at possibly bogus inodes */ for (i = 0; i < mp->m_sb.sb_agcount; i++) { check_uncertain_aginodes(mp, i); PROG_RPT_INC(prog_rpt_done[i], 1); } print_final_rpt(); /* ok, now that the tree's ok, let's take a good look */ do_log(_( " - process known inodes and perform inode discovery...\n")); set_progress_msg(PROG_FMT_PROCESS_INO, (__uint64_t) mp->m_sb.sb_icount); process_ags(mp); print_final_rpt(); /* * process newly discovered inode chunks */ do_log(_(" - process newly discovered inodes...\n")); set_progress_msg(PROG_FMT_NEW_INODES, (__uint64_t) glob_agcount); counts = calloc(sizeof(*counts), mp->m_sb.sb_agcount); if (!counts) { do_abort(_("no memory for uncertain inode counts\n")); return; } do { /* * have to loop until no ag has any uncertain * inodes */ j = 0; memset(counts, 0, mp->m_sb.sb_agcount * sizeof(*counts)); create_work_queue(&wq, mp, scan_threads); for (i = 0; i < mp->m_sb.sb_agcount; i++) queue_work(&wq, do_uncertain_aginodes, i, &counts[i]); destroy_work_queue(&wq); /* tally up the counts */ for (i = 0; i < mp->m_sb.sb_agcount; i++) j += counts[i]; } while (j != 0); free(counts); print_final_rpt(); }
static void phase5_func( xfs_mount_t *mp, xfs_agnumber_t agno) { __uint64_t num_inos; __uint64_t num_free_inos; __uint64_t finobt_num_inos; __uint64_t finobt_num_free_inos; bt_status_t bno_btree_curs; bt_status_t bcnt_btree_curs; bt_status_t ino_btree_curs; bt_status_t fino_btree_curs; int extra_blocks = 0; uint num_freeblocks; xfs_extlen_t freeblks1; #ifdef DEBUG xfs_extlen_t freeblks2; #endif xfs_agblock_t num_extents; __uint32_t magic; struct agi_stat agi_stat = {0,}; if (verbose) do_log(_(" - agno = %d\n"), agno); { /* * build up incore bno and bcnt extent btrees */ num_extents = mk_incore_fstree(mp, agno); #ifdef XR_BLD_FREE_TRACE fprintf(stderr, "# of bno extents is %d\n", count_bno_extents(agno)); #endif if (num_extents == 0) { /* * XXX - what we probably should do here is pick an * inode for a regular file in the allocation group * that has space allocated and shoot it by traversing * the bmap list and putting all its extents on the * incore freespace trees, clearing the inode, * and clearing the in-use bit in the incore inode * tree. Then try mk_incore_fstree() again. */ do_error(_("unable to rebuild AG %u. " "Not enough free space in on-disk AG.\n"), agno); } /* * ok, now set up the btree cursors for the * on-disk btrees (includs pre-allocating all * required blocks for the trees themselves) */ init_ino_cursor(mp, agno, &ino_btree_curs, &num_inos, &num_free_inos, 0); if (xfs_sb_version_hasfinobt(&mp->m_sb)) init_ino_cursor(mp, agno, &fino_btree_curs, &finobt_num_inos, &finobt_num_free_inos, 1); sb_icount_ag[agno] += num_inos; sb_ifree_ag[agno] += num_free_inos; num_extents = count_bno_extents_blocks(agno, &num_freeblocks); /* * lose two blocks per AG -- the space tree roots * are counted as allocated since the space trees * always have roots */ sb_fdblocks_ag[agno] += num_freeblocks - 2; if (num_extents == 0) { /* * XXX - what we probably should do here is pick an * inode for a regular file in the allocation group * that has space allocated and shoot it by traversing * the bmap list and putting all its extents on the * incore freespace trees, clearing the inode, * and clearing the in-use bit in the incore inode * tree. Then try mk_incore_fstree() again. */ do_error( _("unable to rebuild AG %u. No free space.\n"), agno); } #ifdef XR_BLD_FREE_TRACE fprintf(stderr, "# of bno extents is %d\n", num_extents); #endif /* * track blocks that we might really lose */ extra_blocks = calculate_freespace_cursor(mp, agno, &num_extents, &bno_btree_curs); /* * freespace btrees live in the "free space" but * the filesystem treats AGFL blocks as allocated * since they aren't described by the freespace trees */ /* * see if we can fit all the extra blocks into the AGFL */ extra_blocks = (extra_blocks - XFS_AGFL_SIZE(mp) > 0) ? extra_blocks - XFS_AGFL_SIZE(mp) : 0; if (extra_blocks > 0) { do_warn(_("lost %d blocks in agno %d, sorry.\n"), extra_blocks, agno); sb_fdblocks_ag[agno] -= extra_blocks; } bcnt_btree_curs = bno_btree_curs; setup_cursor(mp, agno, &bno_btree_curs); setup_cursor(mp, agno, &bcnt_btree_curs); #ifdef XR_BLD_FREE_TRACE fprintf(stderr, "# of bno extents is %d\n", count_bno_extents(agno)); fprintf(stderr, "# of bcnt extents is %d\n", count_bcnt_extents(agno)); #endif /* * now rebuild the freespace trees */ freeblks1 = build_freespace_tree(mp, agno, &bno_btree_curs, XFS_ABTB_MAGIC); #ifdef XR_BLD_FREE_TRACE fprintf(stderr, "# of free blocks == %d\n", freeblks1); #endif write_cursor(&bno_btree_curs); #ifdef DEBUG freeblks2 = build_freespace_tree(mp, agno, &bcnt_btree_curs, XFS_ABTC_MAGIC); #else (void) build_freespace_tree(mp, agno, &bcnt_btree_curs, XFS_ABTC_MAGIC); #endif write_cursor(&bcnt_btree_curs); ASSERT(freeblks1 == freeblks2); /* * set up agf and agfl */ build_agf_agfl(mp, agno, &bno_btree_curs, &bcnt_btree_curs, freeblks1, extra_blocks); /* * build inode allocation tree. */ magic = xfs_sb_version_hascrc(&mp->m_sb) ? XFS_IBT_CRC_MAGIC : XFS_IBT_MAGIC; build_ino_tree(mp, agno, &ino_btree_curs, magic, &agi_stat, 0); write_cursor(&ino_btree_curs); /* * build free inode tree */ if (xfs_sb_version_hasfinobt(&mp->m_sb)) { magic = xfs_sb_version_hascrc(&mp->m_sb) ? XFS_FIBT_CRC_MAGIC : XFS_FIBT_MAGIC; build_ino_tree(mp, agno, &fino_btree_curs, magic, NULL, 1); write_cursor(&fino_btree_curs); } /* build the agi */ build_agi(mp, agno, &ino_btree_curs, &fino_btree_curs, &agi_stat); /* * tear down cursors */ finish_cursor(&bno_btree_curs); finish_cursor(&ino_btree_curs); if (xfs_sb_version_hasfinobt(&mp->m_sb)) finish_cursor(&fino_btree_curs); finish_cursor(&bcnt_btree_curs); /* * release the incore per-AG bno/bcnt trees so * the extent nodes can be recycled */ release_agbno_extent_tree(agno); release_agbcnt_extent_tree(agno); } PROG_RPT_INC(prog_rpt_done[agno], 1); }