#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"
/*
* 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;
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;
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;
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);