Merge tag 'v3.10.55' into update
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / fs / namespace.c
index 00409add4d9661f2511f647606e49fd1408729ee..31df51c8b24899b95cb6e562cdd125972a68c41e 100644 (file)
 #include <linux/fs_struct.h>   /* get_fs_root et.al. */
 #include <linux/fsnotify.h>    /* fsnotify_vfsmount_delete */
 #include <linux/uaccess.h>
+//#define UMOUNT_LOG  //enable kernel layer unmount log when unmount fail
+#ifdef UMOUNT_LOG
+#include <linux/types.h>
+#endif
 #include <linux/proc_ns.h>
 #include <linux/magic.h>
 #include "pnode.h"
@@ -132,10 +136,130 @@ void mnt_release_group_id(struct mount *mnt)
 /*
  * vfsmount lock must be held for read
  */
+#ifdef UMOUNT_LOG
+#define UMOUNT_Partition "/emmc@usrdata"
+struct  record_ref_count{ 
+  pid_t pid;
+  char name[TASK_COMM_LEN];
+  int count;
+  struct record_ref_count *next;
+};
+
+struct record_ref_count *ref_head    = NULL;
+struct record_ref_count *ref_current = NULL;
+struct record_ref_count *ref_prev    = NULL;
+int s_total_count = 0;
+#endif
 static inline void mnt_add_count(struct mount *mnt, int n)
 {
+#ifdef UMOUNT_LOG
+int print_link_list=0;
+#ifndef CONFIG_SMP
+       preempt_disable();
+#endif
+
+               if (strcmp(UMOUNT_Partition,mnt->mnt_devname)==0)
+                       {
+                               //if (strcmp("mobile_log_d",current->comm)!=0) 
+                                       {
+                                       //if (current->pid < 100)       //((current->pid < 70) && (current->pid > 60))  
+                                       {
+                                               //printk("Ahsin n=%d  current->pid=%d name=%s \n",n,current->pid,current->comm);
+                                               spin_lock(&mnt_id_lock);
+                                               if (ref_head == NULL) //linked list head (start)
+                                               {
+                                                       printk("Ahsin link list init mnt_get_count=%d \n",mnt_get_count(mnt));
+                                                       
+                                                       ref_current = kmalloc(sizeof(struct record_ref_count), GFP_KERNEL);
+                                               if (ref_current == NULL)
+                                                           printk("Ahsin can't allocate memory for ref_current /n");
+
+                                                       ref_current->next = NULL;
+                                                       ref_current->pid = current->pid;
+                                                       strncpy(ref_current->name, current->comm, TASK_COMM_LEN -1);                                    
+                                                       ref_current->name[TASK_COMM_LEN -1] = '\0';
+                                                       ref_current->count = n;
+                                                       s_total_count = s_total_count + n;
+                                                       ref_head = ref_current;
+                                                       
+                                                       printk("Ahsin ref_head == NULL pid=%d name=%s counter=%d n=%d \n",ref_current->pid,ref_current->name,ref_current->count,n);
+                                               }
+                                               else //check exist first and then add linked list or modify counter
+                                               {
+                                                       ref_prev = ref_head;
+                                                       while(ref_prev != NULL) 
+                                                       {
+                                                               //printk("Ahsin PID= %d, Name= %s, Count= %d n=%d  current->pid=%d \n", ref_prev->pid, ref_prev->name, ref_prev->count,n,current->pid);
+                                                               if (strcmp(ref_prev->name,current->comm)==0) //(ref_prev->pid==current->pid)//exist and find, modify counter
+                                                               {
+                                                                       ref_prev->count = ref_prev->count + n;
+                                                                       s_total_count = s_total_count + n;
+                                                                       //printk("Ahsin (ref_prev->name,current->comm) pid=%d name=%s counter=%d n=%d \n",ref_prev->pid,ref_prev->name,ref_prev->count,n);
+                                                                       break;
+                                                               }
+                                                               else 
+                                                               {
+                                                                       if (ref_prev->next != NULL) 
+                                                                               ref_prev = ref_prev->next;
+                                                                       else 
+                                                                       {       // end of link list
+                                                                               ref_current = kmalloc(sizeof(struct record_ref_count), GFP_KERNEL);
+                                                                               if (ref_current == NULL)
+                                                                                   printk("Ahsin can't allocate memory for ref_prev /n");
+
+                                                                               ref_current->next = NULL;
+                                                                               ref_current->pid = current->pid;
+                                                                               strncpy(ref_current->name, current->comm, TASK_COMM_LEN -1);                                    
+                                                                               ref_current->name[TASK_COMM_LEN -1] = '\0';
+                                                                               ref_current->count = n;
+                                                                               s_total_count = s_total_count + n;
+                                                                               ref_prev->next = ref_current;
+                                                                               //printk("Ahsin new node(end of link list) pid=%d name=%s counter=%d n=%d \n",ref_current->pid,ref_current->name,ref_current->count,n);
+                                                                               break;
+                                                                               
+                                                                       }
+                                                               }
+                                                       }
+                                               }
+                                               spin_unlock(&mnt_id_lock);
+                                       }
+                                       }
+                       }
+
+#ifndef CONFIG_SMP
+       preempt_enable();
+#endif
+#endif
 #ifdef CONFIG_SMP
        this_cpu_add(mnt->mnt_pcp->mnt_count, n);
+#ifdef UMOUNT_LOG
+#if 0
+       if (strcmp(UMOUNT_Partition,mnt->mnt_devname)==0)
+       {
+               if (strcmp("mobile_log_d",current->comm)!=0) 
+                       {
+                               printk("Ahsin s_total_count=%d mnt_get_count=%d n=%d  current->pid=%d \n",s_total_count,mnt_get_count(mnt),n,current->pid);
+                       //if (current->pid < 100)
+                               {       
+                                       // print linked list
+                                       spin_lock(&mnt_id_lock);
+                                       ref_current = ref_head;
+                                       while(ref_current != NULL) 
+                                       {
+                                               if (ref_current->count)
+                                                       {
+                                                               print_link_list = print_link_list + ref_current->count;
+                                                               //printk("Ahsin PID= %d, Name = %s, Count= %d \n", ref_current->pid, ref_current->name, ref_current->count);
+                                                       }
+                                               ref_current = ref_current->next;
+                                       }
+                                       spin_unlock(&mnt_id_lock);
+                                       printk("Ahsin print_link_list=%d \n",print_link_list);
+                               }
+                       }
+       }
+#endif 
+#endif
 #else
        preempt_disable();
        mnt->mnt_count += n;
@@ -183,6 +307,12 @@ static struct mount *alloc_vfsmnt(const char *name)
                if (!mnt->mnt_pcp)
                        goto out_free_devname;
 
+#ifdef UMOUNT_LOG
+               if (strcmp(UMOUNT_Partition,mnt->mnt_devname)==0)
+               {
+                       printk("Ahsin alloc_vfsmnt current->pid=%d name=%s \n",current->pid,current->comm);     
+               }
+#endif         
                this_cpu_add(mnt->mnt_pcp->mnt_count, 1);
 #else
                mnt->mnt_count = 1;
@@ -1321,7 +1451,9 @@ SYSCALL_DEFINE2(umount, char __user *, name, int, flags)
        struct mount *mnt;
        int retval;
        int lookup_flags = 0;
-
+#ifdef UMOUNT_LOG      
+       int total_value =0;
+#endif
        if (flags & ~(MNT_FORCE | MNT_DETACH | MNT_EXPIRE | UMOUNT_NOFOLLOW))
                return -EINVAL;
 
@@ -1342,6 +1474,32 @@ SYSCALL_DEFINE2(umount, char __user *, name, int, flags)
                goto dput_and_out;
 
        retval = do_umount(mnt, flags);
+#ifdef UMOUNT_LOG
+       {
+               printk("Ahsin do_umount retval=%d \n",retval);
+               //do_umount success: 0, do_umount busy: -16
+               //if do_umount fail, need to dump the link list here
+       
+               if(retval)
+                       printk("Ahsin do_umount fail;  mnt_get_count=%d   mnt->mnt_devname=%s\n",mnt_get_count(mnt),mnt->mnt_devname);          
+               else
+                       printk("Ahsin do_umount success;  mnt_get_count=%d   mnt->mnt_devname=%s\n",mnt_get_count(mnt),mnt->mnt_devname);               
+               
+               // print linked list
+               spin_lock(&mnt_id_lock);
+               ref_current = ref_head;
+               while(ref_current != NULL) 
+               {
+                       total_value = total_value + ref_current->count;
+                       
+                       if (ref_current->count)
+                               printk("Ahsin PID= %d, Name = %s, Count= %d \n", ref_current->pid, ref_current->name, ref_current->count);
+                       ref_current = ref_current->next;
+               }
+               spin_unlock(&mnt_id_lock);
+               printk("Ahsin total_value=%d \n",total_value);
+       }
+#endif
 dput_and_out:
        /* we mustn't call path_put() as that would clear mnt_expiry_mark */
        dput(path.dentry);