@@ -401,7 +401,7 @@ static int ashmem_mmap(struct file *file, struct vm_area_struct *vma)
401401 ret = - EPERM ;
402402 goto out ;
403403 }
404- vma -> vm_flags &= ~ calc_vm_may_flags (~asma -> prot_mask );
404+ vm_flags_clear ( vma , calc_vm_may_flags (~asma -> prot_mask ) );
405405
406406 if (!asma -> file ) {
407407 char * name = ASHMEM_NAME_DEF ;
@@ -703,30 +703,33 @@ static int ashmem_pin(struct ashmem_area *asma, size_t pgstart, size_t pgend,
703703static int ashmem_unpin (struct ashmem_area * asma , size_t pgstart , size_t pgend ,
704704 struct ashmem_range * * new_range )
705705{
706- struct ashmem_range * range , * next ;
706+ struct ashmem_range * range = NULL , * iter , * next ;
707707 unsigned int purged = ASHMEM_NOT_PURGED ;
708708
709709restart :
710- list_for_each_entry_safe (range , next , & asma -> unpinned_list , unpinned ) {
710+ list_for_each_entry_safe (iter , next , & asma -> unpinned_list , unpinned ) {
711711 /* short circuit: this is our insertion point */
712- if (range_before_page (range , pgstart ))
712+ if (range_before_page (iter , pgstart )) {
713+ range = iter ;
713714 break ;
715+ }
714716
715717 /*
716718 * The user can ask us to unpin pages that are already entirely
717719 * or partially pinned. We handle those two cases here.
718720 */
719- if (page_range_subsumed_by_range (range , pgstart , pgend ))
721+ if (page_range_subsumed_by_range (iter , pgstart , pgend ))
720722 return 0 ;
721- if (page_range_in_range (range , pgstart , pgend )) {
722- pgstart = min (range -> pgstart , pgstart );
723- pgend = max (range -> pgend , pgend );
724- purged |= range -> purged ;
725- range_del (range );
723+ if (page_range_in_range (iter , pgstart , pgend )) {
724+ pgstart = min (iter -> pgstart , pgstart );
725+ pgend = max (iter -> pgend , pgend );
726+ purged |= iter -> purged ;
727+ range_del (iter );
726728 goto restart ;
727729 }
728730 }
729731
732+ range = list_prepare_entry (range , & asma -> unpinned_list , unpinned );
730733 range_alloc (asma , range , purged , pgstart , pgend , new_range );
731734 return 0 ;
732735}
@@ -817,6 +820,7 @@ static int ashmem_pin_unpin(struct ashmem_area *asma, unsigned long cmd,
817820static long ashmem_ioctl (struct file * file , unsigned int cmd , unsigned long arg )
818821{
819822 struct ashmem_area * asma = file -> private_data ;
823+ unsigned long ino ;
820824 long ret = - ENOTTY ;
821825
822826 switch (cmd ) {
@@ -860,6 +864,23 @@ static long ashmem_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
860864 ashmem_shrink_scan (& ashmem_shrinker , & sc );
861865 }
862866 break ;
867+ case ASHMEM_GET_FILE_ID :
868+ /* Lock around our check to avoid racing with ashmem_mmap(). */
869+ mutex_lock (& ashmem_mutex );
870+ if (!asma || !asma -> file ) {
871+ mutex_unlock (& ashmem_mutex );
872+ ret = - EINVAL ;
873+ break ;
874+ }
875+ ino = file_inode (asma -> file )-> i_ino ;
876+ mutex_unlock (& ashmem_mutex );
877+
878+ if (copy_to_user ((void __user * )arg , & ino , sizeof (ino ))) {
879+ ret = - EFAULT ;
880+ break ;
881+ }
882+ ret = 0 ;
883+ break ;
863884 }
864885
865886 return ret ;
@@ -916,6 +937,15 @@ static const struct file_operations ashmem_fops = {
916937#endif
917938};
918939
940+ /*
941+ * is_ashmem_file - Check if struct file* is associated with ashmem
942+ */
943+ int is_ashmem_file (struct file * file )
944+ {
945+ return file -> f_op == & ashmem_fops ;
946+ }
947+ EXPORT_SYMBOL_GPL (is_ashmem_file );
948+
919949static struct miscdevice ashmem_misc = {
920950 .minor = MISC_DYNAMIC_MINOR ,
921951 .name = "ashmem" ,
@@ -948,7 +978,7 @@ static int __init ashmem_init(void)
948978 goto out_free2 ;
949979 }
950980
951- ret = register_shrinker (& ashmem_shrinker );
981+ ret = register_shrinker (& ashmem_shrinker , "android-ashmem" );
952982 if (ret ) {
953983 pr_err ("failed to register shrinker!\n" );
954984 goto out_demisc ;
0 commit comments