]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
md: move freeing of badblocks.page into md_rdev_clear
authorNeilBrown <neilb@suse.de>
Tue, 24 Apr 2012 00:57:51 +0000 (10:57 +1000)
committerNeilBrown <neilb@suse.de>
Tue, 24 Apr 2012 00:57:51 +0000 (10:57 +1000)
This ensures that it is always freed - there were case where
we failed to free the page.

Reported-by: majianpeng <majianpeng@gmail.com>
Signed-off-by: NeilBrown <neilb@suse.de>
drivers/md/md.c

index 11e12ba0f61b4944650312d1631f6045d2625148..d677d9dbcd6f9a4da978c943216bb3a8a6ca5af3 100644 (file)
@@ -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);
 }