diff options
Diffstat (limited to 'net/sched/act_ife.c')
| -rw-r--r-- | net/sched/act_ife.c | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/net/sched/act_ife.c b/net/sched/act_ife.c index 196430aefe87..06a3d4801878 100644 --- a/net/sched/act_ife.c +++ b/net/sched/act_ife.c | |||
| @@ -326,6 +326,20 @@ static int __add_metainfo(const struct tcf_meta_ops *ops, | |||
| 326 | return ret; | 326 | return ret; |
| 327 | } | 327 | } |
| 328 | 328 | ||
| 329 | static int add_metainfo_and_get_ops(const struct tcf_meta_ops *ops, | ||
| 330 | struct tcf_ife_info *ife, u32 metaid, | ||
| 331 | bool exists) | ||
| 332 | { | ||
| 333 | int ret; | ||
| 334 | |||
| 335 | if (!try_module_get(ops->owner)) | ||
| 336 | return -ENOENT; | ||
| 337 | ret = __add_metainfo(ops, ife, metaid, NULL, 0, true, exists); | ||
| 338 | if (ret) | ||
| 339 | module_put(ops->owner); | ||
| 340 | return ret; | ||
| 341 | } | ||
| 342 | |||
| 329 | static int add_metainfo(struct tcf_ife_info *ife, u32 metaid, void *metaval, | 343 | static int add_metainfo(struct tcf_ife_info *ife, u32 metaid, void *metaval, |
| 330 | int len, bool exists) | 344 | int len, bool exists) |
| 331 | { | 345 | { |
| @@ -349,7 +363,7 @@ static int use_all_metadata(struct tcf_ife_info *ife, bool exists) | |||
| 349 | 363 | ||
| 350 | read_lock(&ife_mod_lock); | 364 | read_lock(&ife_mod_lock); |
| 351 | list_for_each_entry(o, &ifeoplist, list) { | 365 | list_for_each_entry(o, &ifeoplist, list) { |
| 352 | rc = __add_metainfo(o, ife, o->metaid, NULL, 0, true, exists); | 366 | rc = add_metainfo_and_get_ops(o, ife, o->metaid, exists); |
| 353 | if (rc == 0) | 367 | if (rc == 0) |
| 354 | installed += 1; | 368 | installed += 1; |
| 355 | } | 369 | } |
| @@ -400,7 +414,6 @@ static void _tcf_ife_cleanup(struct tc_action *a) | |||
| 400 | struct tcf_meta_info *e, *n; | 414 | struct tcf_meta_info *e, *n; |
| 401 | 415 | ||
| 402 | list_for_each_entry_safe(e, n, &ife->metalist, metalist) { | 416 | list_for_each_entry_safe(e, n, &ife->metalist, metalist) { |
| 403 | module_put(e->ops->owner); | ||
| 404 | list_del(&e->metalist); | 417 | list_del(&e->metalist); |
| 405 | if (e->metaval) { | 418 | if (e->metaval) { |
| 406 | if (e->ops->release) | 419 | if (e->ops->release) |
| @@ -408,6 +421,7 @@ static void _tcf_ife_cleanup(struct tc_action *a) | |||
| 408 | else | 421 | else |
| 409 | kfree(e->metaval); | 422 | kfree(e->metaval); |
| 410 | } | 423 | } |
| 424 | module_put(e->ops->owner); | ||
| 411 | kfree(e); | 425 | kfree(e); |
| 412 | } | 426 | } |
| 413 | } | 427 | } |
