bool md_handle_request(struct mddev *mddev, struct bio *bio)
{
check_suspended:
- if (is_suspended(mddev, bio)) {
- /* Bail out if REQ_NOWAIT is set for the bio */
- if (bio->bi_opf & REQ_NOWAIT) {
- bio_wouldblock_error(bio);
- return true;
+ if (unlikely(md_cloned_bio(mddev, bio))) {
+ /*
+ * This bio is an MD cloned bio and already holds an
+ * active_io reference, so percpu_ref_get() is safe here.
+ */
+ percpu_ref_get(&mddev->active_io);
+ } else {
+ if (is_suspended(mddev, bio)) {
+ /* Bail out if REQ_NOWAIT is set for the bio */
+ if (bio->bi_opf & REQ_NOWAIT) {
+ bio_wouldblock_error(bio);
+ return true;
+ }
+ wait_event(mddev->sb_wait, !is_suspended(mddev, bio));
}
- wait_event(mddev->sb_wait, !is_suspended(mddev, bio));
+ if (!percpu_ref_tryget_live(&mddev->active_io))
+ goto check_suspended;
}
- if (!percpu_ref_tryget_live(&mddev->active_io))
- goto check_suspended;
-
if (!mddev->pers->make_request(mddev, bio)) {
percpu_ref_put(&mddev->active_io);
if (mddev_is_dm(mddev) && mddev->pers->prepare_suspend)
extern const struct block_device_operations md_fops;
+static inline bool md_cloned_bio(struct mddev *mddev, struct bio *bio)
+{
+ return bio->bi_pool == &mddev->io_clone_set;
+}
+
/*
* MD devices can be used undeneath by DM, in which case ->gendisk is NULL.
*/