Commit 0b173bc4daa8f8ec03a85abf5e47b23502ff80af

Authored by Konstantin Khlebnikov
Committed by Linus Torvalds
1 parent 4b6e1e3702

mm: kill vma flag VM_CAN_NONLINEAR

Move actual pte filling for non-linear file mappings into the new special
vma operation: ->remap_pages().

Filesystems must implement this method to get non-linear mapping support,
if it uses filemap_fault() then generic_file_remap_pages() can be used.

Now device drivers can implement this method and obtain nonlinear vma support.

Signed-off-by: Konstantin Khlebnikov <khlebnikov@openvz.org>
Cc: Alexander Viro <viro@zeniv.linux.org.uk>
Cc: Carsten Otte <cotte@de.ibm.com>
Cc: Chris Metcalf <cmetcalf@tilera.com>	#arch/tile
Cc: Cyrill Gorcunov <gorcunov@openvz.org>
Cc: Eric Paris <eparis@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Hugh Dickins <hughd@google.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: James Morris <james.l.morris@oracle.com>
Cc: Jason Baron <jbaron@redhat.com>
Cc: Kentaro Takeda <takedakn@nttdata.co.jp>
Cc: Matt Helsley <matthltc@us.ibm.com>
Cc: Nick Piggin <npiggin@kernel.dk>
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Robert Richter <robert.richter@amd.com>
Cc: Suresh Siddha <suresh.b.siddha@intel.com>
Cc: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Cc: Venkatesh Pallipadi <venki@google.com>
Acked-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

Showing 21 changed files with 39 additions and 23 deletions Side-by-side Diff

drivers/staging/android/ashmem.c
... ... @@ -332,7 +332,6 @@
332 332 if (vma->vm_file)
333 333 fput(vma->vm_file);
334 334 vma->vm_file = asma->file;
335   - vma->vm_flags |= VM_CAN_NONLINEAR;
336 335  
337 336 out:
338 337 mutex_unlock(&ashmem_mutex);
... ... @@ -738,6 +738,7 @@
738 738 static const struct vm_operations_struct v9fs_file_vm_ops = {
739 739 .fault = filemap_fault,
740 740 .page_mkwrite = v9fs_vm_page_mkwrite,
  741 + .remap_pages = generic_file_remap_pages,
741 742 };
742 743  
743 744  
... ... @@ -1599,6 +1599,7 @@
1599 1599 static const struct vm_operations_struct btrfs_file_vm_ops = {
1600 1600 .fault = filemap_fault,
1601 1601 .page_mkwrite = btrfs_page_mkwrite,
  1602 + .remap_pages = generic_file_remap_pages,
1602 1603 };
1603 1604  
1604 1605 static int btrfs_file_mmap(struct file *filp, struct vm_area_struct *vma)
... ... @@ -1610,7 +1611,6 @@
1610 1611  
1611 1612 file_accessed(filp);
1612 1613 vma->vm_ops = &btrfs_file_vm_ops;
1613   - vma->vm_flags |= VM_CAN_NONLINEAR;
1614 1614  
1615 1615 return 0;
1616 1616 }
... ... @@ -1224,6 +1224,7 @@
1224 1224 static struct vm_operations_struct ceph_vmops = {
1225 1225 .fault = filemap_fault,
1226 1226 .page_mkwrite = ceph_page_mkwrite,
  1227 + .remap_pages = generic_file_remap_pages,
1227 1228 };
1228 1229  
1229 1230 int ceph_mmap(struct file *file, struct vm_area_struct *vma)
... ... @@ -1234,7 +1235,6 @@
1234 1235 return -ENOEXEC;
1235 1236 file_accessed(file);
1236 1237 vma->vm_ops = &ceph_vmops;
1237   - vma->vm_flags |= VM_CAN_NONLINEAR;
1238 1238 return 0;
1239 1239 }
... ... @@ -3003,6 +3003,7 @@
3003 3003 static struct vm_operations_struct cifs_file_vm_ops = {
3004 3004 .fault = filemap_fault,
3005 3005 .page_mkwrite = cifs_page_mkwrite,
  3006 + .remap_pages = generic_file_remap_pages,
3006 3007 };
3007 3008  
3008 3009 int cifs_file_strict_mmap(struct file *file, struct vm_area_struct *vma)
... ... @@ -207,6 +207,7 @@
207 207 static const struct vm_operations_struct ext4_file_vm_ops = {
208 208 .fault = filemap_fault,
209 209 .page_mkwrite = ext4_page_mkwrite,
  210 + .remap_pages = generic_file_remap_pages,
210 211 };
211 212  
212 213 static int ext4_file_mmap(struct file *file, struct vm_area_struct *vma)
... ... @@ -217,7 +218,6 @@
217 218 return -ENOEXEC;
218 219 file_accessed(file);
219 220 vma->vm_ops = &ext4_file_vm_ops;
220   - vma->vm_flags |= VM_CAN_NONLINEAR;
221 221 return 0;
222 222 }
223 223  
... ... @@ -1379,6 +1379,7 @@
1379 1379 .close = fuse_vma_close,
1380 1380 .fault = filemap_fault,
1381 1381 .page_mkwrite = fuse_page_mkwrite,
  1382 + .remap_pages = generic_file_remap_pages,
