func: long do_mount(const char *dev_name, const char __user const char *type_page, unsigned long flags, void *data_page) struct path path ; int mnt_flags = 0 ; if ( ( flags & MS_MGC_MSK ) == MS_MGC_VAL )  flags &= ~MS_MGC_MSK; if ( data_page )  ( ( char * ) data_page ) [ PAGE_SIZE - 1 ] = 0; retval = user_path ( dir_name , & path ); if ( retval )  retval = security_sb_mount ( dev_name , & path , type_page , flags , data_page ); if ( ! retval && ! may_mount ( ) )  static inline bool may_mount(void) return ns_capable ( current -> nsproxy -> mnt_ns -> user_ns , CAP_SYS_ADMIN ) ; retval = - EPERM; if ( ! retval && ( flags & MS_MANDLOCK ) && ! may_mandlock ( ) )  static inline bool may_mandlock(void) return false ; retval = - EPERM; if ( retval )  if ( ! ( flags & MS_NOATIME ) )  mnt_flags |= MNT_RELATIME; if ( flags & MS_NOSUID )  mnt_flags |= MNT_NOSUID; if ( flags & MS_NODEV )  mnt_flags |= MNT_NODEV; if ( flags & MS_NOEXEC )  mnt_flags |= MNT_NOEXEC; if ( flags & MS_NOATIME )  mnt_flags |= MNT_NOATIME; if ( flags & MS_NODIRATIME )  mnt_flags |= MNT_NODIRATIME; if ( flags & MS_STRICTATIME )  mnt_flags &= ~ ( MNT_RELATIME | MNT_NOATIME ); if ( flags & MS_RDONLY )  mnt_flags |= MNT_READONLY; if ( ( flags & MS_REMOUNT ) && ( ( flags & ( MS_NOATIME | MS_NODIRATIME | MS_RELATIME | MS_STRICTATIME ) ) == 0 ) )  mnt_flags &= ~MNT_ATIME_MASK; mnt_flags |= path . mnt -> mnt_flags & MNT_ATIME_MASK; flags &= ~ ( MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_ACTIVE | MS_BORN | MS_NOATIME | MS_NODIRATIME | MS_RELATIME | MS_KERNMOUNT | MS_STRICTATIME ); if ( flags & MS_REMOUNT )  if ( flags & MS_BIND )  if ( flags & ( MS_SHARED | MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE ) )  if ( flags & MS_MOVE )  retval = do_new_mount ( & path , type_page , flags , mnt_flags , dev_name , data_page ); static int do_new_mount(struct path *path, const char *fstype, int int mnt_flags, const char *name, void *data) struct file_system_type * type ; struct vfsmount * mnt ; if ( ! fstype )  type = get_fs_type ( fstype ); if ( ! type )  mnt = vfs_kern_mount ( type , flags , name , data ); struct vfsmount vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void *data) struct mount * mnt ; struct dentry * root ; if ( ! type )  return ERR_PTR ( - ENODEV ) ; mnt = alloc_vfsmnt ( name ); static struct mount *alloc_vfsmnt(const char *name) struct mount * mnt = kmem_cache_zalloc ( mnt_cache , GFP_KERNEL ) ; if ( mnt )  int err ; err = mnt_alloc_id ( mnt ); static int mnt_alloc_id(struct mount *mnt) int res ; res = ida_get_new_above ( & mnt_id_ida , mnt_id_start , & mnt -> mnt_id ); if ( ! res )  mnt_id_start = mnt -> mnt_id + 1; if ( res == - EAGAIN )  return res ; if ( err )  if ( name )  mnt -> mnt_devname = kstrdup_const ( name , GFP_KERNEL ); if ( ! mnt -> mnt_devname )  mnt -> mnt_pcp = alloc_percpu ( struct mnt_pcp ) if ( ! mnt -> mnt_pcp )  return mnt ; return NULL ; if ( ! mnt )  return ERR_PTR ( - ENOMEM ) ; if ( flags & MS_KERNMOUNT )  mnt -> mnt . mnt_flags = MNT_INTERNAL; root = mount_fs ( type , flags , name , data ); if ( IS_ERR ( root ) )  return ERR_CAST ( root ) ; mnt -> mnt . mnt_root = root; mnt -> mnt . mnt_sb = root -> d_sb; mnt -> mnt_mountpoint = mnt -> mnt . mnt_root; mnt -> mnt_parent = mnt; return & mnt -> mnt ; if ( ! IS_ERR ( mnt ) && ( type -> fs_flags & FS_HAS_SUBTYPE ) && ! mnt -> mnt_sb -> s_subtype )  mnt = fs_set_subtype ( mnt , fstype ); static struct vfsmount *fs_set_subtype(struct vfsmount *mnt, const char *fstype) const char * subtype = strchr ( fstype , '.' ) ; if ( subtype )  subtype ++; if ( ! subtype [ 0 ] )  mnt -> mnt_sb -> s_subtype = kstrdup ( subtype , GFP_KERNEL ); if ( ! mnt -> mnt_sb -> s_subtype )  