disable some mediatekl custom warnings
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / fs / namespace.c
index b4f96a5230a3874ebde148f42eedba02207e0c20..83151b9915c7bd2e430a75c17a07f319dfbd8d56 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;
@@ -1308,7 +1438,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;
 
@@ -1329,6 +1461,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);
@@ -1429,7 +1587,7 @@ struct vfsmount *collect_mounts(struct path *path)
                         CL_COPY_ALL | CL_PRIVATE);
        namespace_unlock();
        if (IS_ERR(tree))
-               return NULL;
+               return ERR_CAST(tree);
        return &tree->mnt;
 }
 
@@ -2284,12 +2442,11 @@ long do_mount(const char *dev_name, const char *dir_name,
 
        retval = security_sb_mount(dev_name, &path,
                                   type_page, flags, data_page);
+       if (!retval && !may_mount())
+               retval = -EPERM;
        if (retval)
                goto dput_out;
 
-       if (!may_mount())
-               return -EPERM;
-
        /* Default to relatime unless overriden */
        if (!(flags & MS_NOATIME))
                mnt_flags |= MNT_RELATIME;
@@ -2464,7 +2621,7 @@ static struct mnt_namespace *create_mnt_ns(struct vfsmount *m)
                struct mount *mnt = real_mount(m);
                mnt->mnt_ns = new_ns;
                new_ns->root = mnt;
-               list_add(&new_ns->list, &mnt->mnt_list);
+               list_add(&mnt->mnt_list, &new_ns->list);
        } else {
                mntput(m);
        }