diff options
Diffstat (limited to 'net/atm/common.c')
-rw-r--r-- | net/atm/common.c | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/net/atm/common.c b/net/atm/common.c index 0c0ad930a632..806fc0a40051 100644 --- a/net/atm/common.c +++ b/net/atm/common.c | |||
@@ -126,10 +126,19 @@ static void vcc_write_space(struct sock *sk) | |||
126 | rcu_read_unlock(); | 126 | rcu_read_unlock(); |
127 | } | 127 | } |
128 | 128 | ||
129 | static void vcc_release_cb(struct sock *sk) | ||
130 | { | ||
131 | struct atm_vcc *vcc = atm_sk(sk); | ||
132 | |||
133 | if (vcc->release_cb) | ||
134 | vcc->release_cb(vcc); | ||
135 | } | ||
136 | |||
129 | static struct proto vcc_proto = { | 137 | static struct proto vcc_proto = { |
130 | .name = "VCC", | 138 | .name = "VCC", |
131 | .owner = THIS_MODULE, | 139 | .owner = THIS_MODULE, |
132 | .obj_size = sizeof(struct atm_vcc), | 140 | .obj_size = sizeof(struct atm_vcc), |
141 | .release_cb = vcc_release_cb, | ||
133 | }; | 142 | }; |
134 | 143 | ||
135 | int vcc_create(struct net *net, struct socket *sock, int protocol, int family) | 144 | int vcc_create(struct net *net, struct socket *sock, int protocol, int family) |
@@ -156,7 +165,9 @@ int vcc_create(struct net *net, struct socket *sock, int protocol, int family) | |||
156 | atomic_set(&sk->sk_rmem_alloc, 0); | 165 | atomic_set(&sk->sk_rmem_alloc, 0); |
157 | vcc->push = NULL; | 166 | vcc->push = NULL; |
158 | vcc->pop = NULL; | 167 | vcc->pop = NULL; |
168 | vcc->owner = NULL; | ||
159 | vcc->push_oam = NULL; | 169 | vcc->push_oam = NULL; |
170 | vcc->release_cb = NULL; | ||
160 | vcc->vpi = vcc->vci = 0; /* no VCI/VPI yet */ | 171 | vcc->vpi = vcc->vci = 0; /* no VCI/VPI yet */ |
161 | vcc->atm_options = vcc->aal_options = 0; | 172 | vcc->atm_options = vcc->aal_options = 0; |
162 | sk->sk_destruct = vcc_sock_destruct; | 173 | sk->sk_destruct = vcc_sock_destruct; |
@@ -175,6 +186,7 @@ static void vcc_destroy_socket(struct sock *sk) | |||
175 | vcc->dev->ops->close(vcc); | 186 | vcc->dev->ops->close(vcc); |
176 | if (vcc->push) | 187 | if (vcc->push) |
177 | vcc->push(vcc, NULL); /* atmarpd has no push */ | 188 | vcc->push(vcc, NULL); /* atmarpd has no push */ |
189 | module_put(vcc->owner); | ||
178 | 190 | ||
179 | while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) { | 191 | while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) { |
180 | atm_return(vcc, skb->truesize); | 192 | atm_return(vcc, skb->truesize); |