Merge tag 'v3.10.95' into update
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / net / core / sock.c
index d4f4cea726e7bfdb0d9cc47a779d5252738bf37c..66e2ab8888eece6be9ff5cba28c45f08f2889e21 100644 (file)
 
 #include <trace/events/sock.h>
 
+#include <net/af_unix.h>
+
+
 #ifdef CONFIG_INET
 #include <net/tcp.h>
 #endif
+#include <linux/xlog.h>
 
 static DEFINE_MUTEX(proto_list_mutex);
 static LIST_HEAD(proto_list);
 
+/**
+ * sk_ns_capable - General socket capability test
+ * @sk: Socket to use a capability on or through
+ * @user_ns: The user namespace of the capability to use
+ * @cap: The capability to use
+ *
+ * Test to see if the opener of the socket had when the socket was
+ * created and the current process has the capability @cap in the user
+ * namespace @user_ns.
+ */
+bool sk_ns_capable(const struct sock *sk,
+                  struct user_namespace *user_ns, int cap)
+{
+       return file_ns_capable(sk->sk_socket->file, user_ns, cap) &&
+               ns_capable(user_ns, cap);
+}
+EXPORT_SYMBOL(sk_ns_capable);
+
+/**
+ * sk_capable - Socket global capability test
+ * @sk: Socket to use a capability on or through
+ * @cap: The global capbility to use
+ *
+ * Test to see if the opener of the socket had when the socket was
+ * created and the current process has the capability @cap in all user
+ * namespaces.
+ */
+bool sk_capable(const struct sock *sk, int cap)
+{
+       return sk_ns_capable(sk, &init_user_ns, cap);
+}
+EXPORT_SYMBOL(sk_capable);
+
+/**
+ * sk_net_capable - Network namespace socket capability test
+ * @sk: Socket to use a capability on or through
+ * @cap: The capability to use
+ *
+ * Test to see if the opener of the socket had when the socke was created
+ * and the current process has the capability @cap over the network namespace
+ * the socket is a member of.
+ */
+bool sk_net_capable(const struct sock *sk, int cap)
+{
+       return sk_ns_capable(sk, sock_net(sk)->user_ns, cap);
+}
+EXPORT_SYMBOL(sk_net_capable);
+
+
 #ifdef CONFIG_MEMCG_KMEM
 int mem_cgroup_sockets_init(struct mem_cgroup *memcg, struct cgroup_subsys *ss)
 {
@@ -210,7 +263,7 @@ static const char *const af_family_key_strings[AF_MAX+1] = {
   "sk_lock-AF_TIPC"  , "sk_lock-AF_BLUETOOTH", "sk_lock-IUCV"        ,
   "sk_lock-AF_RXRPC" , "sk_lock-AF_ISDN"     , "sk_lock-AF_PHONET"   ,
   "sk_lock-AF_IEEE802154", "sk_lock-AF_CAIF" , "sk_lock-AF_ALG"      ,
-  "sk_lock-AF_NFC"   , "sk_lock-AF_MAX"
+  "sk_lock-AF_NFC"   , "sk_lock-AF_VSOCK"    , "sk_lock-AF_MAX"
 };
 static const char *const af_family_slock_key_strings[AF_MAX+1] = {
   "slock-AF_UNSPEC", "slock-AF_UNIX"     , "slock-AF_INET"     ,
@@ -226,7 +279,7 @@ static const char *const af_family_slock_key_strings[AF_MAX+1] = {
   "slock-AF_TIPC"  , "slock-AF_BLUETOOTH", "slock-AF_IUCV"     ,
   "slock-AF_RXRPC" , "slock-AF_ISDN"     , "slock-AF_PHONET"   ,
   "slock-AF_IEEE802154", "slock-AF_CAIF" , "slock-AF_ALG"      ,
-  "slock-AF_NFC"   , "slock-AF_MAX"
+  "slock-AF_NFC"   , "slock-AF_VSOCK"    ,"slock-AF_MAX"
 };
 static const char *const af_family_clock_key_strings[AF_MAX+1] = {
   "clock-AF_UNSPEC", "clock-AF_UNIX"     , "clock-AF_INET"     ,
@@ -242,7 +295,7 @@ static const char *const af_family_clock_key_strings[AF_MAX+1] = {
   "clock-AF_TIPC"  , "clock-AF_BLUETOOTH", "clock-AF_IUCV"     ,
   "clock-AF_RXRPC" , "clock-AF_ISDN"     , "clock-AF_PHONET"   ,
   "clock-AF_IEEE802154", "clock-AF_CAIF" , "clock-AF_ALG"      ,
-  "clock-AF_NFC"   , "clock-AF_MAX"
+  "clock-AF_NFC"   , "clock-AF_VSOCK"    , "clock-AF_MAX"
 };
 
 /*
@@ -264,7 +317,7 @@ static struct lock_class_key af_callback_keys[AF_MAX];
 /* Run time adjustable parameters. */
 __u32 sysctl_wmem_max __read_mostly = SK_WMEM_MAX;
 EXPORT_SYMBOL(sysctl_wmem_max);
-__u32 sysctl_rmem_max __read_mostly = SK_RMEM_MAX;
+__u32 sysctl_rmem_max __read_mostly = (SK_RMEM_MAX*8);
 EXPORT_SYMBOL(sysctl_rmem_max);
 __u32 sysctl_wmem_default __read_mostly = SK_WMEM_MAX;
 __u32 sysctl_rmem_default __read_mostly = SK_RMEM_MAX;
@@ -370,8 +423,6 @@ static void sock_warn_obsolete_bsdism(const char *name)
        }
 }
 
-#define SK_FLAGS_TIMESTAMP ((1UL << SOCK_TIMESTAMP) | (1UL << SOCK_TIMESTAMPING_RX_SOFTWARE))
-
 static void sock_disable_timestamp(struct sock *sk, unsigned long flags)
 {
        if (sk->sk_flags & flags) {
@@ -571,9 +622,7 @@ static int sock_getbindtodevice(struct sock *sk, char __user *optval,
        int ret = -ENOPROTOOPT;
 #ifdef CONFIG_NETDEVICES
        struct net *net = sock_net(sk);
-       struct net_device *dev;
        char devname[IFNAMSIZ];
-       unsigned seq;
 
        if (sk->sk_bound_dev_if == 0) {
                len = 0;
@@ -584,20 +633,9 @@ static int sock_getbindtodevice(struct sock *sk, char __user *optval,
        if (len < IFNAMSIZ)
                goto out;
 
-retry:
-       seq = read_seqcount_begin(&devnet_rename_seq);
-       rcu_read_lock();
-       dev = dev_get_by_index_rcu(net, sk->sk_bound_dev_if);
-       ret = -ENODEV;
-       if (!dev) {
-               rcu_read_unlock();
+       ret = netdev_get_name(net, devname, sk->sk_bound_dev_if);
+       if (ret)
                goto out;
-       }
-
-       strcpy(devname, dev->name);
-       rcu_read_unlock();
-       if (read_seqcount_retry(&devnet_rename_seq, seq))
-               goto retry;
 
        len = strlen(devname) + 1;
 
@@ -691,7 +729,7 @@ int sock_setsockopt(struct socket *sock, int level, int optname,
                val = min_t(u32, val, sysctl_wmem_max);
 set_sndbuf:
                sk->sk_userlocks |= SOCK_SNDBUF_LOCK;
-               sk->sk_sndbuf = max_t(u32, val * 2, SOCK_MIN_SNDBUF);
+               sk->sk_sndbuf = max_t(int, val * 2, SOCK_MIN_SNDBUF);
                /* Wake up sending tasks if we upped the value. */
                sk->sk_write_space(sk);
                break;
@@ -727,7 +765,7 @@ set_rcvbuf:
                 * returning the value we actually used in getsockopt
                 * is the most desirable behavior.
                 */
-               sk->sk_rcvbuf = max_t(u32, val * 2, SOCK_MIN_RCVBUF);
+               sk->sk_rcvbuf = max_t(int, val * 2, SOCK_MIN_RCVBUF);
                break;
 
        case SO_RCVBUFFORCE:
@@ -898,7 +936,7 @@ set_rcvbuf:
 
        case SO_PEEK_OFF:
                if (sock->ops->set_peek_off)
-                       sock->ops->set_peek_off(sk, val);
+                       ret = sock->ops->set_peek_off(sk, val);
                else
                        ret = -EOPNOTSUPP;
                break;
@@ -1217,18 +1255,6 @@ static void sock_copy(struct sock *nsk, const struct sock *osk)
 #endif
 }
 
-/*
- * caches using SLAB_DESTROY_BY_RCU should let .next pointer from nulls nodes
- * un-modified. Special care is taken when initializing object to zero.
- */
-static inline void sk_prot_clear_nulls(struct sock *sk, int size)
-{
-       if (offsetof(struct sock, sk_node.next) != 0)
-               memset(sk, 0, offsetof(struct sock, sk_node.next));
-       memset(&sk->sk_node.pprev, 0,
-              size - offsetof(struct sock, sk_node.pprev));
-}
-
 void sk_prot_clear_portaddr_nulls(struct sock *sk, int size)
 {
        unsigned long nulls1, nulls2;
@@ -1608,7 +1634,13 @@ EXPORT_SYMBOL(sock_edemux);
 kuid_t sock_i_uid(struct sock *sk)
 {
        kuid_t uid;
-
+       
+       /*mtk_net: fix kernel bug*/
+       if (!sk) {
+               pr_info("sk == NULL for sock_i_uid\n");
+               return GLOBAL_ROOT_UID;
+       }
+       
        read_lock_bh(&sk->sk_callback_lock);
        uid = sk->sk_socket ? SOCK_INODE(sk->sk_socket)->i_uid : GLOBAL_ROOT_UID;
        read_unlock_bh(&sk->sk_callback_lock);
@@ -1719,6 +1751,111 @@ static long sock_wait_for_wmem(struct sock *sk, long timeo)
 }
 
 
+//debug funcion
+
+static int sock_dump_info(struct sock *sk)
+{
+    //dump receiver queue 128 bytes
+    //struct sk_buff *skb;
+    //char skbmsg[128];
+    //dump receiver queue 128 bytes end
+
+               if(sk->sk_family == AF_UNIX)
+               {
+                 struct unix_sock *u = unix_sk(sk);
+                 struct sock *other = NULL;
+                 if( (u->path.dentry !=NULL)&&(u->path.dentry->d_iname!=NULL))
+                  //if( (u->dentry !=NULL)&&(u->dentry->d_iname!=NULL))
+                 {
+                         #ifdef CONFIG_MTK_NET_LOGGING  
+                     printk(KERN_INFO "[mtk_net][sock]sockdbg: socket-Name:%s \n",u->path.dentry->d_iname);
+                     #endif
+                 }
+                  else
+                 {
+                          #ifdef CONFIG_MTK_NET_LOGGING  
+               printk(KERN_INFO "[mtk_net][sock]sockdbg:socket Name (NULL)\n" );
+               #endif
+                  }
+                  
+                  if(sk->sk_socket && SOCK_INODE(sk->sk_socket))
+                 {
+                               #ifdef CONFIG_MTK_NET_LOGGING  
+                       printk(KERN_INFO "[mtk_net][sock]sockdbg:socket Inode[%lu]\n" ,SOCK_INODE(sk->sk_socket)->i_ino);
+                       #endif
+                  }             
+
+                   other = unix_sk(sk)->peer ;
+                       if (!other)
+                       {
+                               #ifdef CONFIG_MTK_NET_LOGGING  
+                       printk(KERN_INFO "[mtk_net][sock]sockdbg:peer is (NULL) \n");
+                       #endif
+                        } else{
+                        
+                               if ((((struct unix_sock *)other)->path.dentry != NULL)&&(((struct unix_sock *)other)->path.dentry->d_iname != NULL))
+                                //if ((((struct unix_sock *)other)->dentry != NULL)&&(((struct unix_sock *)other)->dentry->d_iname != NULL))
+                               {
+                                       #ifdef CONFIG_MTK_NET_LOGGING  
+                           printk(KERN_INFO "[mtk_net][sock]sockdbg: Peer Name:%s \n",((struct unix_sock *)other)->path.dentry->d_iname);
+                           #endif
+                                }                              
+                               else
+                               {
+                                       #ifdef CONFIG_MTK_NET_LOGGING  
+                    printk(KERN_INFO "[mtk_net][sock]sockdbg: Peer Name (NULL) \n");
+                    #endif
+                               }
+
+                               if(other->sk_socket && SOCK_INODE(other->sk_socket))
+                                  {
+                                       #ifdef CONFIG_MTK_NET_LOGGING  
+                           printk(KERN_INFO "[mtk_net][sock]sockdbg: Peer Inode [%lu] \n", SOCK_INODE(other->sk_socket)->i_ino);
+                           #endif
+                                   }
+                   #ifdef CONFIG_MTK_NET_LOGGING  
+                               printk(KERN_INFO "[mtk_net][sock]sockdbg: Peer Recieve Queue len:%d \n",other->sk_receive_queue.qlen);
+                #endif
+                                //dump receiver queue 128 bytes
+                                               /* if ((skb = skb_peek_tail(&other->sk_receive_queue)) == NULL) {
+                                       
+                                   printk(KERN_INFO "sockdbg: Peer Recieve Queue is null (warning) \n");
+                                                }else{
+                                                      int i =0 ,len=0;
+                                     if((skb->len !=0) && (skb->data != NULL)){
+
+                                       if(skb->len >= 127){
+                                                                       len = 127 ;                          
+                                                                }else
+                                                                {
+                                          len = skb->len ;
+                                                                }
+                                       for (i=0;i<len;i++)
+                                                                 sprintf(skbmsg+i, "%x", skb->data[i]);
+
+                                                               skbmsg[len]= '\0' ;
+                                                               
+                                       printk(KERN_INFO "sockdbg: Peer Recieve Queue dump(%d bytes):%s\n", len, skbmsg);
+                                                                                               
+                                       
+                                                         }else{                
+                                       printk(KERN_INFO "sockdbg: Peer Recieve skb error \n");
+                                                         }*/
+                     //dump receiver queue 128 bytes end      
+
+                                //}
+                               //dump receiver queue 128 bytes end                              
+
+                        }
+               }
+
+               return 0 ;        
+
+       
+}
+
+
+
 /*
  *     Generic send/receive buffer handlers
  */
@@ -1794,7 +1931,17 @@ struct sk_buff *sock_alloc_send_pskb(struct sock *sk, unsigned long header_len,
                        goto failure;
                if (signal_pending(current))
                        goto interrupted;
+
+        sock_dump_info(sk);
+        #ifdef CONFIG_MTK_NET_LOGGING  
+               printk(KERN_INFO "[mtk_net][sock]sockdbg: wait_for_wmem, timeo =%ld, wmem =%d, snd buf =%d \n",
+                        timeo, atomic_read(&sk->sk_wmem_alloc), sk->sk_sndbuf); 
+        #endif
                timeo = sock_wait_for_wmem(sk, timeo);
+               #ifdef CONFIG_MTK_NET_LOGGING  
+               printk(KERN_INFO "[mtk_net][sock]sockdbg: wait_for_wmem done, header_len=0x%lx, data_len=0x%lx,timeo =%ld \n",
+                        header_len, data_len ,timeo);
+           #endif
        }
 
        skb_set_owner_w(skb, sk);
@@ -1839,7 +1986,7 @@ bool sk_page_frag_refill(struct sock *sk, struct page_frag *pfrag)
                gfp_t gfp = sk->sk_allocation;
 
                if (order)
-                       gfp |= __GFP_COMP | __GFP_NOWARN;
+                       gfp |= __GFP_COMP | __GFP_NOWARN | __GFP_NORETRY;
                pfrag->page = alloc_pages(gfp, order);
                if (likely(pfrag->page)) {
                        pfrag->offset = 0;
@@ -2296,6 +2443,7 @@ void sock_init_data(struct socket *sock, struct sock *sk)
 
        sk->sk_stamp = ktime_set(-1L, 0);
 
+       sk->sk_pacing_rate = ~0U;
        /*
         * Before updating sk_refcnt, we must commit prior changes to memory
         * (Documentation/RCU/rculist_nulls.txt for details)
@@ -2333,10 +2481,13 @@ void release_sock(struct sock *sk)
        if (sk->sk_backlog.tail)
                __release_sock(sk);
 
+       /* Warning : release_cb() might need to release sk ownership,
+        * ie call sock_release_ownership(sk) before us.
+        */
        if (sk->sk_prot->release_cb)
                sk->sk_prot->release_cb(sk);
 
-       sk->sk_lock.owned = 0;
+       sock_release_ownership(sk);
        if (waitqueue_active(&sk->sk_lock.wq))
                wake_up(&sk->sk_lock.wq);
        spin_unlock_bh(&sk->sk_lock.slock);