diff options
author | Vasily Averin <vvs@sw.ru> | 2006-03-05 17:18:14 -0500 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.il.steeleye.com> | 2006-03-12 09:53:16 -0500 |
commit | 071a651e28bfc1a66a885dc285792e335427a097 (patch) | |
tree | b0329efb4c0e2643e19058157b34648c820e61d9 | |
parent | cf7f5b45fe0180a0f0e3491183c0ec95e4b96d44 (diff) |
[SCSI] i2o: fix memory leak in i2o_exec_lct_modified
i2o_exec_lct_modified() does not release memory allocated for work_struct.
Signed-off-by: Vasily Averin <vvs@sw.ru>
Although your patch is the same, i've rewritten it a little bit for
naming consistency in the I2O driver.
Acked-by: Markus Lidel <Markus.Lidel@shadowconnect.com>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
-rw-r--r-- | drivers/message/i2o/exec-osm.c | 21 |
1 files changed, 17 insertions, 4 deletions
diff --git a/drivers/message/i2o/exec-osm.c b/drivers/message/i2o/exec-osm.c index 9bb9859f6dfe..5ea133c59afb 100644 --- a/drivers/message/i2o/exec-osm.c +++ b/drivers/message/i2o/exec-osm.c | |||
@@ -57,6 +57,13 @@ struct i2o_exec_wait { | |||
57 | struct list_head list; /* node in global wait list */ | 57 | struct list_head list; /* node in global wait list */ |
58 | }; | 58 | }; |
59 | 59 | ||
60 | /* Work struct needed to handle LCT NOTIFY replies */ | ||
61 | struct i2o_exec_lct_notify_work { | ||
62 | struct work_struct work; /* work struct */ | ||
63 | struct i2o_controller *c; /* controller on which the LCT NOTIFY | ||
64 | was received */ | ||
65 | }; | ||
66 | |||
60 | /* Exec OSM class handling definition */ | 67 | /* Exec OSM class handling definition */ |
61 | static struct i2o_class_id i2o_exec_class_id[] = { | 68 | static struct i2o_class_id i2o_exec_class_id[] = { |
62 | {I2O_CLASS_EXECUTIVE}, | 69 | {I2O_CLASS_EXECUTIVE}, |
@@ -355,9 +362,12 @@ static int i2o_exec_remove(struct device *dev) | |||
355 | * new LCT and if the buffer for the LCT was to small sends a LCT NOTIFY | 362 | * new LCT and if the buffer for the LCT was to small sends a LCT NOTIFY |
356 | * again, otherwise send LCT NOTIFY to get informed on next LCT change. | 363 | * again, otherwise send LCT NOTIFY to get informed on next LCT change. |
357 | */ | 364 | */ |
358 | static void i2o_exec_lct_modified(struct i2o_controller *c) | 365 | static void i2o_exec_lct_modified(struct i2o_exec_lct_notify_work *work) |
359 | { | 366 | { |
360 | u32 change_ind = 0; | 367 | u32 change_ind = 0; |
368 | struct i2o_controller *c = work->c; | ||
369 | |||
370 | kfree(work); | ||
361 | 371 | ||
362 | if (i2o_device_parse_lct(c) != -EAGAIN) | 372 | if (i2o_device_parse_lct(c) != -EAGAIN) |
363 | change_ind = c->lct->change_ind + 1; | 373 | change_ind = c->lct->change_ind + 1; |
@@ -410,7 +420,7 @@ static int i2o_exec_reply(struct i2o_controller *c, u32 m, | |||
410 | return i2o_msg_post_wait_complete(c, m, msg, context); | 420 | return i2o_msg_post_wait_complete(c, m, msg, context); |
411 | 421 | ||
412 | if ((le32_to_cpu(msg->u.head[1]) >> 24) == I2O_CMD_LCT_NOTIFY) { | 422 | if ((le32_to_cpu(msg->u.head[1]) >> 24) == I2O_CMD_LCT_NOTIFY) { |
413 | struct work_struct *work; | 423 | struct i2o_exec_lct_notify_work *work; |
414 | 424 | ||
415 | pr_debug("%s: LCT notify received\n", c->name); | 425 | pr_debug("%s: LCT notify received\n", c->name); |
416 | 426 | ||
@@ -418,8 +428,11 @@ static int i2o_exec_reply(struct i2o_controller *c, u32 m, | |||
418 | if (!work) | 428 | if (!work) |
419 | return -ENOMEM; | 429 | return -ENOMEM; |
420 | 430 | ||
421 | INIT_WORK(work, (void (*)(void *))i2o_exec_lct_modified, c); | 431 | work->c = c; |
422 | queue_work(i2o_exec_driver.event_queue, work); | 432 | |
433 | INIT_WORK(&work->work, (void (*)(void *))i2o_exec_lct_modified, | ||
434 | work); | ||
435 | queue_work(i2o_exec_driver.event_queue, &work->work); | ||
423 | return 1; | 436 | return 1; |
424 | } | 437 | } |
425 | 438 | ||