Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6e2144b7 authored by Arnaldo Carvalho de Melo's avatar Arnaldo Carvalho de Melo
Browse files

[LLC]: Use refcounting with struct llc_sap

parent 04e4223f
Loading
Loading
Loading
Loading
+15 −1
Original line number Diff line number Diff line
@@ -17,6 +17,8 @@
#include <linux/list.h>
#include <linux/spinlock.h>

#include <asm/atomic.h>

struct net_device;
struct packet_type;
struct sk_buff;
@@ -44,6 +46,7 @@ struct llc_sap {
	unsigned char	 state;
	unsigned char	 p_bit;
	unsigned char	 f_bit;
	atomic_t         refcnt;
	int		 (*rcv_func)(struct sk_buff *skb,
				     struct net_device *dev,
				     struct packet_type *pt,
@@ -81,8 +84,19 @@ extern struct llc_sap *llc_sap_open(unsigned char lsap,
					       struct net_device *dev,
					       struct packet_type *pt,
					       struct net_device *orig_dev));
static inline void llc_sap_hold(struct llc_sap *sap)
{
	atomic_inc(&sap->refcnt);
}

static inline void llc_sap_put(struct llc_sap *sap)
{
	extern void llc_sap_close(struct llc_sap *sap);

	if (atomic_dec_and_test(&sap->refcnt))
		llc_sap_close(sap);
}

extern struct llc_sap *llc_sap_find(unsigned char sap_value);

extern int llc_build_and_send_ui_pkt(struct llc_sap *sap, struct sk_buff *skb,
+0 −1
Original line number Diff line number Diff line
@@ -115,5 +115,4 @@ extern void llc_sap_remove_socket(struct llc_sap *sap, struct sock *sk);

extern u8 llc_data_accept_state(u8 state);
extern void llc_build_offset_table(void);
extern int llc_release_sockets(struct llc_sap *sap);
#endif /* LLC_CONN_H */
+1 −1
Original line number Diff line number Diff line
@@ -56,7 +56,7 @@ struct datalink_proto *register_8022_client(unsigned char type,

void unregister_8022_client(struct datalink_proto *proto)
{
	llc_sap_close(proto->sap);
	llc_sap_put(proto->sap);
	kfree(proto);
}

+1 −1
Original line number Diff line number Diff line
@@ -106,7 +106,7 @@ module_init(snap_init);

static void __exit snap_exit(void)
{
	llc_sap_close(snap_sap);
	llc_sap_put(snap_sap);
}

module_exit(snap_exit);
+6 −5
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@
 * See the GNU General Public License for more details.
 */
#include <linux/config.h>
#include <linux/compiler.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/rtnetlink.h>
@@ -188,10 +189,6 @@ static int llc_ui_release(struct socket *sock)
	if (!sock_flag(sk, SOCK_ZAPPED))
		llc_sap_remove_socket(llc->sap, sk);
	release_sock(sk);
	if (llc->sap && hlist_empty(&llc->sap->sk_list.list)) {
		llc_release_sockets(llc->sap);
		llc_sap_close(llc->sap);
	}
	if (llc->dev)
		dev_put(llc->dev);
	sock_put(sk);
@@ -220,6 +217,7 @@ static int llc_ui_autoport(void)
				llc_ui_sap_last_autoport = i + 2;
				goto out;
			}
			llc_sap_put(sap);
		}
		llc_ui_sap_last_autoport = LLC_SAP_DYN_START;
		tries++;
@@ -310,6 +308,7 @@ static int llc_ui_bind(struct socket *sock, struct sockaddr *uaddr, int addrlen)
		rc = -EBUSY; /* some other network layer is using the sap */
		if (!sap)
			goto out;
		llc_sap_hold(sap);
	} else {
		struct llc_addr laddr, daddr;
		struct sock *ask;
@@ -326,7 +325,7 @@ static int llc_ui_bind(struct socket *sock, struct sockaddr *uaddr, int addrlen)
		ask = llc_lookup_established(sap, &daddr, &laddr);
		if (ask) {
			sock_put(ask);
			goto out;
			goto out_put;
		}
	}
	llc->laddr.lsap = addr->sllc_sap;
@@ -336,6 +335,8 @@ static int llc_ui_bind(struct socket *sock, struct sockaddr *uaddr, int addrlen)
	llc_sap_add_socket(sap, sk);
	sock_reset_flag(sk, SOCK_ZAPPED);
	rc = 0;
out_put:
	llc_sap_put(sap);
out:
	return rc;
}
Loading