block: rbd: fixed may leaks

rbd_client_create() doesn't free rbdc, this leads to many leaks.

seg_len in rbd_do_op() is unsigned, so (seg_len < 0) makes no sense.
Also if fixed check fails then seg_name is leaked.

Signed-off-by: Vasiliy Kulikov <segooon@gmail.com>
Signed-off-by: Yehuda Sadeh <yehuda@hq.newdream.net>

authored by

Vasiliy Kulikov and committed by
Sage Weil
28f259b7 496e5955

+8 -6
+8 -6
drivers/block/rbd.c
··· 241 rbdc->client = ceph_create_client(opt, rbdc); 242 if (IS_ERR(rbdc->client)) 243 goto out_rbdc; 244 245 ret = ceph_open_session(rbdc->client); 246 if (ret < 0) ··· 256 257 out_err: 258 ceph_destroy_client(rbdc->client); 259 - return ERR_PTR(ret); 260 - 261 out_rbdc: 262 kfree(rbdc); 263 out_opt: 264 - ceph_destroy_options(opt); 265 - return ERR_PTR(-ENOMEM); 266 } 267 268 /* ··· 889 rbd_dev->header.block_name, 890 ofs, len, 891 seg_name, &seg_ofs); 892 - if (seg_len < 0) 893 - return seg_len; 894 895 payload_len = (flags & CEPH_OSD_FLAG_WRITE ? seg_len : 0); 896
··· 241 rbdc->client = ceph_create_client(opt, rbdc); 242 if (IS_ERR(rbdc->client)) 243 goto out_rbdc; 244 + opt = NULL; /* Now rbdc->client is responsible for opt */ 245 246 ret = ceph_open_session(rbdc->client); 247 if (ret < 0) ··· 255 256 out_err: 257 ceph_destroy_client(rbdc->client); 258 out_rbdc: 259 kfree(rbdc); 260 out_opt: 261 + if (opt) 262 + ceph_destroy_options(opt); 263 + return ERR_PTR(ret); 264 } 265 266 /* ··· 889 rbd_dev->header.block_name, 890 ofs, len, 891 seg_name, &seg_ofs); 892 + if ((s64)seg_len < 0) { 893 + ret = seg_len; 894 + goto done; 895 + } 896 897 payload_len = (flags & CEPH_OSD_FLAG_WRITE ? seg_len : 0); 898