]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
repair: cleanup alloc/free/reset of the block usage tracking
authorChristoph Hellwig <hch@infradead.org>
Wed, 2 Sep 2009 17:55:42 +0000 (17:55 +0000)
committerAlex Elder <aelder@sgi.com>
Fri, 23 Oct 2009 17:12:41 +0000 (12:12 -0500)
Currently the code to allocate, free and reset the block usage bitmaps
is a complete mess.  This patch reorganizes it into logical helpers.

Details:

 - the current incore_init code is called just before phase2 is called,
   which then marks the log and the AG headers used.
 - we get rid of incore_init init, and replace it with direct calls to the
   unchanched incore_ino_init/incore_ext_init functions and our new init_bmaps
   which does all the allocations for the block usage tracking, aswell
   as a call to reset_bmaps to initialize it to the default values.
 - reset_bmaps is also called from early phase4 code to reset all state
   instead of opencoding it.
 - there is a new free_bmaps helper which we call to free our block usage
   bitmaps when we don't need them anymore after phase5.  The current
   code frees some of it a bit early in phase5, but needs to take of it
   in phase6 in case we didn't call phase5 due to nomodify mode, and leaks
   it if we don't call phase 6, which might happen in case of a bad inode
   allocation btree.

Signed-off-by: Barry Naujok <bnaujok@sgi.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Alex Elder <aelder@sgi.com>
Signed-off-by: Alex Elder <aelder@sgi.com>
repair/incore.c
repair/incore.h
repair/phase2.c
repair/phase4.c
repair/phase5.c
repair/phase6.c
repair/xfs_repair.c

index addcdbb3c34da6d913066ca40331f438e6398f85..de0551edc82d972ea6311981c75e8d85833af970 100644 (file)
 #include "err_protos.h"
 #include "threads.h"
 
-/* ba bmap setupstuff.  setting/getting state is in incore.h  */
 
