diff options
author | Vasiliy Kulikov <segooon@gmail.com> | 2010-09-26 04:59:37 -0400 |
---|---|---|
committer | Sage Weil <sage@newdream.net> | 2010-10-20 18:38:19 -0400 |
commit | 28f259b7cd78eb29d38b7ae6b475d656e08fd348 (patch) | |
tree | 4cbefc4ad9562af2c221b6fec52bb560772f0a40 /drivers/block/rbd.c | |
parent | 496e59553c51ce18acc836de070106b583926b87 (diff) |
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>
Diffstat (limited to 'drivers/block/rbd.c')
-rw-r--r-- | drivers/block/rbd.c | 14 |
1 files changed, 8 insertions, 6 deletions
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index c42f3058abc7..83b15dd24853 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c | |||
@@ -241,6 +241,7 @@ static struct rbd_client *rbd_client_create(struct ceph_options *opt) | |||
241 | rbdc->client = ceph_create_client(opt, rbdc); | 241 | rbdc->client = ceph_create_client(opt, rbdc); |
242 | if (IS_ERR(rbdc->client)) | 242 | if (IS_ERR(rbdc->client)) |
243 | goto out_rbdc; | 243 | goto out_rbdc; |
244 | opt = NULL; /* Now rbdc->client is responsible for opt */ | ||
244 | 245 | ||
245 | ret = ceph_open_session(rbdc->client); | 246 | ret = ceph_open_session(rbdc->client); |
246 | if (ret < 0) | 247 | if (ret < 0) |
@@ -255,13 +256,12 @@ static struct rbd_client *rbd_client_create(struct ceph_options *opt) | |||
255 | 256 | ||
256 | out_err: | 257 | out_err: |
257 | ceph_destroy_client(rbdc->client); | 258 | ceph_destroy_client(rbdc->client); |
258 | return ERR_PTR(ret); | ||
259 | |||
260 | out_rbdc: | 259 | out_rbdc: |
261 | kfree(rbdc); | 260 | kfree(rbdc); |
262 | out_opt: | 261 | out_opt: |
263 | ceph_destroy_options(opt); | 262 | if (opt) |
264 | return ERR_PTR(-ENOMEM); | 263 | ceph_destroy_options(opt); |
264 | return ERR_PTR(ret); | ||
265 | } | 265 | } |
266 | 266 | ||
267 | /* | 267 | /* |
@@ -889,8 +889,10 @@ static int rbd_do_op(struct request *rq, | |||
889 | rbd_dev->header.block_name, | 889 | rbd_dev->header.block_name, |
890 | ofs, len, | 890 | ofs, len, |
891 | seg_name, &seg_ofs); | 891 | seg_name, &seg_ofs); |
892 | if (seg_len < 0) | 892 | if ((s64)seg_len < 0) { |
893 | return seg_len; | 893 | ret = seg_len; |
894 | goto done; | ||
895 | } | ||
894 | 896 | ||
895 | payload_len = (flags & CEPH_OSD_FLAG_WRITE ? seg_len : 0); | 897 | payload_len = (flags & CEPH_OSD_FLAG_WRITE ? seg_len : 0); |
896 | 898 | ||