aboutsummaryrefslogtreecommitdiffstats
path: root/net/core
diff options
context:
space:
mode:
authorPavel Emelyanov <xemul@openvz.org>2007-10-18 00:22:17 -0400
committerDavid S. Miller <davem@davemloft.net>2007-10-18 00:22:17 -0400
commitd3904b739928edd83d117f1eb5bfa69f18d6f046 (patch)
treee73ddcf5d45f11b3b37031b0fea67d17943ca46b /net/core
parent309dd5fc872448e35634d510049642312ebc170d (diff)
[NET]: Cleanup the error path in sk_attach_filter
The sk_filter_uncharge is called for error handling and for releasing the former filter, but this will have to be done in a bit different manner, so cleanup the error path a bit. Signed-off-by: Pavel Emelyanov <xemul@openvz.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core')
-rw-r--r--net/core/filter.c23
1 files changed, 11 insertions, 12 deletions
diff --git a/net/core/filter.c b/net/core/filter.c
index 2be1830d3c35..54dddc92452d 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -398,7 +398,7 @@ int sk_chk_filter(struct sock_filter *filter, int flen)
398 */ 398 */
399int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk) 399int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk)
400{ 400{
401 struct sk_filter *fp; 401 struct sk_filter *fp, *old_fp;
402 unsigned int fsize = sizeof(struct sock_filter) * fprog->len; 402 unsigned int fsize = sizeof(struct sock_filter) * fprog->len;
403 int err; 403 int err;
404 404
@@ -418,19 +418,18 @@ int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk)
418 fp->len = fprog->len; 418 fp->len = fprog->len;
419 419
420 err = sk_chk_filter(fp->insns, fp->len); 420 err = sk_chk_filter(fp->insns, fp->len);
421 if (!err) { 421 if (err) {
422 struct sk_filter *old_fp; 422 sk_filter_uncharge(sk, fp);
423 423 return err;
424 rcu_read_lock_bh();
425 old_fp = rcu_dereference(sk->sk_filter);
426 rcu_assign_pointer(sk->sk_filter, fp);
427 rcu_read_unlock_bh();
428 fp = old_fp;
429 } 424 }
430 425
431 if (fp) 426 rcu_read_lock_bh();
432 sk_filter_uncharge(sk, fp); 427 old_fp = rcu_dereference(sk->sk_filter);
433 return err; 428 rcu_assign_pointer(sk->sk_filter, fp);
429 rcu_read_unlock_bh();
430
431 sk_filter_uncharge(sk, old_fp);
432 return 0;
434} 433}
435 434
436int sk_detach_filter(struct sock *sk) 435int sk_detach_filter(struct sock *sk)