diff options
author | Ying Xue <ying.xue@windriver.com> | 2014-11-25 22:41:55 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-11-26 12:30:17 -0500 |
commit | a6ca109443842e7251c68451f8137ae68ae6d8a6 (patch) | |
tree | 82658ff3ecd103abdad794b9b0833e45160b235e /net/tipc/msg.c | |
parent | f03273f1e2fc8a59c3831200dd1532cf29e37e35 (diff) |
tipc: use generic SKB list APIs to manage TIPC outgoing packet chains
Use standard SKB list APIs associated with struct sk_buff_head to
manage socket outgoing packet chain and name table outgoing packet
chain, having relevant code simpler and more readable.
Signed-off-by: Ying Xue <ying.xue@windriver.com>
Reviewed-by: Jon Maloy <jon.maloy@ericsson.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/tipc/msg.c')
-rw-r--r-- | net/tipc/msg.c | 74 |
1 files changed, 36 insertions, 38 deletions
diff --git a/net/tipc/msg.c b/net/tipc/msg.c index ce7514ae6bf3..5b0659791c07 100644 --- a/net/tipc/msg.c +++ b/net/tipc/msg.c | |||
@@ -166,11 +166,12 @@ err: | |||
166 | * @offset: Posision in iov to start copying from | 166 | * @offset: Posision in iov to start copying from |
167 | * @dsz: Total length of user data | 167 | * @dsz: Total length of user data |
168 | * @pktmax: Max packet size that can be used | 168 | * @pktmax: Max packet size that can be used |
169 | * @chain: Buffer or chain of buffers to be returned to caller | 169 | * @list: Buffer or chain of buffers to be returned to caller |
170 | * | ||
170 | * Returns message data size or errno: -ENOMEM, -EFAULT | 171 | * Returns message data size or errno: -ENOMEM, -EFAULT |
171 | */ | 172 | */ |
172 | int tipc_msg_build(struct tipc_msg *mhdr, struct msghdr *m, | 173 | int tipc_msg_build(struct tipc_msg *mhdr, struct msghdr *m, int offset, |
173 | int offset, int dsz, int pktmax , struct sk_buff **chain) | 174 | int dsz, int pktmax, struct sk_buff_head *list) |
174 | { | 175 | { |
175 | int mhsz = msg_hdr_sz(mhdr); | 176 | int mhsz = msg_hdr_sz(mhdr); |
176 | int msz = mhsz + dsz; | 177 | int msz = mhsz + dsz; |
@@ -179,22 +180,22 @@ int tipc_msg_build(struct tipc_msg *mhdr, struct msghdr *m, | |||
179 | int pktrem = pktmax; | 180 | int pktrem = pktmax; |
180 | int drem = dsz; | 181 | int drem = dsz; |
181 | struct tipc_msg pkthdr; | 182 | struct tipc_msg pkthdr; |
182 | struct sk_buff *buf, *prev; | 183 | struct sk_buff *skb; |
183 | char *pktpos; | 184 | char *pktpos; |
184 | int rc; | 185 | int rc; |
185 | uint chain_sz = 0; | 186 | |
186 | msg_set_size(mhdr, msz); | 187 | msg_set_size(mhdr, msz); |
187 | 188 | ||
188 | /* No fragmentation needed? */ | 189 | /* No fragmentation needed? */ |
189 | if (likely(msz <= pktmax)) { | 190 | if (likely(msz <= pktmax)) { |
190 | buf = tipc_buf_acquire(msz); | 191 | skb = tipc_buf_acquire(msz); |
191 | *chain = buf; | 192 | if (unlikely(!skb)) |
192 | if (unlikely(!buf)) | ||
193 | return -ENOMEM; | 193 | return -ENOMEM; |
194 | skb_copy_to_linear_data(buf, mhdr, mhsz); | 194 | __skb_queue_tail(list, skb); |
195 | pktpos = buf->data + mhsz; | 195 | skb_copy_to_linear_data(skb, mhdr, mhsz); |
196 | TIPC_SKB_CB(buf)->chain_sz = 1; | 196 | pktpos = skb->data + mhsz; |
197 | if (!dsz || !memcpy_fromiovecend(pktpos, m->msg_iov, offset, dsz)) | 197 | if (!dsz || !memcpy_fromiovecend(pktpos, m->msg_iov, offset, |
198 | dsz)) | ||
198 | return dsz; | 199 | return dsz; |
199 | rc = -EFAULT; | 200 | rc = -EFAULT; |
200 | goto error; | 201 | goto error; |
@@ -207,15 +208,15 @@ int tipc_msg_build(struct tipc_msg *mhdr, struct msghdr *m, | |||
207 | msg_set_fragm_no(&pkthdr, pktno); | 208 | msg_set_fragm_no(&pkthdr, pktno); |
208 | 209 | ||
209 | /* Prepare first fragment */ | 210 | /* Prepare first fragment */ |
210 | *chain = buf = tipc_buf_acquire(pktmax); | 211 | skb = tipc_buf_acquire(pktmax); |
211 | if (!buf) | 212 | if (!skb) |
212 | return -ENOMEM; | 213 | return -ENOMEM; |
213 | chain_sz = 1; | 214 | __skb_queue_tail(list, skb); |
214 | pktpos = buf->data; | 215 | pktpos = skb->data; |
215 | skb_copy_to_linear_data(buf, &pkthdr, INT_H_SIZE); | 216 | skb_copy_to_linear_data(skb, &pkthdr, INT_H_SIZE); |
216 | pktpos += INT_H_SIZE; | 217 | pktpos += INT_H_SIZE; |
217 | pktrem -= INT_H_SIZE; | 218 | pktrem -= INT_H_SIZE; |
218 | skb_copy_to_linear_data_offset(buf, INT_H_SIZE, mhdr, mhsz); | 219 | skb_copy_to_linear_data_offset(skb, INT_H_SIZE, mhdr, mhsz); |
219 | pktpos += mhsz; | 220 | pktpos += mhsz; |
220 | pktrem -= mhsz; | 221 | pktrem -= mhsz; |
221 | 222 | ||
@@ -238,28 +239,25 @@ int tipc_msg_build(struct tipc_msg *mhdr, struct msghdr *m, | |||
238 | pktsz = drem + INT_H_SIZE; | 239 | pktsz = drem + INT_H_SIZE; |
239 | else | 240 | else |
240 | pktsz = pktmax; | 241 | pktsz = pktmax; |
241 | prev = buf; | 242 | skb = tipc_buf_acquire(pktsz); |
242 | buf = tipc_buf_acquire(pktsz); | 243 | if (!skb) { |
243 | if (!buf) { | ||
244 | rc = -ENOMEM; | 244 | rc = -ENOMEM; |
245 | goto error; | 245 | goto error; |
246 | } | 246 | } |
247 | chain_sz++; | 247 | __skb_queue_tail(list, skb); |
248 | prev->next = buf; | ||
249 | msg_set_type(&pkthdr, FRAGMENT); | 248 | msg_set_type(&pkthdr, FRAGMENT); |
250 | msg_set_size(&pkthdr, pktsz); | 249 | msg_set_size(&pkthdr, pktsz); |
251 | msg_set_fragm_no(&pkthdr, ++pktno); | 250 | msg_set_fragm_no(&pkthdr, ++pktno); |
252 | skb_copy_to_linear_data(buf, &pkthdr, INT_H_SIZE); | 251 | skb_copy_to_linear_data(skb, &pkthdr, INT_H_SIZE); |
253 | pktpos = buf->data + INT_H_SIZE; | 252 | pktpos = skb->data + INT_H_SIZE; |
254 | pktrem = pktsz - INT_H_SIZE; | 253 | pktrem = pktsz - INT_H_SIZE; |
255 | 254 | ||
256 | } while (1); | 255 | } while (1); |
257 | TIPC_SKB_CB(*chain)->chain_sz = chain_sz; | 256 | msg_set_type(buf_msg(skb), LAST_FRAGMENT); |
258 | msg_set_type(buf_msg(buf), LAST_FRAGMENT); | ||
259 | return dsz; | 257 | return dsz; |
260 | error: | 258 | error: |
261 | kfree_skb_list(*chain); | 259 | __skb_queue_purge(list); |
262 | *chain = NULL; | 260 | __skb_queue_head_init(list); |
263 | return rc; | 261 | return rc; |
264 | } | 262 | } |
265 | 263 | ||
@@ -430,22 +428,23 @@ int tipc_msg_eval(struct sk_buff *buf, u32 *dnode) | |||
430 | /* tipc_msg_reassemble() - clone a buffer chain of fragments and | 428 | /* tipc_msg_reassemble() - clone a buffer chain of fragments and |
431 | * reassemble the clones into one message | 429 | * reassemble the clones into one message |
432 | */ | 430 | */ |
433 | struct sk_buff *tipc_msg_reassemble(struct sk_buff *chain) | 431 | struct sk_buff *tipc_msg_reassemble(struct sk_buff_head *list) |
434 | { | 432 | { |
435 | struct sk_buff *buf = chain; | 433 | struct sk_buff *skb; |
436 | struct sk_buff *frag = buf; | 434 | struct sk_buff *frag = NULL; |
437 | struct sk_buff *head = NULL; | 435 | struct sk_buff *head = NULL; |
438 | int hdr_sz; | 436 | int hdr_sz; |
439 | 437 | ||
440 | /* Copy header if single buffer */ | 438 | /* Copy header if single buffer */ |
441 | if (!buf->next) { | 439 | if (skb_queue_len(list) == 1) { |
442 | hdr_sz = skb_headroom(buf) + msg_hdr_sz(buf_msg(buf)); | 440 | skb = skb_peek(list); |
443 | return __pskb_copy(buf, hdr_sz, GFP_ATOMIC); | 441 | hdr_sz = skb_headroom(skb) + msg_hdr_sz(buf_msg(skb)); |
442 | return __pskb_copy(skb, hdr_sz, GFP_ATOMIC); | ||
444 | } | 443 | } |
445 | 444 | ||
446 | /* Clone all fragments and reassemble */ | 445 | /* Clone all fragments and reassemble */ |
447 | while (buf) { | 446 | skb_queue_walk(list, skb) { |
448 | frag = skb_clone(buf, GFP_ATOMIC); | 447 | frag = skb_clone(skb, GFP_ATOMIC); |
449 | if (!frag) | 448 | if (!frag) |
450 | goto error; | 449 | goto error; |
451 | frag->next = NULL; | 450 | frag->next = NULL; |
@@ -453,7 +452,6 @@ struct sk_buff *tipc_msg_reassemble(struct sk_buff *chain) | |||
453 | break; | 452 | break; |
454 | if (!head) | 453 | if (!head) |
455 | goto error; | 454 | goto error; |
456 | buf = buf->next; | ||
457 | } | 455 | } |
458 | return frag; | 456 | return frag; |
459 | error: | 457 | error: |