1382 1383 };
1383 1384  
1384 1385 static int fuse_file_mmap(struct file *file, struct vm_area_struct *vma)
... ... @@ -492,6 +492,7 @@
492 492 static const struct vm_operations_struct gfs2_vm_ops = {
493 493 .fault = filemap_fault,
494 494 .page_mkwrite = gfs2_page_mkwrite,
  495 + .remap_pages = generic_file_remap_pages,
495 496 };
496 497  
497 498 /**
... ... @@ -526,7 +527,6 @@
526 527 return error;
527 528 }
528 529 vma->vm_ops = &gfs2_vm_ops;
529   - vma->vm_flags |= VM_CAN_NONLINEAR;
530 530  
531 531 return 0;
532 532 }
... ... @@ -578,6 +578,7 @@
578 578 static const struct vm_operations_struct nfs_file_vm_ops = {
579 579 .fault = filemap_fault,
580 580 .page_mkwrite = nfs_vm_page_mkwrite,
  581 + .remap_pages = generic_file_remap_pages,
581 582 };
582 583  
583 584 static int nfs_need_sync_write(struct file *filp, struct inode *inode)
... ... @@ -135,13 +135,13 @@
135 135 static const struct vm_operations_struct nilfs_file_vm_ops = {
136 136 .fault = filemap_fault,
137 137 .page_mkwrite = nilfs_page_mkwrite,
  138 + .remap_pages = generic_file_remap_pages,
138 139 };
139 140  
140 141 static int nilfs_file_mmap(struct file *file, struct vm_area_struct *vma)
141 142 {
142 143 file_accessed(file);
143 144 vma->vm_ops = &nilfs_file_vm_ops;
144   - vma->vm_flags |= VM_CAN_NONLINEAR;
145 145 return 0;
146 146 }
147 147  
... ... @@ -173,6 +173,7 @@
173 173 static const struct vm_operations_struct ocfs2_file_vm_ops = {
174 174 .fault = ocfs2_fault,
175 175 .page_mkwrite = ocfs2_page_mkwrite,
  176 + .remap_pages = generic_file_remap_pages,
176 177 };
177 178  
178 179 int ocfs2_mmap(struct file *file, struct vm_area_struct *vma)
... ... @@ -188,7 +189,6 @@
188 189 ocfs2_inode_unlock(file->f_dentry->d_inode, lock_level);
189 190 out:
190 191 vma->vm_ops = &ocfs2_file_vm_ops;
191   - vma->vm_flags |= VM_CAN_NONLINEAR;
192 192 return 0;
193 193 }
... ... @@ -1536,6 +1536,7 @@
1536 1536 static const struct vm_operations_struct ubifs_file_vm_ops = {
1537 1537 .fault = filemap_fault,
1538 1538 .page_mkwrite = ubifs_vm_page_mkwrite,
  1539 + .remap_pages = generic_file_remap_pages,
1539 1540 };
1540 1541  
1541 1542 static int ubifs_file_mmap(struct file *file, struct vm_area_struct *vma)
... ... @@ -940,7 +940,6 @@
940 940 struct vm_area_struct *vma)
941 941 {
942 942 vma->vm_ops = &xfs_file_vm_ops;
943   - vma->vm_flags |= VM_CAN_NONLINEAR;
944 943  
945 944 file_accessed(filp);
946 945 return 0;
... ... @@ -1443,5 +1442,6 @@
1443 1442 static const struct vm_operations_struct xfs_file_vm_ops = {
1444 1443 .fault = filemap_fault,
1445 1444 .page_mkwrite = xfs_vm_page_mkwrite,
  1445 + .remap_pages = generic_file_remap_pages,
1446 1446 };
... ... @@ -2552,6 +2552,8 @@
2552 2552  
2553 2553 extern int generic_file_mmap(struct file *, struct vm_area_struct *);
2554 2554 extern int generic_file_readonly_mmap(struct file *, struct vm_area_struct *);
  2555 +extern int generic_file_remap_pages(struct vm_area_struct *, unsigned long addr,
  2556 + unsigned long size, pgoff_t pgoff);
2555 2557 extern int file_read_actor(read_descriptor_t * desc, struct page *page, unsigned long offset, unsigned long size);
2556 2558 int generic_write_checks(struct file *file, loff_t *pos, size_t *count, int isblk);
2557 2559 extern ssize_t generic_file_aio_read(struct kiocb *, const struct iovec *, unsigned long, loff_t);
... ... @@ -105,7 +105,6 @@
105 105 #define VM_ARCH_1 0x01000000 /* Architecture-specific flag */
106 106 #define VM_NODUMP 0x04000000 /* Do not include in the core dump */
107 107  
108   -#define VM_CAN_NONLINEAR 0x08000000 /* Has ->fault & does nonlinear pages */
109 108 #define VM_MIXEDMAP 0x10000000 /* Can contain "struct page" and pure PFN pages */
110 109 #define VM_HUGEPAGE 0x20000000 /* MADV_HUGEPAGE marked this vma */
111 110 #define VM_NOHUGEPAGE 0x40000000 /* MADV_NOHUGEPAGE marked this vma */
... ... @@ -171,8 +170,7 @@
171 170 * of VM_FAULT_xxx flags that give details about how the fault was handled.
172 171 *
173 172 * pgoff should be used in favour of virtual_address, if possible. If pgoff
174   - * is used, one may set VM_CAN_NONLINEAR in the vma->vm_flags to get nonlinear
175   - * mapping support.
  173 + * is used, one may implement ->remap_pages to get nonlinear mapping support.
