blkmap_free() doesn't actually free the block map unless it's inordinately large; this keeps us from constantly freeing and re-allocating blockmaps for each inode, which makes sense. However, once the threads which have allocated these structures exit, we should actually free them; they can grow up to 2MB for each of the data and attr maps, for each thread, and not be freed through the normal blkmap_free() test. Signed-off-by: Eric Sandeen <sandeen@xxxxxxxxxx> --- repair/bmap.c | 17 ++++++++++++++++- repair/bmap.h | 1 + repair/phase3.c | 2 ++ repair/phase4.c | 1 + 4 files changed, 20 insertions(+), 1 deletions(-) diff --git a/repair/bmap.c b/repair/bmap.c index 2655632..abe9f48 100644 --- a/repair/bmap.c +++ b/repair/bmap.c @@ -82,7 +82,8 @@ blkmap_alloc( * extents) then free it to release the memory. This prevents us from pinning * large tracts of memory due to corrupted fork values or one-off fragmented * files. Otherwise we have nothing to do but keep the memory around for the - * next inode + * next inode. + * When the thread is done, it should do an unconditional, final free. */ void blkmap_free( @@ -103,6 +104,20 @@ blkmap_free( free(blkmap); } +void +blkmap_free_final(void) +{ + blkmap_t *blkmap; + + blkmap = pthread_getspecific(dblkmap_key); + pthread_setspecific(dblkmap_key, NULL); + free(blkmap); + + blkmap = pthread_getspecific(ablkmap_key); + pthread_setspecific(ablkmap_key, NULL); + free(blkmap); +} + /* * Get one entry from a block map. */ diff --git a/repair/bmap.h b/repair/bmap.h index 973081a..501ef6b 100644 --- a/repair/bmap.h +++ b/repair/bmap.h @@ -58,6 +58,7 @@ extern pthread_key_t ablkmap_key; blkmap_t *blkmap_alloc(xfs_extnum_t nex, int whichfork); void blkmap_free(blkmap_t *blkmap); +void blkmap_free_final(void); int blkmap_set_ext(blkmap_t **blkmapp, xfs_fileoff_t o, xfs_fsblock_t b, xfs_filblks_t c); diff --git a/repair/phase3.c b/repair/phase3.c index 20786af..76c9440 100644 --- a/repair/phase3.c +++ b/repair/phase3.c @@ -27,6 +27,7 @@ #include "err_protos.h" #include "dinode.h" #include "progress.h" +#include "bmap.h" static void process_agi_unlinked( @@ -75,6 +76,7 @@ process_ag_func( wait_for_inode_prefetch(arg); do_log(_(" - agno = %d\n"), agno); process_aginodes(wq->mp, arg, agno, 1, 0, 1); + blkmap_free_final(); cleanup_inode_prefetch(arg); } diff --git a/repair/phase4.c b/repair/phase4.c index e0571e8..1a7d7b5 100644 --- a/repair/phase4.c +++ b/repair/phase4.c @@ -138,6 +138,7 @@ process_ag_func( wait_for_inode_prefetch(arg); do_log(_(" - agno = %d\n"), agno); process_aginodes(wq->mp, arg, agno, 0, 1, 0); + blkmap_free_final(); cleanup_inode_prefetch(arg); /* -- 1.7.1 _______________________________________________ xfs mailing list xfs@xxxxxxxxxxx http://oss.sgi.com/mailman/listinfo/xfs