.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
---|
1 | 2 | /* |
---|
2 | | - * This program is free software; you can redistribute it and/or modify |
---|
3 | | - * it under the terms of the GNU General Public License as published by |
---|
4 | | - * the Free Software Foundation; either version 2 of the License, or |
---|
5 | | - * (at your option) any later version. |
---|
6 | 3 | * |
---|
7 | 4 | * Copyright (C) Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk) |
---|
8 | 5 | */ |
---|
.. | .. |
---|
40 | 37 | for (ax25_dev = ax25_dev_list; ax25_dev != NULL; ax25_dev = ax25_dev->next) |
---|
41 | 38 | if (ax25cmp(addr, (ax25_address *)ax25_dev->dev->dev_addr) == 0) { |
---|
42 | 39 | res = ax25_dev; |
---|
| 40 | + ax25_dev_hold(ax25_dev); |
---|
43 | 41 | } |
---|
44 | 42 | spin_unlock_bh(&ax25_dev_lock); |
---|
45 | 43 | |
---|
.. | .. |
---|
59 | 57 | return; |
---|
60 | 58 | } |
---|
61 | 59 | |
---|
| 60 | + refcount_set(&ax25_dev->refcount, 1); |
---|
62 | 61 | dev->ax25_ptr = ax25_dev; |
---|
63 | 62 | ax25_dev->dev = dev; |
---|
64 | 63 | dev_hold(dev); |
---|
.. | .. |
---|
87 | 86 | ax25_dev->next = ax25_dev_list; |
---|
88 | 87 | ax25_dev_list = ax25_dev; |
---|
89 | 88 | spin_unlock_bh(&ax25_dev_lock); |
---|
| 89 | + ax25_dev_hold(ax25_dev); |
---|
90 | 90 | |
---|
91 | 91 | ax25_register_dev_sysctl(ax25_dev); |
---|
92 | 92 | } |
---|
.. | .. |
---|
116 | 116 | if ((s = ax25_dev_list) == ax25_dev) { |
---|
117 | 117 | ax25_dev_list = s->next; |
---|
118 | 118 | spin_unlock_bh(&ax25_dev_lock); |
---|
| 119 | + ax25_dev_put(ax25_dev); |
---|
119 | 120 | dev->ax25_ptr = NULL; |
---|
120 | 121 | dev_put(dev); |
---|
121 | | - kfree(ax25_dev); |
---|
| 122 | + ax25_dev_put(ax25_dev); |
---|
122 | 123 | return; |
---|
123 | 124 | } |
---|
124 | 125 | |
---|
.. | .. |
---|
126 | 127 | if (s->next == ax25_dev) { |
---|
127 | 128 | s->next = ax25_dev->next; |
---|
128 | 129 | spin_unlock_bh(&ax25_dev_lock); |
---|
| 130 | + ax25_dev_put(ax25_dev); |
---|
129 | 131 | dev->ax25_ptr = NULL; |
---|
130 | 132 | dev_put(dev); |
---|
131 | | - kfree(ax25_dev); |
---|
| 133 | + ax25_dev_put(ax25_dev); |
---|
132 | 134 | return; |
---|
133 | 135 | } |
---|
134 | 136 | |
---|
.. | .. |
---|
136 | 138 | } |
---|
137 | 139 | spin_unlock_bh(&ax25_dev_lock); |
---|
138 | 140 | dev->ax25_ptr = NULL; |
---|
| 141 | + ax25_dev_put(ax25_dev); |
---|
139 | 142 | } |
---|
140 | 143 | |
---|
141 | 144 | int ax25_fwd_ioctl(unsigned int cmd, struct ax25_fwd_struct *fwd) |
---|
.. | .. |
---|
147 | 150 | |
---|
148 | 151 | switch (cmd) { |
---|
149 | 152 | case SIOCAX25ADDFWD: |
---|
150 | | - if ((fwd_dev = ax25_addr_ax25dev(&fwd->port_to)) == NULL) |
---|
| 153 | + fwd_dev = ax25_addr_ax25dev(&fwd->port_to); |
---|
| 154 | + if (!fwd_dev) { |
---|
| 155 | + ax25_dev_put(ax25_dev); |
---|
151 | 156 | return -EINVAL; |
---|
152 | | - if (ax25_dev->forward != NULL) |
---|
| 157 | + } |
---|
| 158 | + if (ax25_dev->forward) { |
---|
| 159 | + ax25_dev_put(fwd_dev); |
---|
| 160 | + ax25_dev_put(ax25_dev); |
---|
153 | 161 | return -EINVAL; |
---|
| 162 | + } |
---|
154 | 163 | ax25_dev->forward = fwd_dev->dev; |
---|
| 164 | + ax25_dev_put(fwd_dev); |
---|
| 165 | + ax25_dev_put(ax25_dev); |
---|
155 | 166 | break; |
---|
156 | 167 | |
---|
157 | 168 | case SIOCAX25DELFWD: |
---|
158 | | - if (ax25_dev->forward == NULL) |
---|
| 169 | + if (!ax25_dev->forward) { |
---|
| 170 | + ax25_dev_put(ax25_dev); |
---|
159 | 171 | return -EINVAL; |
---|
| 172 | + } |
---|
160 | 173 | ax25_dev->forward = NULL; |
---|
| 174 | + ax25_dev_put(ax25_dev); |
---|
161 | 175 | break; |
---|
162 | 176 | |
---|
163 | 177 | default: |
---|
| 178 | + ax25_dev_put(ax25_dev); |
---|
164 | 179 | return -EINVAL; |
---|
165 | 180 | } |
---|
166 | 181 | |
---|