176 174 */
177 175 struct vm_fault {
178 176 unsigned int flags; /* FAULT_FLAG_xxx flags */
... ... @@ -230,6 +228,9 @@
230 228 int (*migrate)(struct vm_area_struct *vma, const nodemask_t *from,
231 229 const nodemask_t *to, unsigned long flags);
232 230 #endif
  231 + /* called by sys_remap_file_pages() to populate non-linear mapping */
  232 + int (*remap_pages)(struct vm_area_struct *vma, unsigned long addr,
  233 + unsigned long size, pgoff_t pgoff);
233 234 };
234 235  
235 236 struct mmu_gather;
... ... @@ -1737,6 +1737,7 @@
1737 1737 const struct vm_operations_struct generic_file_vm_ops = {
1738 1738 .fault = filemap_fault,
1739 1739 .page_mkwrite = filemap_page_mkwrite,
  1740 + .remap_pages = generic_file_remap_pages,
1740 1741 };
1741 1742  
1742 1743 /* This is used for a general mmap of a disk file */
... ... @@ -1749,7 +1750,6 @@
1749 1750 return -ENOEXEC;
1750 1751 file_accessed(file);
1751 1752 vma->vm_ops = &generic_file_vm_ops;
1752   - vma->vm_flags |= VM_CAN_NONLINEAR;
1753 1753 return 0;
1754 1754 }
1755 1755  
... ... @@ -305,6 +305,7 @@
305 305 static const struct vm_operations_struct xip_file_vm_ops = {
306 306 .fault = xip_file_fault,
307 307 .page_mkwrite = filemap_page_mkwrite,
  308 + .remap_pages = generic_file_remap_pages,
308 309 };
309 310  
310 311 int xip_file_mmap(struct file * file, struct vm_area_struct * vma)
... ... @@ -313,7 +314,7 @@
313 314  
314 315 file_accessed(file);
315 316 vma->vm_ops = &xip_file_vm_ops;
316   - vma->vm_flags |= VM_CAN_NONLINEAR | VM_MIXEDMAP;
  317 + vma->vm_flags |= VM_MIXEDMAP;
317 318 return 0;
318 319 }
319 320 EXPORT_SYMBOL_GPL(xip_file_mmap);
... ... @@ -5,6 +5,7 @@
5 5 *
6 6 * started by Ingo Molnar, Copyright (C) 2002, 2003
7 7 */
  8 +#include <linux/export.h>
