diff options
author | David Howells <dhowells@redhat.com> | 2006-09-27 04:50:16 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-09-27 11:26:14 -0400 |
commit | 5da6185bca064e35aa73a7c1f27488d2b96434f4 (patch) | |
tree | b854ad2105e177d4b4ec4bb6a5ac26d41ebe368f /drivers/char/mem.c | |
parent | 0ec76a110f432e98277e464b82ace8dd66571689 (diff) |
[PATCH] NOMMU: Set BDI capabilities for /dev/mem and /dev/kmem
Set the backing device info capabilities for /dev/mem and /dev/kmem to
permit direct sharing under no-MMU conditions and full mapping capabilities
under MMU conditions. Make the BDI used by these available to all directly
mappable character devices.
Also comment the capabilities for /dev/zero.
[akpm@osdl.org: ifdef reductions]
Signed-off-by: David Howells <dhowells@redhat.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/char/mem.c')
-rw-r--r-- | drivers/char/mem.c | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/drivers/char/mem.c b/drivers/char/mem.c index 917b20402664..4ac70ec697f0 100644 --- a/drivers/char/mem.c +++ b/drivers/char/mem.c | |||
@@ -238,6 +238,32 @@ static pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn, | |||
238 | } | 238 | } |
239 | #endif | 239 | #endif |
240 | 240 | ||
241 | #ifndef CONFIG_MMU | ||
242 | static unsigned long get_unmapped_area_mem(struct file *file, | ||
243 | unsigned long addr, | ||
244 | unsigned long len, | ||
245 | unsigned long pgoff, | ||
246 | unsigned long flags) | ||
247 | { | ||
248 | if (!valid_mmap_phys_addr_range(pgoff, len)) | ||
249 | return (unsigned long) -EINVAL; | ||
250 | return pgoff; | ||
251 | } | ||
252 | |||
253 | /* can't do an in-place private mapping if there's no MMU */ | ||
254 | static inline int private_mapping_ok(struct vm_area_struct *vma) | ||
255 | { | ||
256 | return vma->vm_flags & VM_MAYSHARE; | ||
257 | } | ||
258 | #else | ||
259 | #define get_unmapped_area_mem NULL | ||
260 | |||
261 | static inline int private_mapping_ok(struct vm_area_struct *vma) | ||
262 | { | ||
263 | return 1; | ||
264 | } | ||
265 | #endif | ||
266 | |||
241 | static int mmap_mem(struct file * file, struct vm_area_struct * vma) | 267 | static int mmap_mem(struct file * file, struct vm_area_struct * vma) |
242 | { | 268 | { |
243 | size_t size = vma->vm_end - vma->vm_start; | 269 | size_t size = vma->vm_end - vma->vm_start; |
@@ -245,6 +271,9 @@ static int mmap_mem(struct file * file, struct vm_area_struct * vma) | |||
245 | if (!valid_mmap_phys_addr_range(vma->vm_pgoff, size)) | 271 | if (!valid_mmap_phys_addr_range(vma->vm_pgoff, size)) |
246 | return -EINVAL; | 272 | return -EINVAL; |
247 | 273 | ||
274 | if (!private_mapping_ok(vma)) | ||
275 | return -ENOSYS; | ||
276 | |||
248 | vma->vm_page_prot = phys_mem_access_prot(file, vma->vm_pgoff, | 277 | vma->vm_page_prot = phys_mem_access_prot(file, vma->vm_pgoff, |
249 | size, | 278 | size, |
250 | vma->vm_page_prot); | 279 | vma->vm_page_prot); |
@@ -782,6 +811,7 @@ static const struct file_operations mem_fops = { | |||
782 | .write = write_mem, | 811 | .write = write_mem, |
783 | .mmap = mmap_mem, | 812 | .mmap = mmap_mem, |
784 | .open = open_mem, | 813 | .open = open_mem, |
814 | .get_unmapped_area = get_unmapped_area_mem, | ||
785 | }; | 815 | }; |
786 | 816 | ||
787 | static const struct file_operations kmem_fops = { | 817 | static const struct file_operations kmem_fops = { |
@@ -790,6 +820,7 @@ static const struct file_operations kmem_fops = { | |||
790 | .write = write_kmem, | 820 | .write = write_kmem, |
791 | .mmap = mmap_kmem, | 821 | .mmap = mmap_kmem, |
792 | .open = open_kmem, | 822 | .open = open_kmem, |
823 | .get_unmapped_area = get_unmapped_area_mem, | ||
793 | }; | 824 | }; |
794 | 825 | ||
795 | static const struct file_operations null_fops = { | 826 | static const struct file_operations null_fops = { |
@@ -815,6 +846,10 @@ static const struct file_operations zero_fops = { | |||
815 | .mmap = mmap_zero, | 846 | .mmap = mmap_zero, |
816 | }; | 847 | }; |
817 | 848 | ||
849 | /* | ||
850 | * capabilities for /dev/zero | ||
851 | * - permits private mappings, "copies" are taken of the source of zeros | ||
852 | */ | ||
818 | static struct backing_dev_info zero_bdi = { | 853 | static struct backing_dev_info zero_bdi = { |
819 | .capabilities = BDI_CAP_MAP_COPY, | 854 | .capabilities = BDI_CAP_MAP_COPY, |
820 | }; | 855 | }; |
@@ -862,9 +897,13 @@ static int memory_open(struct inode * inode, struct file * filp) | |||
862 | switch (iminor(inode)) { | 897 | switch (iminor(inode)) { |
863 | case 1: | 898 | case 1: |
864 | filp->f_op = &mem_fops; | 899 | filp->f_op = &mem_fops; |
900 | filp->f_mapping->backing_dev_info = | ||
901 | &directly_mappable_cdev_bdi; | ||
865 | break; | 902 | break; |
866 | case 2: | 903 | case 2: |
867 | filp->f_op = &kmem_fops; | 904 | filp->f_op = &kmem_fops; |
905 | filp->f_mapping->backing_dev_info = | ||
906 | &directly_mappable_cdev_bdi; | ||
868 | break; | 907 | break; |
869 | case 3: | 908 | case 3: |
870 | filp->f_op = &null_fops; | 909 | filp->f_op = &null_fops; |