Skip to content

Commit 0b173bc

Browse files
koct9itorvalds
authored andcommitted
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>
1 parent 4b6e1e3 commit 0b173bc

File tree

21 files changed

+39
-23
lines changed

21 files changed

+39
-23
lines changed

drivers/staging/android/ashmem.c

-1
Original file line numberDiff line numberDiff line change
@@ -332,7 +332,6 @@ static int ashmem_mmap(struct file *file, struct vm_area_struct *vma)
332332
if (vma->vm_file)
333333
fput(vma->vm_file);
334334
vma->vm_file = asma->file;
335-
vma->vm_flags |= VM_CAN_NONLINEAR;
336335

337336
out:
338337
mutex_unlock(&ashmem_mutex);

fs/9p/vfs_file.c

+1
Original file line numberDiff line numberDiff line change
@@ -738,6 +738,7 @@ v9fs_cached_file_write(struct file *filp, const char __user * data,
738738
static const struct vm_operations_struct v9fs_file_vm_ops = {
739739
.fault = filemap_fault,
740740
.page_mkwrite = v9fs_vm_page_mkwrite,
741+
.remap_pages = generic_file_remap_pages,
741742
};
742743

743744

fs/btrfs/file.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -1599,6 +1599,7 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
15991599
static const struct vm_operations_struct btrfs_file_vm_ops = {
16001600
.fault = filemap_fault,
16011601
.page_mkwrite = btrfs_page_mkwrite,
1602+
.remap_pages = generic_file_remap_pages,
16021603
};
16031604

16041605
static int btrfs_file_mmap(struct file *filp, struct vm_area_struct *vma)
@@ -1610,7 +1611,6 @@ static int btrfs_file_mmap(struct file *filp, struct vm_area_struct *vma)
16101611

16111612
file_accessed(filp);
16121613
vma->vm_ops = &btrfs_file_vm_ops;
1613-
vma->vm_flags |= VM_CAN_NONLINEAR;
16141614

16151615
return 0;
16161616
}

fs/ceph/addr.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -1224,6 +1224,7 @@ static int ceph_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
12241224
static struct vm_operations_struct ceph_vmops = {
12251225
.fault = filemap_fault,
12261226
.page_mkwrite = ceph_page_mkwrite,
1227+
.remap_pages = generic_file_remap_pages,
12271228
};
12281229

12291230
int ceph_mmap(struct file *file, struct vm_area_struct *vma)
@@ -1234,6 +1235,5 @@ int ceph_mmap(struct file *file, struct vm_area_struct *vma)
12341235
return -ENOEXEC;
12351236
file_accessed(file);
12361237
vma->vm_ops = &ceph_vmops;
1237-
vma->vm_flags |= VM_CAN_NONLINEAR;
12381238
return 0;
12391239
}

fs/cifs/file.c

+1
Original file line numberDiff line numberDiff line change
@@ -3003,6 +3003,7 @@ cifs_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
30033003
static struct vm_operations_struct cifs_file_vm_ops = {
30043004
.fault = filemap_fault,
30053005
.page_mkwrite = cifs_page_mkwrite,
3006+
.remap_pages = generic_file_remap_pages,
30063007
};
30073008

30083009
int cifs_file_strict_mmap(struct file *file, struct vm_area_struct *vma)

fs/ext4/file.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,7 @@ ext4_file_write(struct kiocb *iocb, const struct iovec *iov,
207207
static const struct vm_operations_struct ext4_file_vm_ops = {
208208
.fault = filemap_fault,
209209
.page_mkwrite = ext4_page_mkwrite,
210+
.remap_pages = generic_file_remap_pages,
210211
};
211212

212213
static int ext4_file_mmap(struct file *file, struct vm_area_struct *vma)
@@ -217,7 +218,6 @@ static int ext4_file_mmap(struct file *file, struct vm_area_struct *vma)
217218
return -ENOEXEC;
218219
file_accessed(file);
219220
vma->vm_ops = &ext4_file_vm_ops;
220-
vma->vm_flags |= VM_CAN_NONLINEAR;
221221
return 0;
222222
}
223223

