* [PATCH 0/4] xfsprogs: fix some xfs_repair memory leaks
@ 2015-08-20 18:06 Eric Sandeen
2015-08-20 18:08 ` [PATCH 1/4] xfsprogs: Free all data in libxfs_umount; call from xfs_copy as well Eric Sandeen
` (3 more replies)
0 siblings, 4 replies; 6+ messages in thread
From: Eric Sandeen @ 2015-08-20 18:06 UTC (permalink / raw)
To: xfs-oss
This fixes the fairly trivial "definitely lost" leaks spotted by valgrind
on a trivial xfs_repair run, two of which are coverity-spotted.
Dave, I *did* do a quick test via ./check -g quick, this time. :)
Thanks,
-Eric
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 1/4] xfsprogs: Free all data in libxfs_umount; call from xfs_copy as well
2015-08-20 18:06 [PATCH 0/4] xfsprogs: fix some xfs_repair memory leaks Eric Sandeen
@ 2015-08-20 18:08 ` Eric Sandeen
2015-08-24 1:51 ` Dave Chinner
2015-08-20 18:09 ` [PATCH 2/4] xfs_repair: free msgbuf on exit Eric Sandeen
` (2 subsequent siblings)
3 siblings, 1 reply; 6+ messages in thread
From: Eric Sandeen @ 2015-08-20 18:08 UTC (permalink / raw)
To: xfs-oss
libxfs_umount was failing to free a handful of resources; fix that up.
Call it from xfs_copy as well, while we're at it; every other libxfs_mount
has a libxfs_umount counterpart, at least on a clean exit.
Signed-off-by: Eric Sandeen <sandeen@redhat.com>
---
copy/xfs_copy.c | 2 ++
libxfs/init.c | 9 +++++++++
2 files changed, 11 insertions(+), 0 deletions(-)
diff --git a/copy/xfs_copy.c b/copy/xfs_copy.c
index e13f468..4497b7f 100644
--- a/copy/xfs_copy.c
+++ b/copy/xfs_copy.c
@@ -1165,6 +1165,8 @@ main(int argc, char **argv)
}
check_errors();
+ libxfs_umount(mp);
+
return 0;
}
diff --git a/libxfs/init.c b/libxfs/init.c
index 2859f94..c7f9dc8 100644
--- a/libxfs/init.c
+++ b/libxfs/init.c
@@ -832,6 +832,15 @@ libxfs_umount(xfs_mount_t *mp)
pag = radix_tree_delete(&mp->m_perag_tree, agno);
kmem_free(pag);
}
+
+ kmem_free(mp->m_attr_geo);
+ kmem_free(mp->m_dir_geo);
+
+ kmem_free(mp->m_rtdev_targp);
+ if (mp->m_logdev_targp != mp->m_ddev_targp)
+ kmem_free(mp->m_logdev_targp);
+ kmem_free(mp->m_ddev_targp);
+
}
/*
-- 1.7.1
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 2/4] xfs_repair: free msgbuf on exit
2015-08-20 18:06 [PATCH 0/4] xfsprogs: fix some xfs_repair memory leaks Eric Sandeen
2015-08-20 18:08 ` [PATCH 1/4] xfsprogs: Free all data in libxfs_umount; call from xfs_copy as well Eric Sandeen
@ 2015-08-20 18:09 ` Eric Sandeen
2015-08-20 18:10 ` [PATCH 3/4] xfs_repair: call IRELE(ip) after libxfs_trans_iget calls Eric Sandeen
2015-08-20 18:11 ` [PATCH 4/4] xfs_repair: unconditionally free blockmaps when threads complete Eric Sandeen
3 siblings, 0 replies; 6+ messages in thread
From: Eric Sandeen @ 2015-08-20 18:09 UTC (permalink / raw)
To: xfs-oss
Just to keep valgrind less noisy, and make it easiser to spot
more things that actually matter ...
Signed-off-by: Eric Sandeen <sandeen@redhat.com>
---
repair/xfs_repair.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/repair/xfs_repair.c b/repair/xfs_repair.c
index db703d0..85a012b 100644
--- a/repair/xfs_repair.c
+++ b/repair/xfs_repair.c
@@ -946,5 +946,7 @@ _("Repair of readonly mount complete. Immediate reboot encouraged.\n"));
pftrace_done();
+ free(msgbuf);
+
return (0);
}
-- 1.7.1
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 3/4] xfs_repair: call IRELE(ip) after libxfs_trans_iget calls
2015-08-20 18:06 [PATCH 0/4] xfsprogs: fix some xfs_repair memory leaks Eric Sandeen
2015-08-20 18:08 ` [PATCH 1/4] xfsprogs: Free all data in libxfs_umount; call from xfs_copy as well Eric Sandeen
2015-08-20 18:09 ` [PATCH 2/4] xfs_repair: free msgbuf on exit Eric Sandeen
@ 2015-08-20 18:10 ` Eric Sandeen
2015-08-20 18:11 ` [PATCH 4/4] xfs_repair: unconditionally free blockmaps when threads complete Eric Sandeen
3 siblings, 0 replies; 6+ messages in thread
From: Eric Sandeen @ 2015-08-20 18:10 UTC (permalink / raw)
To: xfs-oss
Commit 260c85e libxfs: dont free xfs_inode until complete
changed the alloc/free convention a bit:
Originally, the xfs_inode are released upon the first
call to xfs_trans_cancel, xfs_trans_commit, or
inode_item_done.
<snip>
This patch does the following:
1) Removes the iput from the transaction completion and
requires that the xfs_inode allocators call IRELE()
when they are done with the pointer.
But that change missed several callers in xfs_repair phase6;
fix that up.
Addresses-Coverity-Id: 1315100
Addresses-Coverity-Id: 1315101
Signed-off-by: Eric Sandeen <sandeen@redhat.com>
---
repair/phase6.c | 6 ++++++
1 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/repair/phase6.c b/repair/phase6.c
index 9cfedbf..04638c2 100644
--- a/repair/phase6.c
+++ b/repair/phase6.c
@@ -585,6 +585,7 @@ mk_rbmino(xfs_mount_t *mp)
error);
}
libxfs_trans_commit(tp);
+ IRELE(ip);
}
static int
@@ -654,6 +655,7 @@ _("can't access block %" PRIu64 " (fsbno %" PRIu64 ") of realtime bitmap inode %
}
libxfs_trans_commit(tp);
+ IRELE(ip);
return(0);
}
@@ -714,6 +716,7 @@ fill_rsumino(xfs_mount_t *mp)
do_warn(
_("can't access block %" PRIu64 " (fsbno %" PRIu64 ") of realtime summary inode %" PRIu64 "\n"),
bno, map.br_startblock, mp->m_sb.sb_rsumino);
+ IRELE(ip);
return(1);
}
@@ -726,6 +729,7 @@ _("can't access block %" PRIu64 " (fsbno %" PRIu64 ") of realtime summary inode
}
libxfs_trans_commit(tp);
+ IRELE(ip);
return(0);
}
@@ -846,6 +850,7 @@ mk_rsumino(xfs_mount_t *mp)
error);
}
libxfs_trans_commit(tp);
+ IRELE(ip);
}
/*
@@ -920,6 +925,7 @@ mk_root_dir(xfs_mount_t *mp)
libxfs_dir_init(tp, ip, ip);
libxfs_trans_commit(tp);
+ IRELE(ip);
irec = find_inode_rec(mp, XFS_INO_TO_AGNO(mp, mp->m_sb.sb_rootino),
XFS_INO_TO_AGINO(mp, mp->m_sb.sb_rootino));
-- 1.7.1
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 4/4] xfs_repair: unconditionally free blockmaps when threads complete
2015-08-20 18:06 [PATCH 0/4] xfsprogs: fix some xfs_repair memory leaks Eric Sandeen
` (2 preceding siblings ...)
2015-08-20 18:10 ` [PATCH 3/4] xfs_repair: call IRELE(ip) after libxfs_trans_iget calls Eric Sandeen
@ 2015-08-20 18:11 ` Eric Sandeen
3 siblings, 0 replies; 6+ messages in thread
From: Eric Sandeen @ 2015-08-20 18:11 UTC (permalink / raw)
To: xfs-oss
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@redhat.com>
---
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@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH 1/4] xfsprogs: Free all data in libxfs_umount; call from xfs_copy as well
2015-08-20 18:08 ` [PATCH 1/4] xfsprogs: Free all data in libxfs_umount; call from xfs_copy as well Eric Sandeen
@ 2015-08-24 1:51 ` Dave Chinner
0 siblings, 0 replies; 6+ messages in thread
From: Dave Chinner @ 2015-08-24 1:51 UTC (permalink / raw)
To: Eric Sandeen; +Cc: xfs-oss
On Thu, Aug 20, 2015 at 01:08:27PM -0500, Eric Sandeen wrote:
> libxfs_umount was failing to free a handful of resources; fix that up.
> Call it from xfs_copy as well, while we're at it; every other libxfs_mount
> has a libxfs_umount counterpart, at least on a clean exit.
xfs/077 6s ... - output mismatch (see /home/dave/src/xfstests-dev/results//xfs/077.out.bad)
--- tests/xfs/077.out 2015-08-05 15:00:15.000000000 +1000
+++ /home/dave/src/xfstests-dev/results//xfs/077.out.bad 2015-08-24 11:35:42.000000000 +1000
@@ -18,4 +18,6 @@
writing all SBs
new UUID = <EXACTUUID>
== xfs_copy with new UUID
+cache_purge: shake on cache 0x64b2e0 left 1 nodes!?
== xfs_copy with duplicate UUID
+cache_purge: shake on cache 0x64b2e0 left 1 nodes!?
...
It would seem that this exposes a buffer refcount issue in xfs_copy?
Oh, yeah, the superblock. Patch modified to include this hunk:
@@ -696,6 +696,7 @@ main(int argc, char **argv)
sbp = libxfs_readbuf(mbuf.m_ddev_targp, XFS_SB_DADDR,
1 << (sb->sb_sectlog - BBSHIFT),
0, &xfs_sb_buf_ops);
+ libxfs_putbuf(sbp);
mp = libxfs_mount(&mbuf, sb, xargs.ddev, xargs.logdev, xargs.rtdev, 0);
if (mp == NULL) {
Which makes the immediate problem go away.
Eric, can you send another patch here to abort xfs_copy if the
superblock is detected as corrupt by the verifier?
Cheers,
Dave.
--
Dave Chinner
david@fromorbit.com
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2015-08-24 1:51 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-08-20 18:06 [PATCH 0/4] xfsprogs: fix some xfs_repair memory leaks Eric Sandeen
2015-08-20 18:08 ` [PATCH 1/4] xfsprogs: Free all data in libxfs_umount; call from xfs_copy as well Eric Sandeen
2015-08-24 1:51 ` Dave Chinner
2015-08-20 18:09 ` [PATCH 2/4] xfs_repair: free msgbuf on exit Eric Sandeen
2015-08-20 18:10 ` [PATCH 3/4] xfs_repair: call IRELE(ip) after libxfs_trans_iget calls Eric Sandeen
2015-08-20 18:11 ` [PATCH 4/4] xfs_repair: unconditionally free blockmaps when threads complete Eric Sandeen
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox