md:Fix mem leak about rdev->badblocks.page.
PATCH 1/1 md:Fix mem leak about rdev->badblocks.page.
From 7cc5b99748a5505d94d6e67ba4e639e341f0a00a Mon Sep 17 00:00:00 2001
From: majianpeng <[email protected]>
Date: Wed, 11 Apr 2012 15:44:55 +0800
Subject: [PATCH] md:Fix mem leak about rdev->badblocks.page. When exec
md_import_device(),alloc badblocks.page.But met error when exec bind_rdev_to_array().So exec export_rdev().But export_rdev() did not free badblocks.page.
This may occur in those functions:
1:add_new_disk()
2:new_dev_store()
Reported by kmemleak:
unreferenced object 0xffff88008223d668 (size 4096):
comm "mdadm", pid 9497, jiffies 4295848888 (age 21898.212s) hex dump (first 32 bytes):
6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
backtrace:
[<ffffffff81695ec1>] kmemleak_alloc+0x21/0x50
[<ffffffff811180fd>] kmem_cache_alloc_trace+0xad/0x1b0
[<ffffffffa0003b78>] md_rdev_init+0xd8/0x130 [md_mod]
[<ffffffffa0007e28>] md_import_device+0x58/0x2a0 [md_mod]
[<ffffffffa001199e>] add_new_disk+0x178/0x49d [md_mod]
[<ffffffffa000d78e>] md_ioctl+0xb8e/0x11f0 [md_mod]
[<ffffffff8127aa18>] blkdev_ioctl+0xd8/0x790
[<ffffffff8115416b>] block_ioctl+0x3b/0x40
[<ffffffff81131cc6>] do_vfs_ioctl+0x96/0x550
[<ffffffff81132211>] sys_ioctl+0x91/0xa0
[<ffffffff816bc9a2>] system_call_fastpath+0x16/0x1b
[<ffffffffffffffff>] 0xffffffffffffffff--- drivers/md/md.c | 5 +++++ 1 files changed, 5 insertions(+), 0 deletions(-)
drivers/md/md.c +5 -0
@@ -813,6 +813,7 @@ static void free_disk_sb(struct md_rdev * rdev)put_page (rdev->bb_page); rdev->bb_page =NULL ; } + }
@@ -2161,6 +2162,10 @@ static void export_rdev(struct md_rdev * rdev)if (test_bit (AutoDetected, &rdev->flags))md_autodetect_dev (rdev->bdev->bd_dev);#endif +if (rdev->badblocks.page) { +kfree (rdev->badblocks.page); + rdev->badblocks.page =NULL ; + }unlock_rdev (rdev);kobject_put (&rdev->kobj); }
Signature · 6 lines
1.7.5.4 -------------- majianpeng 2012-04-11
Quoted 11 lines · On Wed, 11 Apr 2012 15:58:27 +0800 "majianpeng" <[email protected]> wrote:
Quoted 1 line
From
7cc5b99748a5505d94d6e67ba4e639e341f0a00aMon Sep 17 00:00:00 2001From: majianpeng <[email protected]>
Date: Wed, 11 Apr 2012 15:44:55 +0800
Subject: [PATCH] md:Fix mem leak aboutrdev->badblocks.page. When exec
md_import_device(),alloc badblocks.page.But met error when exec bind_rdev_to_array().So exec export_rdev().Butexport_rdev()did not free badblocks.page.This may occur in those functions:
1:add_new_disk()
2:new_dev_store()
Thanks for the report.
I have chosen to fix it slightly differently - by doing the 'free' in free_disk_sb, which I have since renamed to md_rdev_clear.
Here is that patch I have committed.
Thanks,
NeilBrown
From 79a97ee9d3ce9c36a855ac2217ad946856f98d25 Mon Sep 17 00:00:00 2001
From: NeilBrown <[email protected]>
Date: Tue, 17 Apr 2012 11:52:56 +1000
Subject: [PATCH] md: move freeing of badblocks.page into md_rdev_clear
This ensures that it is always freed - there were case where we failed to free the page.
drivers/md/md.c +4 -3
@@ -814,6 +814,10 @@ void md_rdev_clear(struct md_rdev *rdev)put_page (rdev->bb_page); rdev->bb_page =NULL ; } +if (rdev->badblocks.page) { +kfree (rdev->badblocks.page); + rdev->badblocks.page =NULL ; + } }EXPORT_SYMBOL_GPL (md_rdev_clear);
@@ -2189,9 +2193,7 @@ static void unbind_rdev_from_array(struct md_rdev * rdev)sysfs_remove_link (&rdev->kobj,"block" );sysfs_put (rdev->sysfs_state); rdev->sysfs_state =NULL ; -kfree (rdev->badblocks.page); rdev->badblocks.count =0 ; - rdev->badblocks.page =NULL ;/* We need to delay this, otherwise we can deadlock when * writing to 'remove' to "dev/state". We also need * to delay it due to rcu usage.
@@ -3323,7 +3325,6 @@ abort_free:if (rdev->bdev)unlock_rdev (rdev);md_rdev_clear (rdev); -kfree (rdev->badblocks.page);kfree (rdev);return ERR_PTR (err); }