fs/fuse/file.c

+1
Original file line numberDiff line numberDiff line change
@@ -1379,6 +1379,7 @@ static const struct vm_operations_struct fuse_file_vm_ops = {
13791379
.close = fuse_vma_close,
13801380
.fault = filemap_fault,
13811381
.page_mkwrite = fuse_page_mkwrite,
1382+
.remap_pages = generic_file_remap_pages,
13821383
};
13831384

13841385
static int fuse_file_mmap(struct file *file, struct vm_area_struct *vma)

fs/gfs2/file.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -492,6 +492,7 @@ static int gfs2_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
492492
static const struct vm_operations_struct gfs2_vm_ops = {
493493
.fault = filemap_fault,
494494
.page_mkwrite = gfs2_page_mkwrite,
495+
.remap_pages = generic_file_remap_pages,
495496
};
496497

497498
/**
@@ -526,7 +527,6 @@ static int gfs2_mmap(struct file *file, struct vm_area_struct *vma)
526527
return error;
527528
}
528529
vma->vm_ops = &gfs2_vm_ops;
529-
vma->vm_flags |= VM_CAN_NONLINEAR;
530530

531531
return 0;
532532
}

fs/nfs/file.c

+1
Original file line numberDiff line numberDiff line change
@@ -578,6 +578,7 @@ static int nfs_vm_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
578578
static const struct vm_operations_struct nfs_file_vm_ops = {
579579
.fault = filemap_fault,
580580
.page_mkwrite = nfs_vm_page_mkwrite,
581+
.remap_pages = generic_file_remap_pages,
581582
};
582583

583584
static int nfs_need_sync_write(struct file *filp, struct inode *inode)

fs/nilfs2/file.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -135,13 +135,13 @@ static int nilfs_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
135135
static const struct vm_operations_struct nilfs_file_vm_ops = {
136136
.fault = filemap_fault,
137137
.page_mkwrite = nilfs_page_mkwrite,
138+
.remap_pages = generic_file_remap_pages,
138139
};
139140

140141
static int nilfs_file_mmap(struct file *file, struct vm_area_struct *vma)
141142
{
142143
file_accessed(file);
143144
vma->vm_ops = &nilfs_file_vm_ops;
144-
vma->vm_flags |= VM_CAN_NONLINEAR;
145145
return 0;
146146
}
147147

fs/ocfs2/mmap.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,7 @@ static int ocfs2_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
173173
static const struct vm_operations_struct ocfs2_file_vm_ops = {
174174
.fault = ocfs2_fault,
175175
.page_mkwrite = ocfs2_page_mkwrite,
176+
.remap_pages = generic_file_remap_pages,
176177
};
177178

178179
int ocfs2_mmap(struct file *file, struct vm_area_struct *vma)
@@ -188,7 +189,6 @@ int ocfs2_mmap(struct file *file, struct vm_area_struct *vma)
188189
ocfs2_inode_unlock(file->f_dentry->d_inode, lock_level);
189190
out:
190191
vma->vm_ops = &ocfs2_file_vm_ops;
191-
vma->vm_flags |= VM_CAN_NONLINEAR;
192192
return 0;
193193
}
194194

fs/ubifs/file.c

+1
Original file line numberDiff line numberDiff line change
@@ -1536,6 +1536,7 @@ static int ubifs_vm_page_mkwrite(struct vm_area_struct *vma,
15361536
static const struct vm_operations_struct ubifs_file_vm_ops = {
15371537
.fault = filemap_fault,
15381538
.page_mkwrite = ubifs_vm_page_mkwrite,
1539+
.remap_pages = generic_file_remap_pages,
15391540
};
15401541

15411542
static int ubifs_file_mmap(struct file *file, struct vm_area_struct *vma)

fs/xfs/xfs_file.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -940,7 +940,6 @@ xfs_file_mmap(
940940
struct vm_area_struct *vma)
941941
{
942942
vma->vm_ops = &xfs_file_vm_ops;
943-
vma->vm_flags |= VM_CAN_NONLINEAR;
944943

945944
file_accessed(filp);
946945
return 0;
@@ -1443,4 +1442,5 @@ const struct file_operations xfs_dir_file_operations = {
14431442
static const struct vm_operations_struct xfs_file_vm_ops = {
14441443
.fault = filemap_fault,
14451444
.page_mkwrite = xfs_vm_page_mkwrite,
1445+
.remap_pages = generic_file_remap_pages,
14461446
};

include/linux/fs.h

+2
Original file line numberDiff line numberDiff line change
@@ -2552,6 +2552,8 @@ extern int sb_min_blocksize(struct super_block *, int);
25522552

25532553
extern int generic_file_mmap(struct file *, struct vm_area_struct *);
25542554
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);
25552557
extern int file_read_actor(read_descriptor_t * desc, struct page *page, unsigned long offset, unsigned long size);
25562558
int generic_write_checks(struct file *file, loff_t *pos, size_t *count, int isblk);
25572559
extern ssize_t generic_file_aio_read(struct kiocb *, const struct iovec *, unsigned long, loff_t);

include/linux/mm.h

+4-3
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,6 @@ extern unsigned int kobjsize(const void *objp);
105105
#define VM_ARCH_1 0x01000000 /* Architecture-specific flag */
106106
#define VM_NODUMP 0x04000000 /* Do not include in the core dump */
107107

