diff options
author | David Howells <dhowells@redhat.com> | 2006-01-06 03:11:42 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-01-06 11:33:32 -0500 |
commit | b0e15190ead07056ab0c3844a499ff35e66d27cc (patch) | |
tree | 0601a8d68fa051a7ee85d22640e982c0a64f0efc | |
parent | 642fb4d1f1dd2417aa69189fe5ceb81e4fb72900 (diff) |
[PATCH] NOMMU: Make SYSV IPC SHM use ramfs facilities on NOMMU
The attached patch makes the SYSV IPC shared memory facilities use the new
ramfs facilities on a no-MMU kernel.
The following changes are made:
(1) There are now shmem_mmap() and shmem_get_unmapped_area() functions to
allow the IPC SHM facilities to commune with the tiny-shmem and shmem
code.
(2) ramfs files now need resizing using do_truncate() rather than by modifying
the inode size directly (see shmem_file_setup()). This causes ramfs to
attempt to bind a block of pages of sufficient size to the inode.
(3) CONFIG_SYSVIPC is no longer contingent on CONFIG_MMU.
Signed-off-by: David Howells <dhowells@redhat.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r-- | include/linux/mm.h | 9 | ||||
-rw-r--r-- | init/Kconfig | 1 | ||||
-rw-r--r-- | ipc/shm.c | 18 | ||||
-rw-r--r-- | mm/nommu.c | 7 | ||||
-rw-r--r-- | mm/shmem.c | 2 | ||||
-rw-r--r-- | mm/tiny-shmem.c | 29 |
6 files changed, 58 insertions, 8 deletions
diff --git a/include/linux/mm.h b/include/linux/mm.h index 75ec04e2f184..26f3094911a5 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h | |||
@@ -654,9 +654,18 @@ static inline struct mempolicy *shmem_get_policy(struct vm_area_struct *vma, | |||
654 | } | 654 | } |
655 | #endif | 655 | #endif |
656 | struct file *shmem_file_setup(char *name, loff_t size, unsigned long flags); | 656 | struct file *shmem_file_setup(char *name, loff_t size, unsigned long flags); |
657 | extern int shmem_mmap(struct file *file, struct vm_area_struct *vma); | ||
657 | 658 | ||
658 | int shmem_zero_setup(struct vm_area_struct *); | 659 | int shmem_zero_setup(struct vm_area_struct *); |
659 | 660 | ||
661 | #ifndef CONFIG_MMU | ||
662 | extern unsigned long shmem_get_unmapped_area(struct file *file, | ||
663 | unsigned long addr, | ||
664 | unsigned long len, | ||
665 | unsigned long pgoff, | ||
666 | unsigned long flags); | ||
667 | #endif | ||
668 | |||
660 | static inline int can_do_mlock(void) | 669 | static inline int can_do_mlock(void) |
661 | { | 670 | { |
662 | if (capable(CAP_IPC_LOCK)) | 671 | if (capable(CAP_IPC_LOCK)) |
diff --git a/init/Kconfig b/init/Kconfig index ce737e02c5a2..24e0f7c756c0 100644 --- a/init/Kconfig +++ b/init/Kconfig | |||
@@ -105,7 +105,6 @@ config SWAP | |||
105 | 105 | ||
106 | config SYSVIPC | 106 | config SYSVIPC |
107 | bool "System V IPC" | 107 | bool "System V IPC" |
108 | depends on MMU | ||
109 | ---help--- | 108 | ---help--- |
110 | Inter Process Communication is a suite of library functions and | 109 | Inter Process Communication is a suite of library functions and |
111 | system calls which let processes (running programs) synchronize and | 110 | system calls which let processes (running programs) synchronize and |
@@ -157,14 +157,22 @@ static void shm_close (struct vm_area_struct *shmd) | |||
157 | 157 | ||
158 | static int shm_mmap(struct file * file, struct vm_area_struct * vma) | 158 | static int shm_mmap(struct file * file, struct vm_area_struct * vma) |
159 | { | 159 | { |
160 | file_accessed(file); | 160 | int ret; |
161 | vma->vm_ops = &shm_vm_ops; | 161 | |
162 | shm_inc(file->f_dentry->d_inode->i_ino); | 162 | ret = shmem_mmap(file, vma); |
163 | return 0; | 163 | if (ret == 0) { |
164 | vma->vm_ops = &shm_vm_ops; | ||
165 | shm_inc(file->f_dentry->d_inode->i_ino); | ||
166 | } | ||
167 | |||
168 | return ret; | ||
164 | } | 169 | } |
165 | 170 | ||
166 | static struct file_operations shm_file_operations = { | 171 | static struct file_operations shm_file_operations = { |
167 | .mmap = shm_mmap | 172 | .mmap = shm_mmap, |
173 | #ifndef CONFIG_MMU | ||
174 | .get_unmapped_area = shmem_get_unmapped_area, | ||
175 | #endif | ||
168 | }; | 176 | }; |
169 | 177 | ||
170 | static struct vm_operations_struct shm_vm_ops = { | 178 | static struct vm_operations_struct shm_vm_ops = { |
diff --git a/mm/nommu.c b/mm/nommu.c index c1196812876b..c10262d68232 100644 --- a/mm/nommu.c +++ b/mm/nommu.c | |||
@@ -1177,3 +1177,10 @@ int in_gate_area_no_task(unsigned long addr) | |||
1177 | { | 1177 | { |
1178 | return 0; | 1178 | return 0; |
1179 | } | 1179 | } |
1180 | |||
1181 | struct page *filemap_nopage(struct vm_area_struct *area, | ||
1182 | unsigned long address, int *type) | ||
1183 | { | ||
1184 | BUG(); | ||
1185 | return NULL; | ||
1186 | } | ||
diff --git a/mm/shmem.c b/mm/shmem.c index 65c148efa2ed..a1f2f02af724 100644 --- a/mm/shmem.c +++ b/mm/shmem.c | |||
@@ -1270,7 +1270,7 @@ out_nomem: | |||
1270 | return retval; | 1270 | return retval; |
1271 | } | 1271 | } |
1272 | 1272 | ||
1273 | static int shmem_mmap(struct file *file, struct vm_area_struct *vma) | 1273 | int shmem_mmap(struct file *file, struct vm_area_struct *vma) |
1274 | { | 1274 | { |
1275 | file_accessed(file); | 1275 | file_accessed(file); |
1276 | vma->vm_ops = &shmem_vm_ops; | 1276 | vma->vm_ops = &shmem_vm_ops; |
diff --git a/mm/tiny-shmem.c b/mm/tiny-shmem.c index b58abcf44ed6..cdc6d431972b 100644 --- a/mm/tiny-shmem.c +++ b/mm/tiny-shmem.c | |||
@@ -81,13 +81,19 @@ struct file *shmem_file_setup(char *name, loff_t size, unsigned long flags) | |||
81 | goto close_file; | 81 | goto close_file; |
82 | 82 | ||
83 | d_instantiate(dentry, inode); | 83 | d_instantiate(dentry, inode); |
84 | inode->i_size = size; | ||
85 | inode->i_nlink = 0; /* It is unlinked */ | 84 | inode->i_nlink = 0; /* It is unlinked */ |
85 | |||
86 | file->f_vfsmnt = mntget(shm_mnt); | 86 | file->f_vfsmnt = mntget(shm_mnt); |
87 | file->f_dentry = dentry; | 87 | file->f_dentry = dentry; |
88 | file->f_mapping = inode->i_mapping; | 88 | file->f_mapping = inode->i_mapping; |
89 | file->f_op = &ramfs_file_operations; | 89 | file->f_op = &ramfs_file_operations; |
90 | file->f_mode = FMODE_WRITE | FMODE_READ; | 90 | file->f_mode = FMODE_WRITE | FMODE_READ; |
91 | |||
92 | /* notify everyone as to the change of file size */ | ||
93 | error = do_truncate(dentry, size, file); | ||
94 | if (error < 0) | ||
95 | goto close_file; | ||
96 | |||
91 | return file; | 97 | return file; |
92 | 98 | ||
93 | close_file: | 99 | close_file: |
@@ -123,3 +129,24 @@ int shmem_unuse(swp_entry_t entry, struct page *page) | |||
123 | { | 129 | { |
124 | return 0; | 130 | return 0; |
125 | } | 131 | } |
132 | |||
133 | int shmem_mmap(struct file *file, struct vm_area_struct *vma) | ||
134 | { | ||
135 | file_accessed(file); | ||
136 | #ifndef CONFIG_MMU | ||
137 | return ramfs_nommu_mmap(file, vma); | ||
138 | #else | ||
139 | return 0; | ||
140 | #endif | ||
141 | } | ||
142 | |||
143 | #ifndef CONFIG_MMU | ||
144 | unsigned long shmem_get_unmapped_area(struct file *file, | ||
145 | unsigned long addr, | ||
146 | unsigned long len, | ||
147 | unsigned long pgoff, | ||
148 | unsigned long flags) | ||
149 | { | ||
150 | return ramfs_nommu_get_unmapped_area(file, addr, len, pgoff, flags); | ||
151 | } | ||
152 | #endif | ||