Messages in this thread Patch in this message |  | | | Date | Thu, 9 Dec 2004 15:08:58 GMT | | From | dhowells@redhat ... | | Subject | [PATCH 5/5] NOMMU: Futher nommu shared memory support |
| |
The attached patch furthers shared memory support under !MMU conditions:
(1) tiny-shmem.c farms get_unmapped_area() and mmap() requests off to ramfs in addition to the inode creation requests, thus supporting SYSV SHM
(2) tiny-shmem.c no longer expands the inode it allocates by writing directly into i_size.
(3) SYSV IPC is then available on nommu.
(a) SYSV SHM requires shmem_mmap() to be provided by the backing filesystem (tmpfs in shmem.c or tiny-shmem.c).
(b) SYSV SHM requires shmem_get_unmapped_area() to be provided by the backing fs if under !MMU conditions.
Signed-Off-By: dhowells@redhat.com --- diffstat nommu-shmem-2610rc2mm3-3.diff include/linux/mm.h | 11 +++++++++++ init/Kconfig | 1 - ipc/shm.c | 16 +++++++++++----- mm/shmem.c | 2 +- mm/tiny-shmem.c | 26 +++++++++++++++++++++++++- 5 files changed, 48 insertions(+), 8 deletions(-) diff -uNrp linux-2.6.10-rc2-mm3-mmcleanup/init/Kconfig linux-2.6.10-rc2-mm3-shmem/init/Kconfig --- linux-2.6.10-rc2-mm3-mmcleanup/init/Kconfig 2004-11-22 10:54:17.000000000 +0000 +++ linux-2.6.10-rc2-mm3-shmem/init/Kconfig 2004-12-01 17:07:36.000000000 +0000 @@ -81,7 +81,6 @@ config SWAP config SYSVIPC bool "System V IPC" - depends on MMU ---help--- Inter Process Communication is a suite of library functions and system calls which let processes (running programs) synchronize and diff -uNrp linux-2.6.10-rc2-mm3-mmcleanup/include/linux/mm.h linux-2.6.10-rc2-mm3-shmem/include/linux/mm.h --- linux-2.6.10-rc2-mm3-mmcleanup/include/linux/mm.h 2004-11-22 10:54:16.000000000 +0000 +++ linux-2.6.10-rc2-mm3-shmem/include/linux/mm.h 2004-12-08 16:52:24.000000000 +0000 @@ -566,9 +603,20 @@ int shmem_lock(struct file *file, int lo #define shmem_get_policy(a, b) (NULL) #endif struct file *shmem_file_setup(char *name, loff_t size, unsigned long flags); +extern int shmem_mmap(struct file *file, struct vm_area_struct *vma); int shmem_zero_setup(struct vm_area_struct *); +#ifdef CONFIG_MMU +#define shmem_get_unmapped_area(f,a,l,p,fl) 0 +#else +extern unsigned long shmem_get_unmapped_area(struct file *file, + unsigned long addr, + unsigned long len, + unsigned long pgoff, + unsigned long flags); +#endif + static inline int can_do_mlock(void) { if (capable(CAP_IPC_LOCK)) diff -uNrp linux-2.6.10-rc2-mm3-mmcleanup/ipc/shm.c linux-2.6.10-rc2-mm3-shmem/ipc/shm.c --- linux-2.6.10-rc2-mm3-mmcleanup/ipc/shm.c 2004-11-22 10:54:17.000000000 +0000 +++ linux-2.6.10-rc2-mm3-shmem/ipc/shm.c 2004-12-02 15:20:36.000000000 +0000 @@ -157,14 +157,20 @@ static void shm_close (struct vm_area_st static int shm_mmap(struct file * file, struct vm_area_struct * vma) { - file_accessed(file); - vma->vm_ops = &shm_vm_ops; - shm_inc(file->f_dentry->d_inode->i_ino); - return 0; + int ret; + + ret = shmem_mmap(file, vma); + if (ret == 0) { + vma->vm_ops = &shm_vm_ops; + shm_inc(file->f_dentry->d_inode->i_ino); + } + + return ret; } static struct file_operations shm_file_operations = { - .mmap = shm_mmap + .mmap = shm_mmap, + .get_unmapped_area = shmem_get_unmapped_area, }; static struct vm_operations_struct shm_vm_ops = { diff -uNrp linux-2.6.10-rc2-mm3-mmcleanup/mm/shmem.c linux-2.6.10-rc2-mm3-shmem/mm/shmem.c --- linux-2.6.10-rc2-mm3-mmcleanup/mm/shmem.c 2004-11-22 10:54:18.000000000 +0000 +++ linux-2.6.10-rc2-mm3-shmem/mm/shmem.c 2004-12-02 15:16:23.000000000 +0000 @@ -1246,7 +1246,7 @@ out_nomem: return retval; } -static int shmem_mmap(struct file *file, struct vm_area_struct *vma) +int shmem_mmap(struct file *file, struct vm_area_struct *vma) { file_accessed(file); vma->vm_ops = &shmem_vm_ops; diff -uNrp linux-2.6.10-rc2-mm3-mmcleanup/mm/tiny-shmem.c linux-2.6.10-rc2-mm3-shmem/mm/tiny-shmem.c --- linux-2.6.10-rc2-mm3-mmcleanup/mm/tiny-shmem.c 2004-11-15 13:34:39.000000000 +0000 +++ linux-2.6.10-rc2-mm3-shmem/mm/tiny-shmem.c 2004-12-02 16:20:55.000000000 +0000 @@ -78,8 +78,13 @@ struct file *shmem_file_setup(char *name goto close_file; d_instantiate(dentry, inode); - inode->i_size = size; inode->i_nlink = 0; /* It is unlinked */ + + /* notify everyone as to the change of file size */ + error = do_truncate(dentry, size); + if (error < 0) + goto close_file; + file->f_vfsmnt = mntget(shm_mnt); file->f_dentry = dentry; file->f_mapping = inode->i_mapping; @@ -120,3 +125,22 @@ int shmem_unuse(swp_entry_t entry, struc { return 0; } + +int shmem_mmap(struct file *file, struct vm_area_struct *vma) +{ + file_accessed(file); +#ifndef CONFIG_MMU + return ramfs_nommu_mmap(file, vma); +#else + return 0; +#endif +} + +unsigned long shmem_get_unmapped_area(struct file *file, + unsigned long addr, + unsigned long len, + unsigned long pgoff, + unsigned long flags) +{ + return ramfs_nommu_get_unmapped_area(file, addr, len, pgoff, flags); +} - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
|  |