]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - include/net/sock.h
[NET]: Fix race condition in sk_wait_event().
[linux-2.6-omap-h63xx.git] / include / net / sock.h
index ff13c4cc287add76e658418aaae91970c1c87f66..f63d0d56712c7c13febfa7016f5cc5ef2c1f734b 100644 (file)
@@ -478,9 +478,9 @@ static inline void sk_add_backlog(struct sock *sk, struct sk_buff *skb)
        rc = __condition;                                       \
        if (!rc) {                                              \
                *(__timeo) = schedule_timeout(*(__timeo));      \
-               rc = __condition;                               \
        }                                                       \
        lock_sock(__sk);                                        \
+       rc = __condition;                                       \
        rc;                                                     \
 })
 
@@ -493,6 +493,7 @@ extern void sk_stream_kill_queues(struct sock *sk);
 extern int sk_wait_data(struct sock *sk, long *timeo);
 
 struct request_sock_ops;
+struct timewait_sock_ops;
 
 /* Networking protocol blocks we attach to sockets.
  * socket layer -> transport layer interface
@@ -557,11 +558,10 @@ struct proto {
        kmem_cache_t            *slab;
        unsigned int            obj_size;
 
-       kmem_cache_t            *twsk_slab;
-       unsigned int            twsk_obj_size;
        atomic_t                *orphan_count;
 
        struct request_sock_ops *rsk_prot;
+       struct timewait_sock_ops *twsk_prot;
 
        struct module           *owner;
 
@@ -856,8 +856,8 @@ static inline int sk_filter(struct sock *sk, struct sk_buff *skb, int needlock)
                
                filter = sk->sk_filter;
                if (filter) {
-                       int pkt_len = sk_run_filter(skb, filter->insns,
-                                                   filter->len);
+                       unsigned int pkt_len = sk_run_filter(skb, filter->insns,
+                                                            filter->len);
                        if (!pkt_len)
                                err = -EPERM;
                        else
@@ -926,6 +926,29 @@ static inline void sock_put(struct sock *sk)
                sk_free(sk);
 }
 
+static inline int sk_receive_skb(struct sock *sk, struct sk_buff *skb)
+{
+       int rc = NET_RX_SUCCESS;
+
+       if (sk_filter(sk, skb, 0))
+               goto discard_and_relse;
+
+       skb->dev = NULL;
+
+       bh_lock_sock(sk);
+       if (!sock_owned_by_user(sk))
+               rc = sk->sk_backlog_rcv(sk, skb);
+       else
+               sk_add_backlog(sk, skb);
+       bh_unlock_sock(sk);
+out:
+       sock_put(sk);
+       return rc;
+discard_and_relse:
+       kfree_skb(skb);
+       goto out;
+}
+
 /* Detach socket from process context.
  * Announce socket dead, detach it from wait queue and inode.
  * Note that parent inode held reference count on this struct sock,
@@ -1166,7 +1189,10 @@ static inline int sock_queue_err_skb(struct sock *sk, struct sk_buff *skb)
  
 static inline int sock_error(struct sock *sk)
 {
-       int err = xchg(&sk->sk_err, 0);
+       int err;
+       if (likely(!sk->sk_err))
+               return 0;
+       err = xchg(&sk->sk_err, 0);
        return -err;
 }
 
@@ -1247,6 +1273,12 @@ static inline struct page *sk_stream_alloc_page(struct sock *sk)
                     (skb != (struct sk_buff *)&(sk)->sk_write_queue);  \
                     skb = skb->next)
 
+/*from STCP for fast SACK Process*/
+#define sk_stream_for_retrans_queue_from(skb, sk)                      \
+               for (; (skb != (sk)->sk_send_head) &&                   \
+                    (skb != (struct sk_buff *)&(sk)->sk_write_queue);  \
+                    skb = skb->next)
+
 /*
  *     Default write policy as shown to user space via poll/select/SIGIO
  */
@@ -1322,12 +1354,12 @@ extern int sock_get_timestamp(struct sock *, struct timeval __user *);
  *     Enable debug/info messages 
  */
 
-#if 0
-#define NETDEBUG(fmt, args...) do { } while (0)
-#define LIMIT_NETDEBUG(fmt, args...) do { } while(0)
-#else
+#ifdef CONFIG_NETDEBUG
 #define NETDEBUG(fmt, args...) printk(fmt,##args)
 #define LIMIT_NETDEBUG(fmt, args...) do { if (net_ratelimit()) printk(fmt,##args); } while(0)
+#else
+#define NETDEBUG(fmt, args...) do { } while (0)
+#define LIMIT_NETDEBUG(fmt, args...) do { } while(0)
 #endif
 
 /*