-void
-setup_bmap(xfs_agnumber_t agno, xfs_agblock_t numblocks, xfs_drtbno_t rtblocks)
-{
-       int i;
-       size_t size = 0;
-
-       ba_bmap = (__uint64_t**)malloc(agno*sizeof(__uint64_t *));
-       if (!ba_bmap)
-               do_error(_("couldn't allocate block map pointers\n"));
-       ag_locks = malloc(agno * sizeof(pthread_mutex_t));
-       if (!ag_locks)
-               do_error(_("couldn't allocate block map locks\n"));
-
-       for (i = 0; i < agno; i++)  {
-               size = roundup((numblocks+(NBBY/XR_BB)-1) / (NBBY/XR_BB),
-                               sizeof(__uint64_t));
+static size_t          rt_bmap_size;
 
-               ba_bmap[i] = (__uint64_t*)memalign(sizeof(__uint64_t), size);
-               if (!ba_bmap[i]) {
-                       do_error(_("couldn't allocate block map, size = %d\n"),
-                               numblocks);
-                       return;
-               }
-               memset(ba_bmap[i], 0, size);
-               pthread_mutex_init(&ag_locks[i], NULL);
-       }
+static void
+reset_rt_bmap(void)
+{
+       if (rt_ba_bmap)
+               memset(rt_ba_bmap, 0x22, rt_bmap_size); /* XR_E_FREE */
+}
 
-       if (rtblocks == 0)  {
-               rt_ba_bmap = NULL;
+static void
+init_rt_bmap(
+       xfs_mount_t     *mp)
+{
+       if (mp->m_sb.sb_rextents == 0)
                return;
-       }
 
-       size = roundup(rtblocks / (NBBY/XR_BB), sizeof(__uint64_t));
+       rt_bmap_size = roundup(mp->m_sb.sb_rextents / (NBBY / XR_BB),
+                              sizeof(__uint64_t));
 
-       rt_ba_bmap=(__uint64_t*)memalign(sizeof(__uint64_t), size);
+       rt_ba_bmap = memalign(sizeof(__uint64_t), rt_bmap_size);
        if (!rt_ba_bmap) {
-                       do_error(
+               do_error(
                _("couldn't allocate realtime block map, size = %llu\n"),
-                               rtblocks);
-                       return;
-       }
-
-       /*
-        * start all real-time as free blocks
-        */
-       set_bmap_rt(rtblocks);
-
-       return;
-}
-
-/* ARGSUSED */
-void
-teardown_rt_bmap(xfs_mount_t *mp)
-{
-       if (rt_ba_bmap != NULL)  {
-               free(rt_ba_bmap);
-               rt_ba_bmap = NULL;
+                       mp->m_sb.sb_rextents);
+               return;
        }
-
-       return;
 }
 
-/* ARGSUSED */
-void
-teardown_ag_bmap(xfs_mount_t *mp, xfs_agnumber_t agno)
+static void
+free_rt_bmap(xfs_mount_t *mp)
 {
-       ASSERT(ba_bmap[agno] != NULL);
-
-       free(ba_bmap[agno]);
-       ba_bmap[agno] = NULL;
-
-       return;
+       free(rt_ba_bmap);
+       rt_ba_bmap = NULL;
 }
 
-/* ARGSUSED */
-void
-teardown_bmap_finish(xfs_mount_t *mp)
-{
-       free(ba_bmap);
-       ba_bmap = NULL;
-
-       return;
-}
 
 void
-teardown_bmap(xfs_mount_t *mp)
+reset_bmaps(xfs_mount_t *mp)
 {
-       xfs_agnumber_t i;
-
-       for (i = 0; i < mp->m_sb.sb_agcount; i++)  {
-               teardown_ag_bmap(mp, i);
+       xfs_agnumber_t  agno;
+       int             ag_hdr_block;
+       int             i;
+
+       ag_hdr_block = howmany(4 * mp->m_sb.sb_sectsize, mp->m_sb.sb_blocksize);
+
+       for (agno = 0; agno < mp->m_sb.sb_agcount; agno++)  {
+               memset(ba_bmap[agno], 0,
+                      roundup((mp->m_sb.sb_agblocks + (NBBY / XR_BB) - 1) /
+                               (NBBY / XR_BB), sizeof(__uint64_t)));
+               for (i = 0; i < ag_hdr_block; i++)
+                       set_bmap(agno, i, XR_E_INUSE_FS);
        }
 
-       teardown_rt_bmap(mp);
-       teardown_bmap_finish(mp);
+       if (mp->m_sb.sb_logstart != 0) {
+               xfs_dfsbno_t    logend;
 
-       return;
-}
-
-/*
- * block map initialization routines -- realtime, log, fs
- */
-void
-set_bmap_rt(xfs_drtbno_t num)
-{
-       xfs_drtbno_t j;
-       xfs_drtbno_t size;
-
-       /*
-        * for now, initialize all realtime blocks to be free
-        * (state == XR_E_FREE)
-        */
-       size = howmany(num / (NBBY/XR_BB), sizeof(__uint64_t));
-
-       for (j = 0; j < size; j++)
-               rt_ba_bmap[j] = 0x2222222222222222LL;
-
-       return;
-}
-
-void
-set_bmap_log(xfs_mount_t *mp)
-{
-       xfs_dfsbno_t    logend, i;
-
-       if (mp->m_sb.sb_logstart == 0)
-               return;
-
-       logend = mp->m_sb.sb_logstart + mp->m_sb.sb_logblocks;
+               logend = mp->m_sb.sb_logstart + mp->m_sb.sb_logblocks;
 
-       for (i = mp->m_sb.sb_logstart; i < logend ; i++)  {
-               set_bmap(XFS_FSB_TO_AGNO(mp, i),
-                        XFS_FSB_TO_AGBNO(mp, i), XR_E_INUSE_FS);
+               for (i = mp->m_sb.sb_logstart; i < logend ; i++)  {
+                       set_bmap(XFS_FSB_TO_AGNO(mp, i),
+                                XFS_FSB_TO_AGBNO(mp, i), XR_E_INUSE_FS);
+               }
        }
 
-       return;
+       reset_rt_bmap();
 }
 
 void
-set_bmap_fs(xfs_mount_t *mp)
+init_bmaps(xfs_mount_t *mp)
 {
-       xfs_agnumber_t  i;
-       xfs_agblock_t   j;
-       xfs_agblock_t   end;
+       xfs_agblock_t numblocks = mp->m_sb.sb_agblocks;
+       int agcount = mp->m_sb.sb_agcount;
+       int i;
+       size_t size = 0;
 
-       /*
-        * AG header is 4 sectors
-        */
-       end = howmany(4 * mp->m_sb.sb_sectsize, mp->m_sb.sb_blocksize);
+       ba_bmap = calloc(agcount, sizeof(__uint64_t *));
+       if (!ba_bmap)
+               do_error(_("couldn't allocate block map pointers\n"));
 
-       for (i = 0; i < mp->m_sb.sb_agcount; i++)
-               for (j = 0; j < end; j++)
-                       set_bmap(i, j, XR_E_INUSE_FS);
+       ag_locks = calloc(agcount, sizeof(pthread_mutex_t));
+       if (!ag_locks)
+               do_error(_("couldn't allocate block map locks\n"));
 
-       return;
-}
+       for (i = 0; i < agcount; i++)  {
+               size = roundup((numblocks+(NBBY/XR_BB)-1) / (NBBY/XR_BB),
+                               sizeof(__uint64_t));
 
-#if 0
-void
-set_bmap_fs_bt(xfs_mount_t *mp)
-{
-       xfs_agnumber_t  i;
-       xfs_agblock_t   j;
-       xfs_agblock_t   begin;
-       xfs_agblock_t   end;
-
-       begin = bnobt_root;
-       end = inobt_root + 1;
-
-       for (i = 0; i < mp->m_sb.sb_agcount; i++)  {
-               /*
-                * account for btree roots
-                */
-               for (j = begin; j < end; j++)
-                       set_bmap(i, j, XR_E_INUSE_FS);
+               ba_bmap[i] = memalign(sizeof(__uint64_t), size);
+               if (!ba_bmap[i]) {
+                       do_error(_("couldn't allocate block map, size = %d\n"),
+                               numblocks);
+                       return;
+               }
+               memset(ba_bmap[i], 0, size);
+               pthread_mutex_init(&ag_locks[i], NULL);
        }
 
-       return;
+       init_rt_bmap(mp);
+       reset_bmaps(mp);
 }
-#endif
 
 void
-incore_init(xfs_mount_t *mp)
+free_bmaps(xfs_mount_t *mp)
 {
-       int agcount = mp->m_sb.sb_agcount;
-       extern void incore_ino_init(xfs_mount_t *);
-       extern void incore_ext_init(xfs_mount_t *);
-
-       /* init block alloc bmap */
-
-       setup_bmap(agcount, mp->m_sb.sb_agblocks, mp->m_sb.sb_rextents);
-       incore_ino_init(mp);
-       incore_ext_init(mp);
-
-       /* initialize random globals now that we know the fs geometry */
+       xfs_agnumber_t i;
 
-       inodes_per_block = mp->m_sb.sb_inopblock;
+       for (i = 0; i < mp->m_sb.sb_agcount; i++)
+               free(ba_bmap[i]);
+       free(ba_bmap);
+       ba_bmap = NULL;
 
-       return;
+       free_rt_bmap(mp);
 }
index 82bcb13c34c193ff8a70e43a1bba5f3ffde54fc4..56ea6f6382a87d8125388c8a53e736b879599c6d 100644 (file)
  */
 #define BA_BMAP_SIZE(x)                (howmany(x, 4))
 
-void                   set_bmap_rt(xfs_drfsbno_t numblocks);
-void                   set_bmap_log(xfs_mount_t *mp);
-void                   set_bmap_fs(xfs_mount_t *mp);
-void                   teardown_bmap(xfs_mount_t *mp);
+void                   init_bmaps(xfs_mount_t *mp);
+void                   reset_bmaps(xfs_mount_t *mp);
+void                   free_bmaps(xfs_mount_t *mp);
 
-void                   teardown_rt_bmap(xfs_mount_t *mp);
-void                   teardown_ag_bmap(xfs_mount_t *mp, xfs_agnumber_t agno);
-void                   teardown_bmap_finish(xfs_mount_t *mp);
 
 /* blocks are numbered from zero */
 
@@ -243,6 +239,7 @@ void                release_agbcnt_extent_tree(xfs_agnumber_t agno);
  */
 void           free_rt_dup_extent_tree(xfs_mount_t *mp);
 
+void           incore_ext_init(xfs_mount_t *);
 /*
  * per-AG extent trees shutdown routine -- all (bno, bcnt and dup)
  * at once.  this one actually frees the memory instead of just recyling
@@ -250,6 +247,8 @@ void                free_rt_dup_extent_tree(xfs_mount_t *mp);
  */
 void           incore_ext_teardown(xfs_mount_t *mp);
 
+void           incore_ino_init(xfs_mount_t *);
+
 /*
  * inode definitions
  */
index ac590dfaa523c1fe2615944d08671bd48f95b5af..5d5b9339805ce755ec4de2d471ccb5a9859f9766 100644 (file)
@@ -134,12 +134,6 @@ phase2(xfs_mount_t *mp)
 
        do_log(_("        - scan filesystem freespace and inode maps...\n"));
 
-       /*
-        * account for space used by ag headers and log if internal
-        */
-       set_bmap_log(mp);
-       set_bmap_fs(mp);
-
        bad_ino_btree = 0;
 
        set_progress_msg(PROG_FMT_SCAN_AG, (__uint64_t) glob_agcount);
index 090bd7bfd3f52eae048916db0ec359dd42c5b379..b5c0daea6673fb0015e5244c0f586f48730ee874 100644 (file)
@@ -355,19 +355,7 @@ phase4(xfs_mount_t *mp)
        /*
         * initialize bitmaps for all AGs
         */
-       for (i = 0; i < mp->m_sb.sb_agcount; i++)  {
-               /*
-                * now reset the bitmap for all ags
-                */
-               memset(ba_bmap[i], 0,
-                   roundup((mp->m_sb.sb_agblocks+(NBBY/XR_BB)-1)/(NBBY/XR_BB),
-                                               sizeof(__uint64_t)));
-               for (j = 0; j < ag_hdr_block; j++)
-                       set_bmap(i, j, XR_E_INUSE_FS);
-       }
-       set_bmap_rt(mp->m_sb.sb_rextents);
-       set_bmap_log(mp);
-       set_bmap_fs(mp);
+       reset_bmaps(mp);
 
        do_log(_("        - check for inodes claiming duplicate blocks...\n"));
        set_progress_msg(PROG_FMT_DUP_BLOCKS, (__uint64_t) mp->m_sb.sb_icount);
index d6b765775bb72383875e162fd83939e52294dcc0..e51946f458d174bbfaf0b36c3197ffd6085b83bb 100644 (file)
@@ -1464,11 +1464,6 @@ phase5_func(
                                agno);
                }
 
-               /*
-                * done with the AG bitmap, toss it...
-                */
-               teardown_ag_bmap(mp, agno);
-
                /*
                 * ok, now set up the btree cursors for the
                 * on-disk btrees (includs pre-allocating all
@@ -1655,7 +1650,6 @@ phase5(xfs_mount_t *mp)
                _("        - generate realtime summary info and bitmap...\n"));
                rtinit(mp);
                generate_rtinfo(mp, btmcompute, sumcompute);
-               teardown_rt_bmap(mp);
        }
 
        do_log(_("        - reset superblock...\n"));
index becedbd2738c1a3f91ec682fff769b9d26e24f28..d0560631f9f02b98a651dc1248c71d815d06dfd4 100644 (file)
@@ -3661,11 +3661,6 @@ phase6(xfs_mount_t *mp)
 
        do_log(_("Phase 6 - check inode connectivity...\n"));
 
-       if (!no_modify)
-               teardown_bmap_finish(mp);
-       else
-               teardown_bmap(mp);
-
        incore_ext_teardown(mp);
 
        add_ino_ex_data(mp);
index 9e5dffa0b9a39c1726d5f6192ff3cf89768a6fe4..e36eeae9adfc78a46965235e499710c4e6ea088f 100644 (file)
@@ -39,7 +39,6 @@ extern void   phase4(xfs_mount_t *);
 extern void    phase5(xfs_mount_t *);
 extern void    phase6(xfs_mount_t *);
 extern void    phase7(xfs_mount_t *);
-extern void    incore_init(xfs_mount_t *);
 
 #define                XR_MAX_SECT_SIZE        (64 * 1024)
 
@@ -688,9 +687,14 @@ main(int argc, char **argv)
        calc_mkfs(mp);
 
        /*
-        * check sb filesystem stats and initialize in-core data structures
+        * initialize block alloc map
         */
-       incore_init(mp);
+       init_bmaps(mp);
+       incore_ino_init(mp);
+       incore_ext_init(mp);
+
+       /* initialize random globals now that we know the fs geometry */
+       inodes_per_block = mp->m_sb.sb_inopblock;
 
        if (parse_sb_version(&mp->m_sb))  {
                do_warn(
@@ -718,6 +722,11 @@ main(int argc, char **argv)
        }
        timestamp(PHASE_END, 5, NULL);
 
+       /*
+        * Done with the block usage maps, toss them...
+        */
+       free_bmaps(mp);
+
        if (!bad_ino_btree)  {
                phase6(mp);
                timestamp(PHASE_END, 6, NULL);