summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorPavel Emelyanov <xemul@openvz.org>2007-10-17 21:22:17 -0700
committerDavid S. Miller <davem@davemloft.net>2007-10-17 21:22:17 -0700
commitd3904b739928edd83d117f1eb5bfa69f18d6f046 (patch)
treee73ddcf5d45f11b3b37031b0fea67d17943ca46b /net
parent309dd5fc872448e35634d510049642312ebc170d (diff)
downloadtalos-obmc-linux-d3904b739928edd83d117f1eb5bfa69f18d6f046.tar.gz
talos-obmc-linux-d3904b739928edd83d117f1eb5bfa69f18d6f046.zip
[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')
-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)
*/
int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk)
{
- struct sk_filter *fp;
+ struct sk_filter *fp, *old_fp;
unsigned int fsize = sizeof(struct sock_filter) * fprog->len;
int err;
@@ -418,19 +418,18 @@ int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk)
fp->len = fprog->len;
err = sk_chk_filter(fp->insns, fp->len);
- if (!err) {
- struct sk_filter *old_fp;
-
- rcu_read_lock_bh();
- old_fp = rcu_dereference(sk->sk_filter);
- rcu_assign_pointer(sk->sk_filter, fp);
- rcu_read_unlock_bh();
- fp = old_fp;
+ if (err) {
+ sk_filter_uncharge(sk, fp);
+ return err;
}
- if (fp)
- sk_filter_uncharge(sk, fp);
- return err;
+ rcu_read_lock_bh();
+ old_fp = rcu_dereference(sk->sk_filter);
+ rcu_assign_pointer(sk->sk_filter, fp);
+ rcu_read_unlock_bh();
+
+ sk_filter_uncharge(sk, old_fp);
+ return 0;
}
int sk_detach_filter(struct sock *sk)
OpenPOWER on IntegriCloud