diff options
author | Lorenzo Stoakes <lstoakes@gmail.com> | 2016-10-12 20:20:11 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-10-18 17:13:36 -0400 |
commit | 859110d7497cdd0e6b21010d6f777049d676382c (patch) | |
tree | d2da6062b292dd6478a607bb8d564047d087144c | |
parent | 19be0eaffa3ac7d8eb6784ad9bdbc7d67ed8e619 (diff) |
mm: remove write/force parameters from __get_user_pages_locked()
This removes the redundant 'write' and 'force' parameters from
__get_user_pages_locked() to make the use of FOLL_FORCE explicit in
callers as use of this flag can result in surprising behaviour (and
hence bugs) within the mm subsystem.
Signed-off-by: Lorenzo Stoakes <lstoakes@gmail.com>
Reviewed-by: Jan Kara <jack@suse.cz>
Acked-by: Michal Hocko <mhocko@suse.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | mm/gup.c | 47 |
1 files changed, 33 insertions, 14 deletions
@@ -739,7 +739,6 @@ static __always_inline long __get_user_pages_locked(struct task_struct *tsk, | |||
739 | struct mm_struct *mm, | 739 | struct mm_struct *mm, |
740 | unsigned long start, | 740 | unsigned long start, |
741 | unsigned long nr_pages, | 741 | unsigned long nr_pages, |
742 | int write, int force, | ||
743 | struct page **pages, | 742 | struct page **pages, |
744 | struct vm_area_struct **vmas, | 743 | struct vm_area_struct **vmas, |
745 | int *locked, bool notify_drop, | 744 | int *locked, bool notify_drop, |
@@ -757,10 +756,6 @@ static __always_inline long __get_user_pages_locked(struct task_struct *tsk, | |||
757 | 756 | ||
758 | if (pages) | 757 | if (pages) |
759 | flags |= FOLL_GET; | 758 | flags |= FOLL_GET; |
760 | if (write) | ||
761 | flags |= FOLL_WRITE; | ||
762 | if (force) | ||
763 | flags |= FOLL_FORCE; | ||
764 | 759 | ||
765 | pages_done = 0; | 760 | pages_done = 0; |
766 | lock_dropped = false; | 761 | lock_dropped = false; |
@@ -856,9 +851,15 @@ long get_user_pages_locked(unsigned long start, unsigned long nr_pages, | |||
856 | int write, int force, struct page **pages, | 851 | int write, int force, struct page **pages, |
857 | int *locked) | 852 | int *locked) |
858 | { | 853 | { |
854 | unsigned int flags = FOLL_TOUCH; | ||
855 | |||
856 | if (write) | ||
857 | flags |= FOLL_WRITE; | ||
858 | if (force) | ||
859 | flags |= FOLL_FORCE; | ||
860 | |||
859 | return __get_user_pages_locked(current, current->mm, start, nr_pages, | 861 | return __get_user_pages_locked(current, current->mm, start, nr_pages, |
860 | write, force, pages, NULL, locked, true, | 862 | pages, NULL, locked, true, flags); |
861 | FOLL_TOUCH); | ||
862 | } | 863 | } |
863 | EXPORT_SYMBOL(get_user_pages_locked); | 864 | EXPORT_SYMBOL(get_user_pages_locked); |
864 | 865 | ||
@@ -879,9 +880,15 @@ __always_inline long __get_user_pages_unlocked(struct task_struct *tsk, struct m | |||
879 | { | 880 | { |
880 | long ret; | 881 | long ret; |
881 | int locked = 1; | 882 | int locked = 1; |
883 | |||
884 | if (write) | ||
885 | gup_flags |= FOLL_WRITE; | ||
886 | if (force) | ||
887 | gup_flags |= FOLL_FORCE; | ||
888 | |||
882 | down_read(&mm->mmap_sem); | 889 | down_read(&mm->mmap_sem); |
883 | ret = __get_user_pages_locked(tsk, mm, start, nr_pages, write, force, | 890 | ret = __get_user_pages_locked(tsk, mm, start, nr_pages, pages, NULL, |
884 | pages, NULL, &locked, false, gup_flags); | 891 | &locked, false, gup_flags); |
885 | if (locked) | 892 | if (locked) |
886 | up_read(&mm->mmap_sem); | 893 | up_read(&mm->mmap_sem); |
887 | return ret; | 894 | return ret; |
@@ -973,9 +980,15 @@ long get_user_pages_remote(struct task_struct *tsk, struct mm_struct *mm, | |||
973 | int write, int force, struct page **pages, | 980 | int write, int force, struct page **pages, |
974 | struct vm_area_struct **vmas) | 981 | struct vm_area_struct **vmas) |
975 | { | 982 | { |
976 | return __get_user_pages_locked(tsk, mm, start, nr_pages, write, force, | 983 | unsigned int flags = FOLL_TOUCH | FOLL_REMOTE; |
977 | pages, vmas, NULL, false, | 984 | |
978 | FOLL_TOUCH | FOLL_REMOTE); | 985 | if (write) |
986 | flags |= FOLL_WRITE; | ||
987 | if (force) | ||
988 | flags |= FOLL_FORCE; | ||
989 | |||
990 | return __get_user_pages_locked(tsk, mm, start, nr_pages, pages, vmas, | ||
991 | NULL, false, flags); | ||
979 | } | 992 | } |
980 | EXPORT_SYMBOL(get_user_pages_remote); | 993 | EXPORT_SYMBOL(get_user_pages_remote); |
981 | 994 | ||
@@ -989,9 +1002,15 @@ long get_user_pages(unsigned long start, unsigned long nr_pages, | |||
989 | int write, int force, struct page **pages, | 1002 | int write, int force, struct page **pages, |
990 | struct vm_area_struct **vmas) | 1003 | struct vm_area_struct **vmas) |
991 | { | 1004 | { |
1005 | unsigned int flags = FOLL_TOUCH; | ||
1006 | |||
1007 | if (write) | ||
1008 | flags |= FOLL_WRITE; | ||
1009 | if (force) | ||
1010 | flags |= FOLL_FORCE; | ||
1011 | |||
992 | return __get_user_pages_locked(current, current->mm, start, nr_pages, | 1012 | return __get_user_pages_locked(current, current->mm, start, nr_pages, |
993 | write, force, pages, vmas, NULL, false, | 1013 | pages, vmas, NULL, false, flags); |
994 | FOLL_TOUCH); | ||
995 | } | 1014 | } |
996 | EXPORT_SYMBOL(get_user_pages); | 1015 | EXPORT_SYMBOL(get_user_pages); |
997 | 1016 | ||