108-
#define VM_CAN_NONLINEAR 0x08000000 /* Has ->fault & does nonlinear pages */
109108
#define VM_MIXEDMAP 0x10000000 /* Can contain "struct page" and pure PFN pages */
110109
#define VM_HUGEPAGE 0x20000000 /* MADV_HUGEPAGE marked this vma */
111110
#define VM_NOHUGEPAGE 0x40000000 /* MADV_NOHUGEPAGE marked this vma */
@@ -171,8 +170,7 @@ extern pgprot_t protection_map[16];
171170
* of VM_FAULT_xxx flags that give details about how the fault was handled.
172171
*
173172
* 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.
176174
*/
177175
struct vm_fault {
178176
unsigned int flags; /* FAULT_FLAG_xxx flags */
@@ -230,6 +228,9 @@ struct vm_operations_struct {
230228
int (*migrate)(struct vm_area_struct *vma, const nodemask_t *from,
231229
const nodemask_t *to, unsigned long flags);
232230
#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);
233234
};
234235

235236
struct mmu_gather;

mm/filemap.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -1737,6 +1737,7 @@ EXPORT_SYMBOL(filemap_page_mkwrite);
17371737
const struct vm_operations_struct generic_file_vm_ops = {
17381738
.fault = filemap_fault,
17391739
.page_mkwrite = filemap_page_mkwrite,
1740+
.remap_pages = generic_file_remap_pages,
17401741
};
17411742

17421743
/* This is used for a general mmap of a disk file */
@@ -1749,7 +1750,6 @@ int generic_file_mmap(struct file * file, struct vm_area_struct * vma)
17491750
return -ENOEXEC;
17501751
file_accessed(file);
17511752
vma->vm_ops = &generic_file_vm_ops;
1752-
vma->vm_flags |= VM_CAN_NONLINEAR;
17531753
return 0;
17541754
}
17551755

mm/filemap_xip.c

+2-1
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,7 @@ static int xip_file_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
305305
static const struct vm_operations_struct xip_file_vm_ops = {
306306
.fault = xip_file_fault,
307307
.page_mkwrite = filemap_page_mkwrite,
308+
.remap_pages = generic_file_remap_pages,
308309
};
309310

310311
int xip_file_mmap(struct file * file, struct vm_area_struct * vma)
@@ -313,7 +314,7 @@ int xip_file_mmap(struct file * file, struct vm_area_struct * vma)
313314

