|
|
@@ -203,6 +203,14 @@ struct bio *bio_alloc_mddev(gfp_t gfp_mask, int nr_iovecs,
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(bio_alloc_mddev);
|
|
|
|
|
|
+static struct bio *md_bio_alloc_sync(struct mddev *mddev)
|
|
|
+{
|
|
|
+ if (!mddev->sync_set)
|
|
|
+ return bio_alloc(GFP_NOIO, 1);
|
|
|
+
|
|
|
+ return bio_alloc_bioset(GFP_NOIO, 1, mddev->sync_set);
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* We have a system wide 'event count' that is incremented
|
|
|
* on any 'interesting' event, and readers of /proc/mdstat
|
|
|
@@ -467,8 +475,6 @@ static void mddev_delayed_delete(struct work_struct *ws);
|
|
|
|
|
|
static void mddev_put(struct mddev *mddev)
|
|
|
{
|
|
|
- struct bio_set *bs = NULL;
|
|
|
-
|
|
|
if (!atomic_dec_and_lock(&mddev->active, &all_mddevs_lock))
|
|
|
return;
|
|
|
if (!mddev->raid_disks && list_empty(&mddev->disks) &&
|
|
|
@@ -476,8 +482,12 @@ static void mddev_put(struct mddev *mddev)
|
|
|
/* Array is not configured at all, and not held active,
|
|
|
* so destroy it */
|
|
|
list_del_init(&mddev->all_mddevs);
|
|
|
- bs = mddev->bio_set;
|
|
|
+ if (mddev->bio_set)
|
|
|
+ bioset_free(mddev->bio_set);
|
|
|
+ if (mddev->sync_set)
|
|
|
+ bioset_free(mddev->sync_set);
|
|
|
mddev->bio_set = NULL;
|
|
|
+ mddev->sync_set = NULL;
|
|
|
if (mddev->gendisk) {
|
|
|
/* We did a probe so need to clean up. Call
|
|
|
* queue_work inside the spinlock so that
|
|
|
@@ -490,8 +500,6 @@ static void mddev_put(struct mddev *mddev)
|
|
|
kfree(mddev);
|
|
|
}
|
|
|
spin_unlock(&all_mddevs_lock);
|
|
|
- if (bs)
|
|
|
- bioset_free(bs);
|
|
|
}
|
|
|
|
|
|
static void md_safemode_timeout(unsigned long data);
|
|
|
@@ -756,7 +764,7 @@ void md_super_write(struct mddev *mddev, struct md_rdev *rdev,
|
|
|
if (test_bit(Faulty, &rdev->flags))
|
|
|
return;
|
|
|
|
|
|
- bio = bio_alloc_mddev(GFP_NOIO, 1, mddev);
|
|
|
+ bio = md_bio_alloc_sync(mddev);
|
|
|
|
|
|
atomic_inc(&rdev->nr_pending);
|
|
|
|
|
|
@@ -788,7 +796,7 @@ int md_super_wait(struct mddev *mddev)
|
|
|
int sync_page_io(struct md_rdev *rdev, sector_t sector, int size,
|
|
|
struct page *page, int op, int op_flags, bool metadata_op)
|
|
|
{
|
|
|
- struct bio *bio = bio_alloc_mddev(GFP_NOIO, 1, rdev->mddev);
|
|
|
+ struct bio *bio = md_bio_alloc_sync(rdev->mddev);
|
|
|
int ret;
|
|
|
|
|
|
bio->bi_bdev = (metadata_op && rdev->meta_bdev) ?
|
|
|
@@ -5437,6 +5445,11 @@ int md_run(struct mddev *mddev)
|
|
|
if (!mddev->bio_set)
|
|
|
return -ENOMEM;
|
|
|
}
|
|
|
+ if (mddev->sync_set == NULL) {
|
|
|
+ mddev->sync_set = bioset_create(BIO_POOL_SIZE, 0);
|
|
|
+ if (!mddev->sync_set)
|
|
|
+ return -ENOMEM;
|
|
|
+ }
|
|
|
|
|
|
spin_lock(&pers_lock);
|
|
|
pers = find_pers(mddev->level, mddev->clevel);
|