diff options
author | Christoph Hellwig <hch@lst.de> | 2015-01-14 04:42:32 -0500 |
---|---|---|
committer | Jens Axboe <axboe@fb.com> | 2015-01-20 16:02:58 -0500 |
commit | b4caecd48005fbed3949dde6c1cb233142fd69e9 (patch) | |
tree | 1fdd9b7c15568c79eb3c1ed84a39858ddbcbc88b /drivers/char/mem.c | |
parent | 97b713ba3ebaa6c8d84c2c720f5468a7c6a6eb4e (diff) |
fs: introduce f_op->mmap_capabilities for nommu mmap support
Since "BDI: Provide backing device capability information [try #3]" the
backing_dev_info structure also provides flags for the kind of mmap
operation available in a nommu environment, which is entirely unrelated
to it's original purpose.
Introduce a new nommu-only file operation to provide this information to
the nommu mmap code instead. Splitting this from the backing_dev_info
structure allows to remove lots of backing_dev_info instance that aren't
otherwise needed, and entirely gets rid of the concept of providing a
backing_dev_info for a character device. It also removes the need for
the mtd_inodefs filesystem.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Tejun Heo <tj@kernel.org>
Acked-by: Brian Norris <computersforpeace@gmail.com>
Signed-off-by: Jens Axboe <axboe@fb.com>
Diffstat (limited to 'drivers/char/mem.c')
-rw-r--r-- | drivers/char/mem.c | 64 |
1 files changed, 32 insertions, 32 deletions
diff --git a/drivers/char/mem.c b/drivers/char/mem.c index 4c58333b4257..9a6b63783a94 100644 --- a/drivers/char/mem.c +++ b/drivers/char/mem.c | |||
@@ -287,13 +287,24 @@ static unsigned long get_unmapped_area_mem(struct file *file, | |||
287 | return pgoff << PAGE_SHIFT; | 287 | return pgoff << PAGE_SHIFT; |
288 | } | 288 | } |
289 | 289 | ||
290 | /* permit direct mmap, for read, write or exec */ | ||
291 | static unsigned memory_mmap_capabilities(struct file *file) | ||
292 | { | ||
293 | return NOMMU_MAP_DIRECT | | ||
294 | NOMMU_MAP_READ | NOMMU_MAP_WRITE | NOMMU_MAP_EXEC; | ||
295 | } | ||
296 | |||
297 | static unsigned zero_mmap_capabilities(struct file *file) | ||
298 | { | ||
299 | return NOMMU_MAP_COPY; | ||
300 | } | ||
301 | |||
290 | /* can't do an in-place private mapping if there's no MMU */ | 302 | /* can't do an in-place private mapping if there's no MMU */ |
291 | static inline int private_mapping_ok(struct vm_area_struct *vma) | 303 | static inline int private_mapping_ok(struct vm_area_struct *vma) |
292 | { | 304 | { |
293 | return vma->vm_flags & VM_MAYSHARE; | 305 | return vma->vm_flags & VM_MAYSHARE; |
294 | } | 306 | } |
295 | #else | 307 | #else |
296 | #define get_unmapped_area_mem NULL | ||
297 | 308 | ||
298 | static inline int private_mapping_ok(struct vm_area_struct *vma) | 309 | static inline int private_mapping_ok(struct vm_area_struct *vma) |
299 | { | 310 | { |
@@ -721,7 +732,10 @@ static const struct file_operations mem_fops = { | |||
721 | .write = write_mem, | 732 | .write = write_mem, |
722 | .mmap = mmap_mem, | 733 | .mmap = mmap_mem, |
723 | .open = open_mem, | 734 | .open = open_mem, |
735 | #ifndef CONFIG_MMU | ||
724 | .get_unmapped_area = get_unmapped_area_mem, | 736 | .get_unmapped_area = get_unmapped_area_mem, |
737 | .mmap_capabilities = memory_mmap_capabilities, | ||
738 | #endif | ||
725 | }; | 739 | }; |
726 | 740 | ||
727 | #ifdef CONFIG_DEVKMEM | 741 | #ifdef CONFIG_DEVKMEM |
@@ -731,7 +745,10 @@ static const struct file_operations kmem_fops = { | |||
731 | .write = write_kmem, | 745 | .write = write_kmem, |
732 | .mmap = mmap_kmem, | 746 | .mmap = mmap_kmem, |
733 | .open = open_kmem, | 747 | .open = open_kmem, |
748 | #ifndef CONFIG_MMU | ||
734 | .get_unmapped_area = get_unmapped_area_mem, | 749 | .get_unmapped_area = get_unmapped_area_mem, |
750 | .mmap_capabilities = memory_mmap_capabilities, | ||
751 | #endif | ||
735 | }; | 752 | }; |
736 | #endif | 753 | #endif |
737 | 754 | ||
@@ -760,16 +777,9 @@ static const struct file_operations zero_fops = { | |||
760 | .read_iter = read_iter_zero, | 777 | .read_iter = read_iter_zero, |
761 | .aio_write = aio_write_zero, | 778 | .aio_write = aio_write_zero, |
762 | .mmap = mmap_zero, | 779 | .mmap = mmap_zero, |
763 | }; | 780 | #ifndef CONFIG_MMU |
764 | 781 | .mmap_capabilities = zero_mmap_capabilities, | |
765 | /* | 782 | #endif |
766 | * capabilities for /dev/zero | ||
767 | * - permits private mappings, "copies" are taken of the source of zeros | ||
768 | * - no writeback happens | ||
769 | */ | ||
770 | static struct backing_dev_info zero_bdi = { | ||
771 | .name = "char/mem", | ||
772 | .capabilities = BDI_CAP_MAP_COPY | BDI_CAP_NO_ACCT_AND_WRITEBACK, | ||
773 | }; | 783 | }; |
774 | 784 | ||
775 | static const struct file_operations full_fops = { | 785 | static const struct file_operations full_fops = { |
@@ -783,22 +793,22 @@ static const struct memdev { | |||
783 | const char *name; | 793 | const char *name; |
784 | umode_t mode; | 794 | umode_t mode; |
785 | const struct file_operations *fops; | 795 | const struct file_operations *fops; |
786 | struct backing_dev_info *dev_info; | 796 | fmode_t fmode; |
787 | } devlist[] = { | 797 | } devlist[] = { |
788 | [1] = { "mem", 0, &mem_fops, &directly_mappable_cdev_bdi }, | 798 | [1] = { "mem", 0, &mem_fops, FMODE_UNSIGNED_OFFSET }, |
789 | #ifdef CONFIG_DEVKMEM | 799 | #ifdef CONFIG_DEVKMEM |
790 | [2] = { "kmem", 0, &kmem_fops, &directly_mappable_cdev_bdi }, | 800 | [2] = { "kmem", 0, &kmem_fops, FMODE_UNSIGNED_OFFSET }, |
791 | #endif | 801 | #endif |
792 | [3] = { "null", 0666, &null_fops, NULL }, | 802 | [3] = { "null", 0666, &null_fops, 0 }, |
793 | #ifdef CONFIG_DEVPORT | 803 | #ifdef CONFIG_DEVPORT |
794 | [4] = { "port", 0, &port_fops, NULL }, | 804 | [4] = { "port", 0, &port_fops, 0 }, |
795 | #endif | 805 | #endif |
796 | [5] = { "zero", 0666, &zero_fops, &zero_bdi }, | 806 | [5] = { "zero", 0666, &zero_fops, 0 }, |
797 | [7] = { "full", 0666, &full_fops, NULL }, | 807 | [7] = { "full", 0666, &full_fops, 0 }, |
798 | [8] = { "random", 0666, &random_fops, NULL }, | 808 | [8] = { "random", 0666, &random_fops, 0 }, |
799 | [9] = { "urandom", 0666, &urandom_fops, NULL }, | 809 | [9] = { "urandom", 0666, &urandom_fops, 0 }, |
800 | #ifdef CONFIG_PRINTK | 810 | #ifdef CONFIG_PRINTK |
801 | [11] = { "kmsg", 0644, &kmsg_fops, NULL }, | 811 | [11] = { "kmsg", 0644, &kmsg_fops, 0 }, |
802 | #endif | 812 | #endif |
803 | }; | 813 | }; |
804 | 814 | ||
@@ -816,12 +826,7 @@ static int memory_open(struct inode *inode, struct file *filp) | |||
816 | return -ENXIO; | 826 | return -ENXIO; |
817 | 827 | ||
818 | filp->f_op = dev->fops; | 828 | filp->f_op = dev->fops; |
819 | if (dev->dev_info) | 829 | filp->f_mode |= dev->fmode; |
820 | filp->f_mapping->backing_dev_info = dev->dev_info; | ||
821 | |||
822 | /* Is /dev/mem or /dev/kmem ? */ | ||
823 | if (dev->dev_info == &directly_mappable_cdev_bdi) | ||
824 | filp->f_mode |= FMODE_UNSIGNED_OFFSET; | ||
825 | 830 | ||
826 | if (dev->fops->open) | 831 | if (dev->fops->open) |
827 | return dev->fops->open(inode, filp); | 832 | return dev->fops->open(inode, filp); |
@@ -846,11 +851,6 @@ static struct class *mem_class; | |||
846 | static int __init chr_dev_init(void) | 851 | static int __init chr_dev_init(void) |
847 | { | 852 | { |
848 | int minor; | 853 | int minor; |
849 | int err; | ||
850 | |||
851 | err = bdi_init(&zero_bdi); | ||
852 | if (err) | ||
853 | return err; | ||
854 | 854 | ||
855 | if (register_chrdev(MEM_MAJOR, "mem", &memory_fops)) | 855 | if (register_chrdev(MEM_MAJOR, "mem", &memory_fops)) |
856 | printk("unable to get major %d for memory devs\n", MEM_MAJOR); | 856 | printk("unable to get major %d for memory devs\n", MEM_MAJOR); |