summaryrefslogtreecommitdiffstats
path: root/drivers/md
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2022-07-19 11:18:17 +0200
committerJens Axboe <axboe@kernel.dk>2022-08-03 01:22:43 +0200
commite8c59ac41974438168c89e2c881119c53934f96c (patch)
treedd02b963c306d5ea6bdcb2b09eb13708be136871 /drivers/md
parentmd: fix error handling in md_alloc (diff)
downloadlinux-e8c59ac41974438168c89e2c881119c53934f96c.tar.xz
linux-e8c59ac41974438168c89e2c881119c53934f96c.zip
md: implement ->free_disk
Ensure that all private data is only freed once all accesses are done. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Logan Gunthorpe <logang@deltatee.com> Reviewed-by: Hannes Reinecke <hare@suse.de> Signed-off-by: Song Liu <song@kernel.org> Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'drivers/md')
-rw-r--r--drivers/md/md.c18
1 files changed, 12 insertions, 6 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c
index c1439d5ab9b1..e07a6f26116c 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -5600,12 +5600,6 @@ static void md_free(struct kobject *ko)
del_gendisk(mddev->gendisk);
put_disk(mddev->gendisk);
-
- percpu_ref_exit(&mddev->writes_pending);
-
- bioset_exit(&mddev->bio_set);
- bioset_exit(&mddev->sync_set);
- kfree(mddev);
}
static const struct sysfs_ops md_sysfs_ops = {
@@ -7875,6 +7869,17 @@ static unsigned int md_check_events(struct gendisk *disk, unsigned int clearing)
return ret;
}
+static void md_free_disk(struct gendisk *disk)
+{
+ struct mddev *mddev = disk->private_data;
+
+ percpu_ref_exit(&mddev->writes_pending);
+ bioset_exit(&mddev->bio_set);
+ bioset_exit(&mddev->sync_set);
+
+ kfree(mddev);
+}
+
const struct block_device_operations md_fops =
{
.owner = THIS_MODULE,
@@ -7888,6 +7893,7 @@ const struct block_device_operations md_fops =
.getgeo = md_getgeo,
.check_events = md_check_events,
.set_read_only = md_set_read_only,
+ .free_disk = md_free_disk,
};
static int md_thread(void *arg)