314315
file_accessed(file);
315316
vma->vm_ops = &xip_file_vm_ops;
316-
vma->vm_flags |= VM_CAN_NONLINEAR | VM_MIXEDMAP;
317+
vma->vm_flags |= VM_MIXEDMAP;
317318
return 0;
318319
}
319320
EXPORT_SYMBOL_GPL(xip_file_mmap);

mm/fremap.c

+8-6
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
*
66
* started by Ingo Molnar, Copyright (C) 2002, 2003
77
*/
8+
#include <linux/export.h>
89
#include <linux/backing-dev.h>
910
#include <linux/mm.h>
1011
#include <linux/swap.h>
@@ -80,9 +81,10 @@ static int install_file_pte(struct mm_struct *mm, struct vm_area_struct *vma,
8081
return err;
8182
}
8283

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)
8586
{
87+
struct mm_struct *mm = vma->vm_mm;
8688
int err;
8789

8890
do {
@@ -95,9 +97,9 @@ static int populate_range(struct mm_struct *mm, struct vm_area_struct *vma,
9597
pgoff++;
9698
} while (size);
9799

98-
return 0;
99-
100+
return 0;
100101
}
102+
EXPORT_SYMBOL(generic_file_remap_pages);
101103

102104
/**
103105
* sys_remap_file_pages - remap arbitrary pages of an existing VM_SHARED vma
@@ -167,7 +169,7 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size,
167169
if (vma->vm_private_data && !(vma->vm_flags & VM_NONLINEAR))
168170
goto out;
169171

170-
if (!(vma->vm_flags & VM_CAN_NONLINEAR))
172+
if (!vma->vm_ops->remap_pages)
171173
goto out;
172174

173175
if (start < vma->vm_start || start + size > vma->vm_end)
@@ -228,7 +230,7 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size,
228230
}
229231

230232
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);
232234
mmu_notifier_invalidate_range_end(mm, start, start + size);
233235
if (!err && !(flags & MAP_NONBLOCK)) {
234236
if (vma->vm_flags & VM_LOCKED) {

mm/mmap.c

+1-2
Original file line numberDiff line numberDiff line change
@@ -669,8 +669,7 @@ again: remove_next = 1 + (end > next->vm_end);
669669
static inline int is_mergeable_vma(struct vm_area_struct *vma,
670670
struct file *file, unsigned long vm_flags)
671671
{
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)
674673
return 0;
675674
if (vma->vm_file != file)
676675
return 0;

mm/nommu.c

+8
Original file line numberDiff line numberDiff line change
@@ -1961,6 +1961,14 @@ int filemap_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
19611961
}
19621962
EXPORT_SYMBOL(filemap_fault);
19631963

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+
19641972
static int __access_remote_vm(struct task_struct *tsk, struct mm_struct *mm,
19651973
unsigned long addr, void *buf, int len, int write)
19661974
{

mm/shmem.c

+1-2
Original file line numberDiff line numberDiff line change
@@ -1339,7 +1339,6 @@ static int shmem_mmap(struct file *file, struct vm_area_struct *vma)
13391339
{
13401340
file_accessed(file);
13411341
vma->vm_ops = &shmem_vm_ops;
1342-
vma->vm_flags |= VM_CAN_NONLINEAR;
13431342
return 0;
13441343
}
13451344

@@ -2643,6 +2642,7 @@ static const struct vm_operations_struct shmem_vm_ops = {
26432642
.set_policy = shmem_set_policy,
26442643
.get_policy = shmem_get_policy,
26452644
#endif
2645+
.remap_pages = generic_file_remap_pages,
26462646
};
26472647

26482648
static struct dentry *shmem_mount(struct file_system_type *fs_type,
@@ -2836,7 +2836,6 @@ int shmem_zero_setup(struct vm_area_struct *vma)
28362836
fput(vma->vm_file);
28372837
vma->vm_file = file;
28382838
vma->vm_ops = &shmem_vm_ops;
2839-
vma->vm_flags |= VM_CAN_NONLINEAR;
28402839
return 0;
28412840
}
28422841

0 commit comments

Comments
 (0)