/* Initialise core socket variables */
extern void sock_init_data(struct socket *sock, struct sock *sk);
-extern void sklist_remove_socket(struct sock **list, struct sock *sk);
-extern void sklist_insert_socket(struct sock **list, struct sock *sk);
-extern void sklist_destroy_socket(struct sock **list, struct sock *sk);
-
#ifdef CONFIG_FILTER
/**
} while((skb = sk->backlog.head) != NULL);
}
-/*
- * Generic socket manager library. Most simpler socket families
- * use this to manage their socket lists. At some point we should
- * hash these. By making this generic we get the lot hashed for free.
- *
- * It is broken by design. All the protocols using it must be fixed. --ANK
- */
-
-rwlock_t net_big_sklist_lock = RW_LOCK_UNLOCKED;
-
-void sklist_remove_socket(struct sock **list, struct sock *sk)
-{
- struct sock *s;
-
- write_lock_bh(&net_big_sklist_lock);
-
- while ((s = *list) != NULL) {
- if (s == sk) {
- *list = s->next;
- break;
- }
- list = &s->next;
- }
-
- write_unlock_bh(&net_big_sklist_lock);
- if (s)
- sock_put(s);
-}
-
-void sklist_insert_socket(struct sock **list, struct sock *sk)
-{
- write_lock_bh(&net_big_sklist_lock);
- sk->next= *list;
- *list=sk;
- sock_hold(sk);
- write_unlock_bh(&net_big_sklist_lock);
-}
-
-/*
- * This is only called from user mode. Thus it protects itself against
- * interrupt users but doesn't worry about being called during work.
- * Once it is removed from the queue no interrupt or bottom half will
- * touch it and we are (fairly 8-) ) safe.
- */
-
-void sklist_destroy_socket(struct sock **list, struct sock *sk);
-
-/*
- * Handler for deferred kills.
- */
-
-static void sklist_destroy_timer(unsigned long data)
-{
- struct sock *sk=(struct sock *)data;
- sklist_destroy_socket(NULL,sk);
-}
-
-/*
- * Destroy a socket. We pass NULL for a list if we know the
- * socket is not on a list.
- */
-
-void sklist_destroy_socket(struct sock **list,struct sock *sk)
-{
- if(list)
- sklist_remove_socket(list, sk);
-
- skb_queue_purge(&sk->receive_queue);
-
- if(atomic_read(&sk->wmem_alloc) == 0 &&
- atomic_read(&sk->rmem_alloc) == 0 &&
- sk->dead)
- {
- sock_put(sk);
- }
- else
- {
- /*
- * Someone is using our buffers still.. defer
- */
- init_timer(&sk->timer);
- sk->timer.expires=jiffies+SOCK_DESTROY_TIME;
- sk->timer.function=sklist_destroy_timer;
- sk->timer.data = (unsigned long)sk;
- add_timer(&sk->timer);
- }
-}
-
/*
* Set of default routines for initialising struct proto_ops when
* the protocol does not support a particular function. In certain
static struct proto_ops econet_ops;
static struct sock *econet_sklist;
+static rwlock_t econet_lock = RW_LOCK_UNLOCKED;
/* Since there are only 256 possible network numbers (or fewer, depends
how you count) it makes sense to use a simple lookup table. */
#endif
};
+static void econet_remove_socket(struct sock **list, struct sock *sk)
+{
+ struct sock *s;
+
+ write_lock_bh(&econet_lock);
+
+ while ((s = *list) != NULL) {
+ if (s == sk) {
+ *list = s->next;
+ break;
+ }
+ list = &s->next;
+ }
+
+ write_unlock_bh(&econet_lock);
+ if (s)
+ sock_put(s);
+}
+
+static void econet_insert_socket(struct sock **list, struct sock *sk)
+{
+ write_lock_bh(&econet_lock);
+ sk->next = *list;
+ sock_hold(sk);
+ write_unlock_bh(&econet_lock);
+}
+
/*
* Pull a packet from our receive queue and hand it to the user.
* If necessary we block.
if (!sk)
return 0;
- sklist_remove_socket(&econet_sklist, sk);
+ econet_remove_socket(&econet_sklist, sk);
/*
* Now the socket is dead. No more input will appear.
sk->family = PF_ECONET;
eo->num = protocol;
- sklist_insert_socket(&econet_sklist, sk);
+ econet_insert_socket(&econet_sklist, sk);
return(0);
out_free:
EXPORT_SYMBOL(vlan_ioctl_hook);
#endif
-EXPORT_SYMBOL(sklist_destroy_socket);
-EXPORT_SYMBOL(sklist_insert_socket);
-
EXPORT_SYMBOL(scm_detach_fds);
#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
EXPORT_SYMBOL(dev_set_allmulti);
EXPORT_SYMBOL(dev_set_promiscuity);
-EXPORT_SYMBOL(sklist_remove_socket);
EXPORT_SYMBOL(rtnl_sem);
EXPORT_SYMBOL(rtnl_lock);
EXPORT_SYMBOL(rtnl_unlock);