diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-02-12 16:50:21 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-02-12 16:50:21 -0500 |
commit | 6bec0035286119eefc32a5b1102127e6a4032cb2 (patch) | |
tree | 440fab001b4c877b0b0c9fd62d8392e956e387e3 /mm/nommu.c | |
parent | 5d8e7fb6916556e9b476de33404e8c9e2c9aee61 (diff) | |
parent | 15d0f5ea348b9c4e6d41df294dde38a56a39c7bf (diff) |
Merge branch 'for-3.20/bdi' of git://git.kernel.dk/linux-block
Pull backing device changes from Jens Axboe:
"This contains a cleanup of how the backing device is handled, in
preparation for a rework of the life time rules. In this part, the
most important change is to split the unrelated nommu mmap flags from
it, but also removing a backing_dev_info pointer from the
address_space (and inode), and a cleanup of other various minor bits.
Christoph did all the work here, I just fixed an oops with pages that
have a swap backing. Arnd fixed a missing export, and Oleg killed the
lustre backing_dev_info from staging. Last patch was from Al,
unexporting parts that are now no longer needed outside"
* 'for-3.20/bdi' of git://git.kernel.dk/linux-block:
Make super_blocks and sb_lock static
mtd: export new mtd_mmap_capabilities
fs: make inode_to_bdi() handle NULL inode
staging/lustre/llite: get rid of backing_dev_info
fs: remove default_backing_dev_info
fs: don't reassign dirty inodes to default_backing_dev_info
nfs: don't call bdi_unregister
ceph: remove call to bdi_unregister
fs: remove mapping->backing_dev_info
fs: export inode_to_bdi and use it in favor of mapping->backing_dev_info
nilfs2: set up s_bdi like the generic mount_bdev code
block_dev: get bdev inode bdi directly from the block device
block_dev: only write bdev inode on close
fs: introduce f_op->mmap_capabilities for nommu mmap support
fs: kill BDI_CAP_SWAP_BACKED
fs: deduplicate noop_backing_dev_info
Diffstat (limited to 'mm/nommu.c')
-rw-r--r-- | mm/nommu.c | 69 |
1 files changed, 30 insertions, 39 deletions
diff --git a/mm/nommu.c b/mm/nommu.c index 1a19fb3b0463..7296360fc057 100644 --- a/mm/nommu.c +++ b/mm/nommu.c | |||
@@ -980,9 +980,6 @@ static int validate_mmap_request(struct file *file, | |||
980 | return -EOVERFLOW; | 980 | return -EOVERFLOW; |
981 | 981 | ||
982 | if (file) { | 982 | if (file) { |
983 | /* validate file mapping requests */ | ||
984 | struct address_space *mapping; | ||
985 | |||
986 | /* files must support mmap */ | 983 | /* files must support mmap */ |
987 | if (!file->f_op->mmap) | 984 | if (!file->f_op->mmap) |
988 | return -ENODEV; | 985 | return -ENODEV; |
@@ -991,28 +988,22 @@ static int validate_mmap_request(struct file *file, | |||
991 | * - we support chardevs that provide their own "memory" | 988 | * - we support chardevs that provide their own "memory" |
992 | * - we support files/blockdevs that are memory backed | 989 | * - we support files/blockdevs that are memory backed |
993 | */ | 990 | */ |
994 | mapping = file->f_mapping; | 991 | if (file->f_op->mmap_capabilities) { |
995 | if (!mapping) | 992 | capabilities = file->f_op->mmap_capabilities(file); |
996 | mapping = file_inode(file)->i_mapping; | 993 | } else { |
997 | |||
998 | capabilities = 0; | ||
999 | if (mapping && mapping->backing_dev_info) | ||
1000 | capabilities = mapping->backing_dev_info->capabilities; | ||
1001 | |||
1002 | if (!capabilities) { | ||
1003 | /* no explicit capabilities set, so assume some | 994 | /* no explicit capabilities set, so assume some |
1004 | * defaults */ | 995 | * defaults */ |
1005 | switch (file_inode(file)->i_mode & S_IFMT) { | 996 | switch (file_inode(file)->i_mode & S_IFMT) { |
1006 | case S_IFREG: | 997 | case S_IFREG: |
1007 | case S_IFBLK: | 998 | case S_IFBLK: |
1008 | capabilities = BDI_CAP_MAP_COPY; | 999 | capabilities = NOMMU_MAP_COPY; |
1009 | break; | 1000 | break; |
1010 | 1001 | ||
1011 | case S_IFCHR: | 1002 | case S_IFCHR: |
1012 | capabilities = | 1003 | capabilities = |
1013 | BDI_CAP_MAP_DIRECT | | 1004 | NOMMU_MAP_DIRECT | |
1014 | BDI_CAP_READ_MAP | | 1005 | NOMMU_MAP_READ | |
1015 | BDI_CAP_WRITE_MAP; | 1006 | NOMMU_MAP_WRITE; |
1016 | break; | 1007 | break; |
1017 | 1008 | ||
1018 | default: | 1009 | default: |
@@ -1023,9 +1014,9 @@ static int validate_mmap_request(struct file *file, | |||
1023 | /* eliminate any capabilities that we can't support on this | 1014 | /* eliminate any capabilities that we can't support on this |
1024 | * device */ | 1015 | * device */ |
1025 | if (!file->f_op->get_unmapped_area) | 1016 | if (!file->f_op->get_unmapped_area) |
1026 | capabilities &= ~BDI_CAP_MAP_DIRECT; | 1017 | capabilities &= ~NOMMU_MAP_DIRECT; |
1027 | if (!file->f_op->read) | 1018 | if (!file->f_op->read) |
1028 | capabilities &= ~BDI_CAP_MAP_COPY; | 1019 | capabilities &= ~NOMMU_MAP_COPY; |
1029 | 1020 | ||
1030 | /* The file shall have been opened with read permission. */ | 1021 | /* The file shall have been opened with read permission. */ |
1031 | if (!(file->f_mode & FMODE_READ)) | 1022 | if (!(file->f_mode & FMODE_READ)) |
@@ -1044,29 +1035,29 @@ static int validate_mmap_request(struct file *file, | |||
1044 | if (locks_verify_locked(file)) | 1035 | if (locks_verify_locked(file)) |
1045 | return -EAGAIN; | 1036 | return -EAGAIN; |
1046 | 1037 | ||
1047 | if (!(capabilities & BDI_CAP_MAP_DIRECT)) | 1038 | if (!(capabilities & NOMMU_MAP_DIRECT)) |
1048 | return -ENODEV; | 1039 | return -ENODEV; |
1049 | 1040 | ||
1050 | /* we mustn't privatise shared mappings */ | 1041 | /* we mustn't privatise shared mappings */ |
1051 | capabilities &= ~BDI_CAP_MAP_COPY; | 1042 | capabilities &= ~NOMMU_MAP_COPY; |
1052 | } else { | 1043 | } else { |
1053 | /* we're going to read the file into private memory we | 1044 | /* we're going to read the file into private memory we |
1054 | * allocate */ | 1045 | * allocate */ |
1055 | if (!(capabilities & BDI_CAP_MAP_COPY)) | 1046 | if (!(capabilities & NOMMU_MAP_COPY)) |
1056 | return -ENODEV; | 1047 | return -ENODEV; |
1057 | 1048 | ||
1058 | /* we don't permit a private writable mapping to be | 1049 | /* we don't permit a private writable mapping to be |
1059 | * shared with the backing device */ | 1050 | * shared with the backing device */ |
1060 | if (prot & PROT_WRITE) | 1051 | if (prot & PROT_WRITE) |
1061 | capabilities &= ~BDI_CAP_MAP_DIRECT; | 1052 | capabilities &= ~NOMMU_MAP_DIRECT; |
1062 | } | 1053 | } |
1063 | 1054 | ||
1064 | if (capabilities & BDI_CAP_MAP_DIRECT) { | 1055 | if (capabilities & NOMMU_MAP_DIRECT) { |
1065 | if (((prot & PROT_READ) && !(capabilities & BDI_CAP_READ_MAP)) || | 1056 | if (((prot & PROT_READ) && !(capabilities & NOMMU_MAP_READ)) || |
1066 | ((prot & PROT_WRITE) && !(capabilities & BDI_CAP_WRITE_MAP)) || | 1057 | ((prot & PROT_WRITE) && !(capabilities & NOMMU_MAP_WRITE)) || |
1067 | ((prot & PROT_EXEC) && !(capabilities & BDI_CAP_EXEC_MAP)) | 1058 | ((prot & PROT_EXEC) && !(capabilities & NOMMU_MAP_EXEC)) |
1068 | ) { | 1059 | ) { |
1069 | capabilities &= ~BDI_CAP_MAP_DIRECT; | 1060 | capabilities &= ~NOMMU_MAP_DIRECT; |
1070 | if (flags & MAP_SHARED) { | 1061 | if (flags & MAP_SHARED) { |
1071 | printk(KERN_WARNING | 1062 | printk(KERN_WARNING |
1072 | "MAP_SHARED not completely supported on !MMU\n"); | 1063 | "MAP_SHARED not completely supported on !MMU\n"); |
@@ -1083,21 +1074,21 @@ static int validate_mmap_request(struct file *file, | |||
1083 | } else if ((prot & PROT_READ) && !(prot & PROT_EXEC)) { | 1074 | } else if ((prot & PROT_READ) && !(prot & PROT_EXEC)) { |
1084 | /* handle implication of PROT_EXEC by PROT_READ */ | 1075 | /* handle implication of PROT_EXEC by PROT_READ */ |
1085 | if (current->personality & READ_IMPLIES_EXEC) { | 1076 | if (current->personality & READ_IMPLIES_EXEC) { |
1086 | if (capabilities & BDI_CAP_EXEC_MAP) | 1077 | if (capabilities & NOMMU_MAP_EXEC) |
1087 | prot |= PROT_EXEC; | 1078 | prot |= PROT_EXEC; |
1088 | } | 1079 | } |
1089 | } else if ((prot & PROT_READ) && | 1080 | } else if ((prot & PROT_READ) && |
1090 | (prot & PROT_EXEC) && | 1081 | (prot & PROT_EXEC) && |
1091 | !(capabilities & BDI_CAP_EXEC_MAP) | 1082 | !(capabilities & NOMMU_MAP_EXEC) |
1092 | ) { | 1083 | ) { |
1093 | /* backing file is not executable, try to copy */ | 1084 | /* backing file is not executable, try to copy */ |
1094 | capabilities &= ~BDI_CAP_MAP_DIRECT; | 1085 | capabilities &= ~NOMMU_MAP_DIRECT; |
1095 | } | 1086 | } |
1096 | } else { | 1087 | } else { |
1097 | /* anonymous mappings are always memory backed and can be | 1088 | /* anonymous mappings are always memory backed and can be |
1098 | * privately mapped | 1089 | * privately mapped |
1099 | */ | 1090 | */ |
1100 | capabilities = BDI_CAP_MAP_COPY; | 1091 | capabilities = NOMMU_MAP_COPY; |
1101 | 1092 | ||
1102 | /* handle PROT_EXEC implication by PROT_READ */ | 1093 | /* handle PROT_EXEC implication by PROT_READ */ |
1103 | if ((prot & PROT_READ) && | 1094 | if ((prot & PROT_READ) && |
@@ -1129,7 +1120,7 @@ static unsigned long determine_vm_flags(struct file *file, | |||
1129 | vm_flags = calc_vm_prot_bits(prot) | calc_vm_flag_bits(flags); | 1120 | vm_flags = calc_vm_prot_bits(prot) | calc_vm_flag_bits(flags); |
1130 | /* vm_flags |= mm->def_flags; */ | 1121 | /* vm_flags |= mm->def_flags; */ |
1131 | 1122 | ||
1132 | if (!(capabilities & BDI_CAP_MAP_DIRECT)) { | 1123 | if (!(capabilities & NOMMU_MAP_DIRECT)) { |
1133 | /* attempt to share read-only copies of mapped file chunks */ | 1124 | /* attempt to share read-only copies of mapped file chunks */ |
1134 | vm_flags |= VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC; | 1125 | vm_flags |= VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC; |
1135 | if (file && !(prot & PROT_WRITE)) | 1126 | if (file && !(prot & PROT_WRITE)) |
@@ -1138,7 +1129,7 @@ static unsigned long determine_vm_flags(struct file *file, | |||
1138 | /* overlay a shareable mapping on the backing device or inode | 1129 | /* overlay a shareable mapping on the backing device or inode |
1139 | * if possible - used for chardevs, ramfs/tmpfs/shmfs and | 1130 | * if possible - used for chardevs, ramfs/tmpfs/shmfs and |
1140 | * romfs/cramfs */ | 1131 | * romfs/cramfs */ |
1141 | vm_flags |= VM_MAYSHARE | (capabilities & BDI_CAP_VMFLAGS); | 1132 | vm_flags |= VM_MAYSHARE | (capabilities & NOMMU_VMFLAGS); |
1142 | if (flags & MAP_SHARED) | 1133 | if (flags & MAP_SHARED) |
1143 | vm_flags |= VM_SHARED; | 1134 | vm_flags |= VM_SHARED; |
1144 | } | 1135 | } |
@@ -1191,7 +1182,7 @@ static int do_mmap_private(struct vm_area_struct *vma, | |||
1191 | * shared mappings on devices or memory | 1182 | * shared mappings on devices or memory |
1192 | * - VM_MAYSHARE will be set if it may attempt to share | 1183 | * - VM_MAYSHARE will be set if it may attempt to share |
1193 | */ | 1184 | */ |
1194 | if (capabilities & BDI_CAP_MAP_DIRECT) { | 1185 | if (capabilities & NOMMU_MAP_DIRECT) { |
1195 | ret = vma->vm_file->f_op->mmap(vma->vm_file, vma); | 1186 | ret = vma->vm_file->f_op->mmap(vma->vm_file, vma); |
1196 | if (ret == 0) { | 1187 | if (ret == 0) { |
1197 | /* shouldn't return success if we're not sharing */ | 1188 | /* shouldn't return success if we're not sharing */ |
@@ -1380,7 +1371,7 @@ unsigned long do_mmap_pgoff(struct file *file, | |||
1380 | if ((pregion->vm_pgoff != pgoff || rpglen != pglen) && | 1371 | if ((pregion->vm_pgoff != pgoff || rpglen != pglen) && |
1381 | !(pgoff >= pregion->vm_pgoff && pgend <= rpgend)) { | 1372 | !(pgoff >= pregion->vm_pgoff && pgend <= rpgend)) { |
1382 | /* new mapping is not a subset of the region */ | 1373 | /* new mapping is not a subset of the region */ |
1383 | if (!(capabilities & BDI_CAP_MAP_DIRECT)) | 1374 | if (!(capabilities & NOMMU_MAP_DIRECT)) |
1384 | goto sharing_violation; | 1375 | goto sharing_violation; |
1385 | continue; | 1376 | continue; |
1386 | } | 1377 | } |
@@ -1419,7 +1410,7 @@ unsigned long do_mmap_pgoff(struct file *file, | |||
1419 | * - this is the hook for quasi-memory character devices to | 1410 | * - this is the hook for quasi-memory character devices to |
1420 | * tell us the location of a shared mapping | 1411 | * tell us the location of a shared mapping |
1421 | */ | 1412 | */ |
1422 | if (capabilities & BDI_CAP_MAP_DIRECT) { | 1413 | if (capabilities & NOMMU_MAP_DIRECT) { |
1423 | addr = file->f_op->get_unmapped_area(file, addr, len, | 1414 | addr = file->f_op->get_unmapped_area(file, addr, len, |
1424 | pgoff, flags); | 1415 | pgoff, flags); |
1425 | if (IS_ERR_VALUE(addr)) { | 1416 | if (IS_ERR_VALUE(addr)) { |
@@ -1431,10 +1422,10 @@ unsigned long do_mmap_pgoff(struct file *file, | |||
1431 | * the mapping so we'll have to attempt to copy | 1422 | * the mapping so we'll have to attempt to copy |
1432 | * it */ | 1423 | * it */ |
1433 | ret = -ENODEV; | 1424 | ret = -ENODEV; |
1434 | if (!(capabilities & BDI_CAP_MAP_COPY)) | 1425 | if (!(capabilities & NOMMU_MAP_COPY)) |
1435 | goto error_just_free; | 1426 | goto error_just_free; |
1436 | 1427 | ||
1437 | capabilities &= ~BDI_CAP_MAP_DIRECT; | 1428 | capabilities &= ~NOMMU_MAP_DIRECT; |
1438 | } else { | 1429 | } else { |
1439 | vma->vm_start = region->vm_start = addr; | 1430 | vma->vm_start = region->vm_start = addr; |
1440 | vma->vm_end = region->vm_end = addr + len; | 1431 | vma->vm_end = region->vm_end = addr + len; |
@@ -1445,7 +1436,7 @@ unsigned long do_mmap_pgoff(struct file *file, | |||
1445 | vma->vm_region = region; | 1436 | vma->vm_region = region; |
1446 | 1437 | ||
1447 | /* set up the mapping | 1438 | /* set up the mapping |
1448 | * - the region is filled in if BDI_CAP_MAP_DIRECT is still set | 1439 | * - the region is filled in if NOMMU_MAP_DIRECT is still set |
1449 | */ | 1440 | */ |
1450 | if (file && vma->vm_flags & VM_SHARED) | 1441 | if (file && vma->vm_flags & VM_SHARED) |
1451 | ret = do_mmap_shared_file(vma); | 1442 | ret = do_mmap_shared_file(vma); |