Hello, On Wed, Oct 23, 2013 at 4:35 PM, Filipe David Manana <fdman...@gmail.com> wrote: > On Wed, Oct 23, 2013 at 2:33 PM, Alex Lyakas > <alex.bt...@zadarastorage.com> wrote: >> Hi Filipe, >> >> >> On Tue, Aug 20, 2013 at 2:52 AM, Filipe David Borba Manana >> <fdman...@gmail.com> wrote: >>> >>> This issue is simple to reproduce and observe if kmemleak is enabled. >>> Two simple ways to reproduce it: >>> >>> ** 1 >>> >>> $ mkfs.btrfs -f /dev/loop0 >>> $ mount /dev/loop0 /mnt/btrfs >>> $ btrfs balance start /mnt/btrfs >>> $ umount /mnt/btrfs
So here it seems that the leak can only happen in case the block-group has a free-space inode. This is what the orphan item is added for. Yes, here kmemleak reports. But: if space_cache option is disabled (and nospace_cache) enabled, it seems that btrfs still creates the FREE_SPACE inodes, although they are empty because in cache_save_setup: inode = lookup_free_space_inode(root, block_group, path); if (IS_ERR(inode) && PTR_ERR(inode) != -ENOENT) { ret = PTR_ERR(inode); btrfs_release_path(path); goto out; } if (IS_ERR(inode)) { ... ret = create_free_space_inode(root, trans, block_group, path); and only later it actually sets BTRFS_DC_WRITTEN if space_cache option is disabled. Amazing! Although this is a different issue, do you know perhaps why these empty inodes are needed? Thanks! Alex. >>> >>> ** 2 >>> >>> $ mkfs.btrfs -f /dev/loop0 >>> $ mount /dev/loop0 /mnt/btrfs >>> $ touch /mnt/btrfs/foobar >>> $ rm -f /mnt/btrfs/foobar >>> $ umount /mnt/btrfs >> >> >> I tried the second repro script on kernel 3.8.13, and kmemleak does >> not report a leak (even if I force the kmemleak scan). I did not try >> the balance-repro script, though. Am I missing something? > > Maybe it's not an issue on 3.8.13 and older releases. > This was on btrfs-next from August 19. > > thanks for testing > >> >> Thanks, >> Alex. >> >> >>> >>> >>> After a while, kmemleak reports the leak: >>> >>> $ cat /sys/kernel/debug/kmemleak >>> unreferenced object 0xffff880402b13e00 (size 128): >>> comm "btrfs", pid 19621, jiffies 4341648183 (age 70057.844s) >>> hex dump (first 32 bytes): >>> 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ >>> 00 fc c6 b1 04 88 ff ff 04 00 04 00 ad 4e ad de .............N.. >>> backtrace: >>> [<ffffffff817275a6>] kmemleak_alloc+0x26/0x50 >>> [<ffffffff8117832b>] kmem_cache_alloc_trace+0xeb/0x1d0 >>> [<ffffffffa04db499>] btrfs_alloc_block_rsv+0x39/0x70 [btrfs] >>> [<ffffffffa04f8bad>] btrfs_orphan_add+0x13d/0x1b0 [btrfs] >>> [<ffffffffa04e2b13>] btrfs_remove_block_group+0x143/0x500 [btrfs] >>> [<ffffffffa0518158>] btrfs_relocate_chunk.isra.63+0x618/0x790 [btrfs] >>> [<ffffffffa051bc27>] btrfs_balance+0x8f7/0xe90 [btrfs] >>> [<ffffffffa05240a0>] btrfs_ioctl_balance+0x250/0x550 [btrfs] >>> [<ffffffffa05269ca>] btrfs_ioctl+0xdfa/0x25f0 [btrfs] >>> [<ffffffff8119c936>] do_vfs_ioctl+0x96/0x570 >>> [<ffffffff8119cea1>] SyS_ioctl+0x91/0xb0 >>> [<ffffffff81750242>] system_call_fastpath+0x16/0x1b >>> [<ffffffffffffffff>] 0xffffffffffffffff >>> >>> This affects btrfs-next, revision be8e3cd00d7293dd177e3f8a4a1645ce09ca3acb >>> (Btrfs: separate out tests into their own directory). >>> >>> Signed-off-by: Filipe David Borba Manana <fdman...@gmail.com> >>> --- >>> >>> V2: removed atomic_t member in struct btrfs_block_rsv, as suggested by >>> Josef Bacik, and use instead the condition reserved == 0 to decide >>> when to free the block. >>> V3: simplified patch, just kfree() (and not btrfs_free_block_rsv) the >>> root's orphan_block_rsv when free'ing the root. Thanks Josef for >>> the suggestion. >>> V4: use btrfs_free_block_rsv() instead of kfree(). The error I was getting >>> in xfstests when using btrfs_free_block_rsv() was unrelated, Josef just >>> pointed it to me (separate issue). >>> V5: move the free call below the iput() call, so that btrfs_evict_node() >>> can process the orphan_block_rsv first to do some needed cleanup before >>> we free it. >>> V6: free the root's orphan_block_rsv in close_ctree() too. After a balance >>> the orphan_block_rsv of the tree of tree roots was being leaked, because >>> free_fs_root() is only called for filesystem trees. >>> >>> fs/btrfs/disk-io.c | 5 +++++ >>> 1 file changed, 5 insertions(+) >>> >>> diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c >>> index 3b12c26..5d17163 100644 >>> --- a/fs/btrfs/disk-io.c >>> +++ b/fs/btrfs/disk-io.c >>> @@ -3430,6 +3430,8 @@ static void free_fs_root(struct btrfs_root *root) >>> { >>> iput(root->cache_inode); >>> WARN_ON(!RB_EMPTY_ROOT(&root->inode_tree)); >>> + btrfs_free_block_rsv(root, root->orphan_block_rsv); >>> + root->orphan_block_rsv = NULL; >>> if (root->anon_dev) >>> free_anon_bdev(root->anon_dev); >>> free_extent_buffer(root->node); >>> @@ -3582,6 +3584,9 @@ int close_ctree(struct btrfs_root *root) >>> >>> btrfs_free_stripe_hash_table(fs_info); >>> >>> + btrfs_free_block_rsv(root, root->orphan_block_rsv); >>> + root->orphan_block_rsv = NULL; >>> + >>> return 0; >>> } >>> >>> -- >>> 1.7.9.5 >>> >>> -- >>> To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in >>> the body of a message to majord...@vger.kernel.org >>> More majordomo info at http://vger.kernel.org/majordomo-info.html > > > > -- > Filipe David Manana, > > "Reasonable men adapt themselves to the world. > Unreasonable men adapt the world to themselves. > That's why all progress depends on unreasonable men." -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html