8 9 #include <linux/backing-dev.h>
9 10 #include <linux/mm.h>
10 11 #include <linux/swap.h>
11 12  
... ... @@ -80,9 +81,10 @@
80 81 return err;
81 82 }
82 83  
83   -static int populate_range(struct mm_struct *mm, struct vm_area_struct *vma,
84   - unsigned long addr, unsigned long size, pgoff_t pgoff)
  84 +int generic_file_remap_pages(struct vm_area_struct *vma, unsigned long addr,
  85 + unsigned long size, pgoff_t pgoff)
85 86 {
  87 + struct mm_struct *mm = vma->vm_mm;
86 88 int err;
87 89  
88 90 do {
89 91  
... ... @@ -95,9 +97,9 @@
95 97 pgoff++;
96 98 } while (size);
97 99  
98   - return 0;
99   -
  100 + return 0;
100 101 }
  102 +EXPORT_SYMBOL(generic_file_remap_pages);
101 103  
102 104 /**
103 105 * sys_remap_file_pages - remap arbitrary pages of an existing VM_SHARED vma
... ... @@ -167,7 +169,7 @@
167 169 if (vma->vm_private_data && !(vma->vm_flags & VM_NONLINEAR))
168 170 goto out;
169 171  
170   - if (!(vma->vm_flags & VM_CAN_NONLINEAR))
  172 + if (!vma->vm_ops->remap_pages)
171 173 goto out;
172 174  
173 175 if (start < vma->vm_start || start + size > vma->vm_end)
... ... @@ -228,7 +230,7 @@
228 230 }
229 231  
230 232 mmu_notifier_invalidate_range_start(mm, start, start + size);
231   - err = populate_range(mm, vma, start, size, pgoff);
  233 + err = vma->vm_ops->remap_pages(vma, start, size, pgoff);
232 234 mmu_notifier_invalidate_range_end(mm, start, start + size);
233 235 if (!err && !(flags & MAP_NONBLOCK)) {
234 236 if (vma->vm_flags & VM_LOCKED) {
... ... @@ -669,8 +669,7 @@
669 669 static inline int is_mergeable_vma(struct vm_area_struct *vma,
670 670 struct file *file, unsigned long vm_flags)
671 671 {
672   - /* VM_CAN_NONLINEAR may get set later by f_op->mmap() */
673   - if ((vma->vm_flags ^ vm_flags) & ~VM_CAN_NONLINEAR)
  672 + if (vma->vm_flags ^ vm_flags)
674 673 return 0;
675 674 if (vma->vm_file != file)
676 675 return 0;
... ... @@ -1961,6 +1961,14 @@
1961 1961 }
1962 1962 EXPORT_SYMBOL(filemap_fault);
1963 1963  
  1964 +int generic_file_remap_pages(struct vm_area_struct *vma, unsigned long addr,
  1965 + unsigned long size, pgoff_t pgoff)
  1966 +{
  1967 + BUG();
  1968 + return 0;
  1969 +}
  1970 +EXPORT_SYMBOL(generic_file_remap_pages);
  1971 +
1964 1972 static int __access_remote_vm(struct task_struct *tsk, struct mm_struct *mm,
1965 1973 unsigned long addr, void *buf, int len, int write)
1966 1974 {
... ... @@ -1339,7 +1339,6 @@
1339 1339 {
1340 1340 file_accessed(file);
1341 1341 vma->vm_ops = &shmem_vm_ops;
1342   - vma->vm_flags |= VM_CAN_NONLINEAR;
1343 1342 return 0;
1344 1343 }
1345 1344  
... ... @@ -2643,6 +2642,7 @@
2643 2642 .set_policy = shmem_set_policy,
2644 2643 .get_policy = shmem_get_policy,
2645 2644 #endif
  2645 + .remap_pages = generic_file_remap_pages,
2646 2646 };
2647 2647  
2648 2648 static struct dentry *shmem_mount(struct file_system_type *fs_type,
... ... @@ -2836,7 +2836,6 @@
2836 2836 fput(vma->vm_file);
2837 2837 vma->vm_file = file;
2838 2838 vma->vm_ops = &shmem_vm_ops;
2839   - vma->vm_flags |= VM_CAN_NONLINEAR;
2840 2839 return 0;
2841 2840 }
2842 2841