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 | |
| 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>
| -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 | ||
