From: Yu Kuai <[email protected]>

dm-pcache may preallocate backing requests with GFP_NOWAIT and initialize
the embedded bio with bio_init_clone().  Non-blocking clone initialization
can now fail if cloning the blkg association would need to create a blkg.

Check the return value and free the preallocated request on failure so the
existing caller can retry through its GFP_NOIO preallocation path.

Signed-off-by: Yu Kuai <[email protected]>
---
 drivers/md/dm-pcache/backing_dev.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/md/dm-pcache/backing_dev.c 
b/drivers/md/dm-pcache/backing_dev.c
index 7165fc0364bb..5bde289ec5d7 100644
--- a/drivers/md/dm-pcache/backing_dev.c
+++ b/drivers/md/dm-pcache/backing_dev.c
@@ -204,6 +204,7 @@ static struct pcache_backing_dev_req 
*req_type_req_alloc(struct pcache_backing_d
        struct pcache_request *pcache_req = opts->req.upper_req;
        struct pcache_backing_dev_req *backing_req;
        struct bio *orig = pcache_req->bio;
+       int ret;
 
        backing_req = mempool_alloc(&backing_dev->req_pool, opts->gfp_mask);
        if (!backing_req)
@@ -211,13 +212,20 @@ static struct pcache_backing_dev_req 
*req_type_req_alloc(struct pcache_backing_d
 
        memset(backing_req, 0, sizeof(struct pcache_backing_dev_req));
 
-       bio_init_clone(backing_dev->dm_dev->bdev, &backing_req->bio, orig, 
opts->gfp_mask);
+       ret = bio_init_clone(backing_dev->dm_dev->bdev, &backing_req->bio,
+                            orig, opts->gfp_mask);
+       if (ret)
+               goto free_backing_req;
 
        backing_req->type = BACKING_DEV_REQ_TYPE_REQ;
        backing_req->backing_dev = backing_dev;
        atomic_inc(&backing_dev->inflight_reqs);
 
        return backing_req;
+
+free_backing_req:
+       mempool_free(backing_req, &backing_dev->req_pool);
+       return NULL;
 }
 
 static struct pcache_backing_dev_req *kmem_type_req_alloc(struct 
pcache_backing_dev *backing_dev,
-- 
2.51.0


Reply via email to