aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2015-01-14 04:42:32 -0500
committerJens Axboe <axboe@fb.com>2015-01-20 16:02:58 -0500
commitb4caecd48005fbed3949dde6c1cb233142fd69e9 (patch)
tree1fdd9b7c15568c79eb3c1ed84a39858ddbcbc88b /mm
parent97b713ba3ebaa6c8d84c2c720f5468a7c6a6eb4e (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 'mm')
-rw-r--r--mm/backing-dev.c7
-rw-r--r--mm/nommu.c69
2 files changed, 32 insertions, 44 deletions
diff --git a/mm/backing-dev.c b/mm/backing-dev.c
index 0ae0df55000b..16c68958aeda 100644
--- a/mm/backing-dev.c
+++ b/mm/backing-dev.c
@@ -17,8 +17,6 @@ static atomic_long_t bdi_seq = ATOMIC_LONG_INIT(0);
17struct backing_dev_info default_backing_dev_info = { 17struct backing_dev_info default_backing_dev_info = {
18 .name = "default", 18 .name = "default",
19 .ra_pages = VM_MAX_READAHEAD * 1024 / PAGE_CACHE_SIZE, 19 .ra_pages = VM_MAX_READAHEAD * 1024 / PAGE_CACHE_SIZE,
20 .state = 0,
21 .capabilities = BDI_CAP_MAP_COPY,
22}; 20};
23EXPORT_SYMBOL_GPL(default_backing_dev_info); 21EXPORT_SYMBOL_GPL(default_backing_dev_info);
24 22
@@ -513,13 +511,12 @@ EXPORT_SYMBOL(bdi_destroy);
513 * For use from filesystems to quickly init and register a bdi associated 511 * For use from filesystems to quickly init and register a bdi associated
514 * with dirty writeback 512 * with dirty writeback
515 */ 513 */
516int bdi_setup_and_register(struct backing_dev_info *bdi, char *name, 514int bdi_setup_and_register(struct backing_dev_info *bdi, char *name)
517 unsigned int cap)
518{ 515{
519 int err; 516 int err;
520 517
521 bdi->name = name; 518 bdi->name = name;
522 bdi->capabilities = cap; 519 bdi->capabilities = 0;
523 err = bdi_init(bdi); 520 err = bdi_init(bdi);
524 if (err) 521 if (err)
525 return err; 522 return err;
diff --git a/mm/nommu.c b/mm/nommu.c
index b51eadf6d952..13af96f35a4b 100644
--- a/mm/nommu.c
+++ b/mm/nommu.c
@@ -946,9 +946,6 @@ static int validate_mmap_request(struct file *file,
946 return -EOVERFLOW; 946 return -EOVERFLOW;
947 947
948 if (file) { 948 if (file) {
949 /* validate file mapping requests */
950 struct address_space *mapping;
951
952 /* files must support mmap */ 949 /* files must support mmap */
953 if (!file->f_op->mmap) 950 if (!file->f_op->mmap)
954 return -ENODEV; 951 return -ENODEV;
@@ -957,28 +954,22 @@ static int validate_mmap_request(struct file *file,
957 * - we support chardevs that provide their own "memory" 954 * - we support chardevs that provide their own "memory"
958 * - we support files/blockdevs that are memory backed 955 * - we support files/blockdevs that are memory backed
959 */ 956 */
960 mapping = file->f_mapping; 957 if (file->f_op->mmap_capabilities) {
961 if (!mapping) 958 capabilities = file->f_op->mmap_capabilities(file);
962 mapping = file_inode(file)->i_mapping; 959 } else {
963
964 capabilities = 0;
965 if (mapping && mapping->backing_dev_info)
966 capabilities = mapping->backing_dev_info->capabilities;
967
968 if (!capabilities) {
969 /* no explicit capabilities set, so assume some 960 /* no explicit capabilities set, so assume some
970 * defaults */ 961 * defaults */
971 switch (file_inode(file)->i_mode & S_IFMT) { 962 switch (file_inode(file)->i_mode & S_IFMT) {
972 case S_IFREG: 963 case S_IFREG:
973 case S_IFBLK: 964 case S_IFBLK:
974 capabilities = BDI_CAP_MAP_COPY; 965 capabilities = NOMMU_MAP_COPY;
975 break; 966 break;
976 967
977 case S_IFCHR: 968 case S_IFCHR:
978 capabilities = 969 capabilities =
979 BDI_CAP_MAP_DIRECT | 970 NOMMU_MAP_DIRECT |
980 BDI_CAP_READ_MAP | 971 NOMMU_MAP_READ |
981 BDI_CAP_WRITE_MAP; 972 NOMMU_MAP_WRITE;
982 break; 973 break;
983 974
984 default: 975 default:
@@ -989,9 +980,9 @@ static int validate_mmap_request(struct file *file,
989 /* eliminate any capabilities that we can't support on this 980 /* eliminate any capabilities that we can't support on this
990 * device */ 981 * device */
991 if (!file->f_op->get_unmapped_area) 982 if (!file->f_op->get_unmapped_area)
992 capabilities &= ~BDI_CAP_MAP_DIRECT; 983 capabilities &= ~NOMMU_MAP_DIRECT;
993 if (!file->f_op->read) 984 if (!file->f_op->read)
994 capabilities &= ~BDI_CAP_MAP_COPY; 985 capabilities &= ~NOMMU_MAP_COPY;
995 986
996 /* The file shall have been opened with read permission. */ 987 /* The file shall have been opened with read permission. */
997 if (!(file->f_mode & FMODE_READ)) 988 if (!(file->f_mode & FMODE_READ))
@@ -1010,29 +1001,29 @@ static int validate_mmap_request(struct file *file,
1010 if (locks_verify_locked(file)) 1001 if (locks_verify_locked(file))
1011 return -EAGAIN; 1002 return -EAGAIN;
1012 1003
1013 if (!(capabilities & BDI_CAP_MAP_DIRECT)) 1004 if (!(capabilities & NOMMU_MAP_DIRECT))
1014 return -ENODEV; 1005 return -ENODEV;
1015 1006
1016 /* we mustn't privatise shared mappings */ 1007 /* we mustn't privatise shared mappings */
1017 capabilities &= ~BDI_CAP_MAP_COPY; 1008 capabilities &= ~NOMMU_MAP_COPY;
1018 } else { 1009 } else {
1019 /* we're going to read the file into private memory we 1010 /* we're going to read the file into private memory we
1020 * allocate */ 1011 * allocate */
1021 if (!(capabilities & BDI_CAP_MAP_COPY)) 1012 if (!(capabilities & NOMMU_MAP_COPY))
1022 return -ENODEV; 1013 return -ENODEV;
1023 1014
1024 /* we don't permit a private writable mapping to be 1015 /* we don't permit a private writable mapping to be
1025 * shared with the backing device */ 1016 * shared with the backing device */
1026 if (prot & PROT_WRITE) 1017 if (prot & PROT_WRITE)
1027 capabilities &= ~BDI_CAP_MAP_DIRECT; 1018 capabilities &= ~NOMMU_MAP_DIRECT;
1028 } 1019 }
1029 1020
1030 if (capabilities & BDI_CAP_MAP_DIRECT) { 1021 if (capabilities & NOMMU_MAP_DIRECT) {
1031 if (((prot & PROT_READ) && !(capabilities & BDI_CAP_READ_MAP)) || 1022 if (((prot & PROT_READ) && !(capabilities & NOMMU_MAP_READ)) ||
1032 ((prot & PROT_WRITE) && !(capabilities & BDI_CAP_WRITE_MAP)) || 1023 ((prot & PROT_WRITE) && !(capabilities & NOMMU_MAP_WRITE)) ||
1033 ((prot & PROT_EXEC) && !(capabilities & BDI_CAP_EXEC_MAP)) 1024 ((prot & PROT_EXEC) && !(capabilities & NOMMU_MAP_EXEC))
1034 ) { 1025 ) {
1035 capabilities &= ~BDI_CAP_MAP_DIRECT; 1026 capabilities &= ~NOMMU_MAP_DIRECT;
1036 if (flags & MAP_SHARED) { 1027 if (flags & MAP_SHARED) {
1037 printk(KERN_WARNING 1028 printk(KERN_WARNING
1038 "MAP_SHARED not completely supported on !MMU\n"); 1029 "MAP_SHARED not completely supported on !MMU\n");
@@ -1049,21 +1040,21 @@ static int validate_mmap_request(struct file *file,
1049 } else if ((prot & PROT_READ) && !(prot & PROT_EXEC)) { 1040 } else if ((prot & PROT_READ) && !(prot & PROT_EXEC)) {
1050 /* handle implication of PROT_EXEC by PROT_READ */ 1041 /* handle implication of PROT_EXEC by PROT_READ */
1051 if (current->personality & READ_IMPLIES_EXEC) { 1042 if (current->personality & READ_IMPLIES_EXEC) {
1052 if (capabilities & BDI_CAP_EXEC_MAP) 1043 if (capabilities & NOMMU_MAP_EXEC)
1053 prot |= PROT_EXEC; 1044 prot |= PROT_EXEC;
1054 } 1045 }
1055 } else if ((prot & PROT_READ) && 1046 } else if ((prot & PROT_READ) &&
1056 (prot & PROT_EXEC) && 1047 (prot & PROT_EXEC) &&
1057 !(capabilities & BDI_CAP_EXEC_MAP) 1048 !(capabilities & NOMMU_MAP_EXEC)
1058 ) { 1049 ) {
1059 /* backing file is not executable, try to copy */ 1050 /* backing file is not executable, try to copy */
1060 capabilities &= ~BDI_CAP_MAP_DIRECT; 1051 capabilities &= ~NOMMU_MAP_DIRECT;
1061 } 1052 }
1062 } else { 1053 } else {
1063 /* anonymous mappings are always memory backed and can be 1054 /* anonymous mappings are always memory backed and can be
1064 * privately mapped 1055 * privately mapped
1065 */ 1056 */
1066 capabilities = BDI_CAP_MAP_COPY; 1057 capabilities = NOMMU_MAP_COPY;
1067 1058
1068 /* handle PROT_EXEC implication by PROT_READ */ 1059 /* handle PROT_EXEC implication by PROT_READ */
1069 if ((prot & PROT_READ) && 1060 if ((prot & PROT_READ) &&
@@ -1095,7 +1086,7 @@ static unsigned long determine_vm_flags(struct file *file,
1095 vm_flags = calc_vm_prot_bits(prot) | calc_vm_flag_bits(flags); 1086 vm_flags = calc_vm_prot_bits(prot) | calc_vm_flag_bits(flags);
1096 /* vm_flags |= mm->def_flags; */ 1087 /* vm_flags |= mm->def_flags; */
1097 1088
1098 if (!(capabilities & BDI_CAP_MAP_DIRECT)) { 1089 if (!(capabilities & NOMMU_MAP_DIRECT)) {
1099 /* attempt to share read-only copies of mapped file chunks */ 1090 /* attempt to share read-only copies of mapped file chunks */
1100 vm_flags |= VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC; 1091 vm_flags |= VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC;
1101 if (file && !(prot & PROT_WRITE)) 1092 if (file && !(prot & PROT_WRITE))
@@ -1104,7 +1095,7 @@ static unsigned long determine_vm_flags(struct file *file,
1104 /* overlay a shareable mapping on the backing device or inode 1095 /* overlay a shareable mapping on the backing device or inode
1105 * if possible - used for chardevs, ramfs/tmpfs/shmfs and 1096 * if possible - used for chardevs, ramfs/tmpfs/shmfs and
1106 * romfs/cramfs */ 1097 * romfs/cramfs */
1107 vm_flags |= VM_MAYSHARE | (capabilities & BDI_CAP_VMFLAGS); 1098 vm_flags |= VM_MAYSHARE | (capabilities & NOMMU_VMFLAGS);
1108 if (flags & MAP_SHARED) 1099 if (flags & MAP_SHARED)
1109 vm_flags |= VM_SHARED; 1100 vm_flags |= VM_SHARED;
1110 } 1101 }
@@ -1157,7 +1148,7 @@ static int do_mmap_private(struct vm_area_struct *vma,
1157 * shared mappings on devices or memory 1148 * shared mappings on devices or memory
1158 * - VM_MAYSHARE will be set if it may attempt to share 1149 * - VM_MAYSHARE will be set if it may attempt to share
1159 */ 1150 */
1160 if (capabilities & BDI_CAP_MAP_DIRECT) { 1151 if (capabilities & NOMMU_MAP_DIRECT) {
1161 ret = vma->vm_file->f_op->mmap(vma->vm_file, vma); 1152 ret = vma->vm_file->f_op->mmap(vma->vm_file, vma);
1162 if (ret == 0) { 1153 if (ret == 0) {
1163 /* shouldn't return success if we're not sharing */ 1154 /* shouldn't return success if we're not sharing */
@@ -1346,7 +1337,7 @@ unsigned long do_mmap_pgoff(struct file *file,
1346 if ((pregion->vm_pgoff != pgoff || rpglen != pglen) && 1337 if ((pregion->vm_pgoff != pgoff || rpglen != pglen) &&
1347 !(pgoff >= pregion->vm_pgoff && pgend <= rpgend)) { 1338 !(pgoff >= pregion->vm_pgoff && pgend <= rpgend)) {
1348 /* new mapping is not a subset of the region */ 1339 /* new mapping is not a subset of the region */
1349 if (!(capabilities & BDI_CAP_MAP_DIRECT)) 1340 if (!(capabilities & NOMMU_MAP_DIRECT))
1350 goto sharing_violation; 1341 goto sharing_violation;
1351 continue; 1342 continue;
1352 } 1343 }
@@ -1385,7 +1376,7 @@ unsigned long do_mmap_pgoff(struct file *file,
1385 * - this is the hook for quasi-memory character devices to 1376 * - this is the hook for quasi-memory character devices to
1386 * tell us the location of a shared mapping 1377 * tell us the location of a shared mapping
1387 */ 1378 */
1388 if (capabilities & BDI_CAP_MAP_DIRECT) { 1379 if (capabilities & NOMMU_MAP_DIRECT) {
1389 addr = file->f_op->get_unmapped_area(file, addr, len, 1380 addr = file->f_op->get_unmapped_area(file, addr, len,
1390 pgoff, flags); 1381 pgoff, flags);
1391 if (IS_ERR_VALUE(addr)) { 1382 if (IS_ERR_VALUE(addr)) {
@@ -1397,10 +1388,10 @@ unsigned long do_mmap_pgoff(struct file *file,
1397 * the mapping so we'll have to attempt to copy 1388 * the mapping so we'll have to attempt to copy
1398 * it */ 1389 * it */
1399 ret = -ENODEV; 1390 ret = -ENODEV;
1400 if (!(capabilities & BDI_CAP_MAP_COPY)) 1391 if (!(capabilities & NOMMU_MAP_COPY))
1401 goto error_just_free; 1392 goto error_just_free;
1402 1393
1403 capabilities &= ~BDI_CAP_MAP_DIRECT; 1394 capabilities &= ~NOMMU_MAP_DIRECT;
1404 } else { 1395 } else {
1405 vma->vm_start = region->vm_start = addr; 1396 vma->vm_start = region->vm_start = addr;
1406 vma->vm_end = region->vm_end = addr + len; 1397 vma->vm_end = region->vm_end = addr + len;
@@ -1411,7 +1402,7 @@ unsigned long do_mmap_pgoff(struct file *file,
1411 vma->vm_region = region; 1402 vma->vm_region = region;
1412 1403
1413 /* set up the mapping 1404 /* set up the mapping
1414 * - the region is filled in if BDI_CAP_MAP_DIRECT is still set 1405 * - the region is filled in if NOMMU_MAP_DIRECT is still set
1415 */ 1406 */
1416 if (file && vma->vm_flags & VM_SHARED) 1407 if (file && vma->vm_flags & VM_SHARED)
1417 ret = do_mmap_shared_file(vma); 1408 ret = do_mmap_shared_file(vma);