@@ -161,6 +161,43 @@ static struct sk_buff *skb_set_peeked(struct sk_buff *skb)
161161 return skb ;
162162}
163163
164+ struct sk_buff * __skb_try_recv_from_queue (struct sock * sk ,
165+ struct sk_buff_head * queue ,
166+ unsigned int flags ,
167+ void (* destructor )(struct sock * sk ,
168+ struct sk_buff * skb ),
169+ int * peeked , int * off , int * err ,
170+ struct sk_buff * * last )
171+ {
172+ struct sk_buff * skb ;
173+
174+ * last = queue -> prev ;
175+ skb_queue_walk (queue , skb ) {
176+ if (flags & MSG_PEEK ) {
177+ if (* off >= skb -> len && (skb -> len || * off ||
178+ skb -> peeked )) {
179+ * off -= skb -> len ;
180+ continue ;
181+ }
182+ if (!skb -> len ) {
183+ skb = skb_set_peeked (skb );
184+ if (unlikely (IS_ERR (skb ))) {
185+ * err = PTR_ERR (skb );
186+ return skb ;
187+ }
188+ }
189+ * peeked = 1 ;
190+ atomic_inc (& skb -> users );
191+ } else {
192+ __skb_unlink (skb , queue );
193+ if (destructor )
194+ destructor (sk , skb );
195+ }
196+ return skb ;
197+ }
198+ return NULL ;
199+ }
200+
164201/**
165202 * __skb_try_recv_datagram - Receive a datagram skbuff
166203 * @sk: socket
@@ -216,46 +253,20 @@ struct sk_buff *__skb_try_recv_datagram(struct sock *sk, unsigned int flags,
216253
217254 * peeked = 0 ;
218255 do {
256+ int _off = * off ;
257+
219258 /* Again only user level code calls this function, so nothing
220259 * interrupt level will suddenly eat the receive_queue.
221260 *
222261 * Look at current nfs client by the way...
223262 * However, this function was correct in any case. 8)
224263 */
225- int _off = * off ;
226-
227- * last = (struct sk_buff * )queue ;
228264 spin_lock_irqsave (& queue -> lock , cpu_flags );
229- skb_queue_walk (queue , skb ) {
230- * last = skb ;
231- if (flags & MSG_PEEK ) {
232- if (_off >= skb -> len && (skb -> len || _off ||
233- skb -> peeked )) {
234- _off -= skb -> len ;
235- continue ;
236- }
237- if (!skb -> len ) {
238- skb = skb_set_peeked (skb );
239- if (IS_ERR (skb )) {
240- error = PTR_ERR (skb );
241- spin_unlock_irqrestore (& queue -> lock ,
242- cpu_flags );
243- goto no_packet ;
244- }
245- }
246- * peeked = 1 ;
247- atomic_inc (& skb -> users );
248- } else {
249- __skb_unlink (skb , queue );
250- if (destructor )
251- destructor (sk , skb );
252- }
253- spin_unlock_irqrestore (& queue -> lock , cpu_flags );
254- * off = _off ;
255- return skb ;
256- }
257-
265+ skb = __skb_try_recv_from_queue (sk , queue , flags , destructor ,
266+ peeked , & _off , err , last );
258267 spin_unlock_irqrestore (& queue -> lock , cpu_flags );
268+ if (skb )
269+ return skb ;
259270
260271 if (!sk_can_busy_loop (sk ))
261272 break ;
@@ -335,24 +346,24 @@ void __skb_free_datagram_locked(struct sock *sk, struct sk_buff *skb, int len)
335346}
336347EXPORT_SYMBOL (__skb_free_datagram_locked );
337348
338- int __sk_queue_drop_skb (struct sock * sk , struct sk_buff * skb ,
339- unsigned int flags ,
349+ int __sk_queue_drop_skb (struct sock * sk , struct sk_buff_head * sk_queue ,
350+ struct sk_buff * skb , unsigned int flags ,
340351 void (* destructor )(struct sock * sk ,
341352 struct sk_buff * skb ))
342353{
343354 int err = 0 ;
344355
345356 if (flags & MSG_PEEK ) {
346357 err = - ENOENT ;
347- spin_lock_bh (& sk -> sk_receive_queue . lock );
348- if (skb == skb_peek (& sk -> sk_receive_queue )) {
349- __skb_unlink (skb , & sk -> sk_receive_queue );
358+ spin_lock_bh (& sk_queue -> lock );
359+ if (skb == skb_peek (sk_queue )) {
360+ __skb_unlink (skb , sk_queue );
350361 atomic_dec (& skb -> users );
351362 if (destructor )
352363 destructor (sk , skb );
353364 err = 0 ;
354365 }
355- spin_unlock_bh (& sk -> sk_receive_queue . lock );
366+ spin_unlock_bh (& sk_queue -> lock );
356367 }
357368
358369 atomic_inc (& sk -> sk_drops );
@@ -383,7 +394,8 @@ EXPORT_SYMBOL(__sk_queue_drop_skb);
383394
384395int skb_kill_datagram (struct sock * sk , struct sk_buff * skb , unsigned int flags )
385396{
386- int err = __sk_queue_drop_skb (sk , skb , flags , NULL );
397+ int err = __sk_queue_drop_skb (sk , & sk -> sk_receive_queue , skb , flags ,
398+ NULL );
387399
388400 kfree_skb (skb );
389401 sk_mem_reclaim_partial (sk );
0 commit comments