md: centralise all freeing of an 'mddev' in 'md_free'
authorNeilBrown <neilb@suse.de>
Thu, 8 Jan 2009 21:31:09 +0000 (08:31 +1100)
committerNeilBrown <neilb@suse.de>
Thu, 8 Jan 2009 21:31:09 +0000 (08:31 +1100)
md_free is the .release handler for the md kobj_type.
So it makes sense to release all the objects referenced by
the mddev in there, rather than just prior to calling kobject_put
for what we think is the last time.

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

index da838cc32cc9f3d9247a93e4a7b1c8feeb751664..970a8c42ba92f96c27df9eba78ae431b2480c847 100644 (file)
@@ -221,12 +221,6 @@ static void mddev_put(mddev_t *mddev)
        if (!mddev->raid_disks && list_empty(&mddev->disks)) {
                list_del(&mddev->all_mddevs);
                spin_unlock(&all_mddevs_lock);
-               if (mddev->queue)
-                       blk_cleanup_queue(mddev->queue);
-               mddev->queue = NULL;
-               if (mddev->sysfs_state)
-                       sysfs_put(mddev->sysfs_state);
-               mddev->sysfs_state = NULL;
                kobject_put(&mddev->kobj);
        } else
                spin_unlock(&all_mddevs_lock);
@@ -3451,6 +3445,17 @@ md_attr_store(struct kobject *kobj, struct attribute *attr,
 static void md_free(struct kobject *ko)
 {
        mddev_t *mddev = container_of(ko, mddev_t, kobj);
+
+       if (mddev->sysfs_state)
+               sysfs_put(mddev->sysfs_state);
+
+       if (mddev->gendisk) {
+               del_gendisk(mddev->gendisk);
+               put_disk(mddev->gendisk);
+       }
+       if (mddev->queue)
+               blk_cleanup_queue(mddev->queue);
+
        kfree(mddev);
 }
 
@@ -6435,9 +6440,6 @@ static __exit void md_exit(void)
                if (!disk)
                        continue;
                export_array(mddev);
-               del_gendisk(disk);
-               put_disk(disk);
-               mddev->gendisk = NULL;
                mddev_put(mddev);
        }
 }