aboutsummaryrefslogtreecommitdiffstats
path: root/net/can/af_can.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/can/af_can.c')
-rw-r--r--net/can/af_can.c67
1 files changed, 42 insertions, 25 deletions
diff --git a/net/can/af_can.c b/net/can/af_can.c
index 733d66f1b05a..094fc5332d42 100644
--- a/net/can/af_can.c
+++ b/net/can/af_can.c
@@ -84,8 +84,8 @@ static DEFINE_SPINLOCK(can_rcvlists_lock);
84static struct kmem_cache *rcv_cache __read_mostly; 84static struct kmem_cache *rcv_cache __read_mostly;
85 85
86/* table of registered CAN protocols */ 86/* table of registered CAN protocols */
87static struct can_proto *proto_tab[CAN_NPROTO] __read_mostly; 87static const struct can_proto *proto_tab[CAN_NPROTO] __read_mostly;
88static DEFINE_SPINLOCK(proto_tab_lock); 88static DEFINE_MUTEX(proto_tab_lock);
89 89
90struct timer_list can_stattimer; /* timer for statistics update */ 90struct timer_list can_stattimer; /* timer for statistics update */
91struct s_stats can_stats; /* packet statistics */ 91struct s_stats can_stats; /* packet statistics */
@@ -115,11 +115,29 @@ static void can_sock_destruct(struct sock *sk)
115 skb_queue_purge(&sk->sk_receive_queue); 115 skb_queue_purge(&sk->sk_receive_queue);
116} 116}
117 117
118static const struct can_proto *can_get_proto(int protocol)
119{
120 const struct can_proto *cp;
121
122 rcu_read_lock();
123 cp = rcu_dereference(proto_tab[protocol]);
124 if (cp && !try_module_get(cp->prot->owner))
125 cp = NULL;
126 rcu_read_unlock();
127
128 return cp;
129}
130
131static inline void can_put_proto(const struct can_proto *cp)
132{
133 module_put(cp->prot->owner);
134}
135
118static int can_create(struct net *net, struct socket *sock, int protocol, 136static int can_create(struct net *net, struct socket *sock, int protocol,
119 int kern) 137 int kern)
120{ 138{
121 struct sock *sk; 139 struct sock *sk;
122 struct can_proto *cp; 140 const struct can_proto *cp;
123 int err = 0; 141 int err = 0;
124 142
125 sock->state = SS_UNCONNECTED; 143 sock->state = SS_UNCONNECTED;
@@ -130,9 +148,12 @@ static int can_create(struct net *net, struct socket *sock, int protocol,
130 if (!net_eq(net, &init_net)) 148 if (!net_eq(net, &init_net))
131 return -EAFNOSUPPORT; 149 return -EAFNOSUPPORT;
132 150
151 cp = can_get_proto(protocol);
152
133#ifdef CONFIG_MODULES 153#ifdef CONFIG_MODULES
134 /* try to load protocol module kernel is modular */ 154 if (!cp) {
135 if (!proto_tab[protocol]) { 155 /* try to load protocol module if kernel is modular */
156
136 err = request_module("can-proto-%d", protocol); 157 err = request_module("can-proto-%d", protocol);
137 158
138 /* 159 /*
@@ -143,22 +164,18 @@ static int can_create(struct net *net, struct socket *sock, int protocol,
143 if (err && printk_ratelimit()) 164 if (err && printk_ratelimit())
144 printk(KERN_ERR "can: request_module " 165 printk(KERN_ERR "can: request_module "
145 "(can-proto-%d) failed.\n", protocol); 166 "(can-proto-%d) failed.\n", protocol);
167
168 cp = can_get_proto(protocol);
146 } 169 }
147#endif 170#endif
148 171
149 spin_lock(&proto_tab_lock);
150 cp = proto_tab[protocol];
151 if (cp && !try_module_get(cp->prot->owner))
152 cp = NULL;
153 spin_unlock(&proto_tab_lock);
154
155 /* check for available protocol and correct usage */ 172 /* check for available protocol and correct usage */
156 173
157 if (!cp) 174 if (!cp)
158 return -EPROTONOSUPPORT; 175 return -EPROTONOSUPPORT;
159 176
160 if (cp->type != sock->type) { 177 if (cp->type != sock->type) {
161 err = -EPROTONOSUPPORT; 178 err = -EPROTOTYPE;
162 goto errout; 179 goto errout;
163 } 180 }
164 181
@@ -183,7 +200,7 @@ static int can_create(struct net *net, struct socket *sock, int protocol,
183 } 200 }
184 201
185 errout: 202 errout:
186 module_put(cp->prot->owner); 203 can_put_proto(cp);
187 return err; 204 return err;
188} 205}
189 206
@@ -679,7 +696,7 @@ drop:
679 * -EBUSY protocol already in use 696 * -EBUSY protocol already in use
680 * -ENOBUF if proto_register() fails 697 * -ENOBUF if proto_register() fails
681 */ 698 */
682int can_proto_register(struct can_proto *cp) 699int can_proto_register(const struct can_proto *cp)
683{ 700{
684 int proto = cp->protocol; 701 int proto = cp->protocol;
685 int err = 0; 702 int err = 0;
@@ -694,15 +711,16 @@ int can_proto_register(struct can_proto *cp)
694 if (err < 0) 711 if (err < 0)
695 return err; 712 return err;
696 713
697 spin_lock(&proto_tab_lock); 714 mutex_lock(&proto_tab_lock);
715
698 if (proto_tab[proto]) { 716 if (proto_tab[proto]) {
699 printk(KERN_ERR "can: protocol %d already registered\n", 717 printk(KERN_ERR "can: protocol %d already registered\n",
700 proto); 718 proto);
701 err = -EBUSY; 719 err = -EBUSY;
702 } else 720 } else
703 proto_tab[proto] = cp; 721 rcu_assign_pointer(proto_tab[proto], cp);
704 722
705 spin_unlock(&proto_tab_lock); 723 mutex_unlock(&proto_tab_lock);
706 724
707 if (err < 0) 725 if (err < 0)
708 proto_unregister(cp->prot); 726 proto_unregister(cp->prot);
@@ -715,17 +733,16 @@ EXPORT_SYMBOL(can_proto_register);
715 * can_proto_unregister - unregister CAN transport protocol 733 * can_proto_unregister - unregister CAN transport protocol
716 * @cp: pointer to CAN protocol structure 734 * @cp: pointer to CAN protocol structure
717 */ 735 */
718void can_proto_unregister(struct can_proto *cp) 736void can_proto_unregister(const struct can_proto *cp)
719{ 737{
720 int proto = cp->protocol; 738 int proto = cp->protocol;
721 739
722 spin_lock(&proto_tab_lock); 740 mutex_lock(&proto_tab_lock);
723 if (!proto_tab[proto]) { 741 BUG_ON(proto_tab[proto] != cp);
724 printk(KERN_ERR "BUG: can: protocol %d is not registered\n", 742 rcu_assign_pointer(proto_tab[proto], NULL);
725 proto); 743 mutex_unlock(&proto_tab_lock);
726 } 744
727 proto_tab[proto] = NULL; 745 synchronize_rcu();
728 spin_unlock(&proto_tab_lock);
729 746
730 proto_unregister(cp->prot); 747 proto_unregister(cp->prot);
731} 748}