Message ID | 1523505895-99462-1-git-send-email-cgxu519@gmx.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Thu, Apr 12, 2018 at 6:04 AM, Chengguang Xu <cgxu519@gmx.com> wrote: > Add proper error handling for osd_req_op_cls_init() to replace > BUG_ON statement when failing from memory allocation. > > Signed-off-by: Chengguang Xu <cgxu519@gmx.com> > --- > drivers/block/rbd.c | 8 ++++++-- > include/linux/ceph/osd_client.h | 2 +- > net/ceph/osd_client.c | 12 +++++++++--- > 3 files changed, 16 insertions(+), 6 deletions(-) > > diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c > index 7320466..ebd1d79 100644 > --- a/drivers/block/rbd.c > +++ b/drivers/block/rbd.c > @@ -2348,6 +2348,7 @@ static bool is_zero_bvecs(struct bio_vec *bvecs, u32 bytes) > static int rbd_obj_issue_copyup(struct rbd_obj_request *obj_req, u32 bytes) > { > unsigned int num_osd_ops = obj_req->osd_req->r_num_ops; > + int err; > > dout("%s obj_req %p bytes %u\n", __func__, obj_req, bytes); > rbd_assert(obj_req->osd_req->r_ops[0].op == CEPH_OSD_OP_STAT); > @@ -2362,6 +2363,11 @@ static int rbd_obj_issue_copyup(struct rbd_obj_request *obj_req, u32 bytes) > if (!obj_req->osd_req) > return -ENOMEM; > > + err = osd_req_op_cls_init(obj_req->osd_req, 0, CEPH_OSD_OP_CALL, "rbd", > + "copyup"); > + if (err) > + return err; > + > /* > * Only send non-zero copyup data to save some I/O and network > * bandwidth -- zero copyup data is equivalent to the object not > @@ -2372,8 +2378,6 @@ static int rbd_obj_issue_copyup(struct rbd_obj_request *obj_req, u32 bytes) > bytes = 0; > } > > - osd_req_op_cls_init(obj_req->osd_req, 0, CEPH_OSD_OP_CALL, "rbd", > - "copyup"); > osd_req_op_cls_request_data_bvecs(obj_req->osd_req, 0, > obj_req->copyup_bvecs, bytes); > > diff --git a/include/linux/ceph/osd_client.h b/include/linux/ceph/osd_client.h > index 528ccc9..ba3d8c2 100644 > --- a/include/linux/ceph/osd_client.h > +++ b/include/linux/ceph/osd_client.h > @@ -432,7 +432,7 @@ extern void osd_req_op_cls_response_data_pages(struct ceph_osd_request *, > struct page **pages, u64 length, > u32 alignment, bool pages_from_pool, > bool own_pages); > -extern void osd_req_op_cls_init(struct ceph_osd_request *osd_req, > +extern int osd_req_op_cls_init(struct ceph_osd_request *osd_req, > unsigned int which, u16 opcode, > const char *class, const char *method); > extern int osd_req_op_xattr_init(struct ceph_osd_request *osd_req, unsigned int which, > diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c > index ea2a6c9f..a2e2c36 100644 > --- a/net/ceph/osd_client.c > +++ b/net/ceph/osd_client.c > @@ -748,7 +748,7 @@ void osd_req_op_extent_dup_last(struct ceph_osd_request *osd_req, > } > EXPORT_SYMBOL(osd_req_op_extent_dup_last); > > -void osd_req_op_cls_init(struct ceph_osd_request *osd_req, unsigned int which, > +int osd_req_op_cls_init(struct ceph_osd_request *osd_req, unsigned int which, > u16 opcode, const char *class, const char *method) > { > struct ceph_osd_req_op *op = _osd_req_op_init(osd_req, which, > @@ -760,7 +760,9 @@ void osd_req_op_cls_init(struct ceph_osd_request *osd_req, unsigned int which, > BUG_ON(opcode != CEPH_OSD_OP_CALL); > > pagelist = kmalloc(sizeof (*pagelist), GFP_NOFS); > - BUG_ON(!pagelist); > + if (!pagelist) > + return -ENOMEM; > + > ceph_pagelist_init(pagelist); > > op->cls.class_name = class; > @@ -780,6 +782,7 @@ void osd_req_op_cls_init(struct ceph_osd_request *osd_req, unsigned int which, > osd_req_op_cls_request_info_pagelist(osd_req, which, pagelist); > > op->indata_len = payload_len; > + return 0; > } > EXPORT_SYMBOL(osd_req_op_cls_init); > > @@ -4909,7 +4912,10 @@ int ceph_osdc_call(struct ceph_osd_client *osdc, > if (ret) > goto out_put_req; > > - osd_req_op_cls_init(req, 0, CEPH_OSD_OP_CALL, class, method); > + ret = osd_req_op_cls_init(req, 0, CEPH_OSD_OP_CALL, class, method); > + if (ret) > + goto out_put_req; > + > if (req_page) > osd_req_op_cls_request_data_pages(req, 0, &req_page, req_len, > 0, false, false); Applied. Thanks, Ilya -- To unsubscribe from this list: send the line "unsubscribe ceph-devel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index 7320466..ebd1d79 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c @@ -2348,6 +2348,7 @@ static bool is_zero_bvecs(struct bio_vec *bvecs, u32 bytes) static int rbd_obj_issue_copyup(struct rbd_obj_request *obj_req, u32 bytes) { unsigned int num_osd_ops = obj_req->osd_req->r_num_ops; + int err; dout("%s obj_req %p bytes %u\n", __func__, obj_req, bytes); rbd_assert(obj_req->osd_req->r_ops[0].op == CEPH_OSD_OP_STAT); @@ -2362,6 +2363,11 @@ static int rbd_obj_issue_copyup(struct rbd_obj_request *obj_req, u32 bytes) if (!obj_req->osd_req) return -ENOMEM; + err = osd_req_op_cls_init(obj_req->osd_req, 0, CEPH_OSD_OP_CALL, "rbd", + "copyup"); + if (err) + return err; + /* * Only send non-zero copyup data to save some I/O and network * bandwidth -- zero copyup data is equivalent to the object not @@ -2372,8 +2378,6 @@ static int rbd_obj_issue_copyup(struct rbd_obj_request *obj_req, u32 bytes) bytes = 0; } - osd_req_op_cls_init(obj_req->osd_req, 0, CEPH_OSD_OP_CALL, "rbd", - "copyup"); osd_req_op_cls_request_data_bvecs(obj_req->osd_req, 0, obj_req->copyup_bvecs, bytes); diff --git a/include/linux/ceph/osd_client.h b/include/linux/ceph/osd_client.h index 528ccc9..ba3d8c2 100644 --- a/include/linux/ceph/osd_client.h +++ b/include/linux/ceph/osd_client.h @@ -432,7 +432,7 @@ extern void osd_req_op_cls_response_data_pages(struct ceph_osd_request *, struct page **pages, u64 length, u32 alignment, bool pages_from_pool, bool own_pages); -extern void osd_req_op_cls_init(struct ceph_osd_request *osd_req, +extern int osd_req_op_cls_init(struct ceph_osd_request *osd_req, unsigned int which, u16 opcode, const char *class, const char *method); extern int osd_req_op_xattr_init(struct ceph_osd_request *osd_req, unsigned int which, diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c index ea2a6c9f..a2e2c36 100644 --- a/net/ceph/osd_client.c +++ b/net/ceph/osd_client.c @@ -748,7 +748,7 @@ void osd_req_op_extent_dup_last(struct ceph_osd_request *osd_req, } EXPORT_SYMBOL(osd_req_op_extent_dup_last); -void osd_req_op_cls_init(struct ceph_osd_request *osd_req, unsigned int which, +int osd_req_op_cls_init(struct ceph_osd_request *osd_req, unsigned int which, u16 opcode, const char *class, const char *method) { struct ceph_osd_req_op *op = _osd_req_op_init(osd_req, which, @@ -760,7 +760,9 @@ void osd_req_op_cls_init(struct ceph_osd_request *osd_req, unsigned int which, BUG_ON(opcode != CEPH_OSD_OP_CALL); pagelist = kmalloc(sizeof (*pagelist), GFP_NOFS); - BUG_ON(!pagelist); + if (!pagelist) + return -ENOMEM; + ceph_pagelist_init(pagelist); op->cls.class_name = class; @@ -780,6 +782,7 @@ void osd_req_op_cls_init(struct ceph_osd_request *osd_req, unsigned int which, osd_req_op_cls_request_info_pagelist(osd_req, which, pagelist); op->indata_len = payload_len; + return 0; } EXPORT_SYMBOL(osd_req_op_cls_init); @@ -4909,7 +4912,10 @@ int ceph_osdc_call(struct ceph_osd_client *osdc, if (ret) goto out_put_req; - osd_req_op_cls_init(req, 0, CEPH_OSD_OP_CALL, class, method); + ret = osd_req_op_cls_init(req, 0, CEPH_OSD_OP_CALL, class, method); + if (ret) + goto out_put_req; + if (req_page) osd_req_op_cls_request_data_pages(req, 0, &req_page, req_len, 0, false, false);
Add proper error handling for osd_req_op_cls_init() to replace BUG_ON statement when failing from memory allocation. Signed-off-by: Chengguang Xu <cgxu519@gmx.com> --- drivers/block/rbd.c | 8 ++++++-- include/linux/ceph/osd_client.h | 2 +- net/ceph/osd_client.c | 12 +++++++++--- 3 files changed, 16 insertions(+), 6 deletions(-)