History

mm: tiny-shmem nommu fix

The previous patch db203d53d474aa068984e409d807628f5841da1b ("mm: tiny-shmem fix lock ordering: mmap_sem vs i_mutex") to fix the lock ordering in tiny-shmem breaks shared anonymous and IPC memory on NOMMU architectures because it was using the expanding truncate to signal ramfs to allocate a physically contiguous RAM backing the inode (otherwise it is unusable for "memory mapping" it to userspace). However do_truncate is what caused the lock ordering error, due to it taking i_mutex. In this case, we can actually just call ramfs directly to allocate memory for the mapping, rather than go via truncate.

Nick Piggin committed 18 years ago

Commit 4b19de61 parent 6c1b7f63 files · +8 −1Browse files

Unified · Split

3 files
  1. fs/ramfs/file-nommu.c +1 −1
  2. include/linux/ramfs.h +1 −0
  3. mm/tiny-shmem.c +6 −0
fs/ramfs/file-nommu.c+1−1
@@ -58,7 +58,7 @@ const struct inode_operations ramfs_file_inode_operations = { · 57 unmodified lines
58 * size 0 on the assumption that it's going to be used for an mmap of shared58 * size 0 on the assumption that it's going to be used for an mmap of shared
59 * memory59 * memory
60 */60 */
61static int ramfs_nommu_expand_for_mapping(struct inode *inode, size_t newsize)61int ramfs_nommu_expand_for_mapping(struct inode *inode, size_t newsize)
62{62{
63 struct pagevec lru_pvec;63 struct pagevec lru_pvec;
64 unsigned long npages, xpages, loop, limit;64 unsigned long npages, xpages, loop, limit;
include/linux/ramfs.h+1−0
@@ -6,6 +6,7 @@ extern int ramfs_get_sb(struct file_system_type *fs_type, · 5 unmodified lines
6 int flags, const char *dev_name, void *data, struct vfsmount *mnt);6 int flags, const char *dev_name, void *data, struct vfsmount *mnt);
7 7
8#ifndef CONFIG_MMU8#ifndef CONFIG_MMU
9extern int ramfs_nommu_expand_for_mapping(struct inode *inode, size_t newsize);
9extern unsigned long ramfs_nommu_get_unmapped_area(struct file *file,10extern unsigned long ramfs_nommu_get_unmapped_area(struct file *file,
10 unsigned long addr,11 unsigned long addr,
11 unsigned long len,12 unsigned long len,
mm/tiny-shmem.c+6−0
@@ -80,6 +80,12 @@ struct file *shmem_file_setup(char *name, loff_t size, unsigned long flags) · 79 unmodified lines
80 inode->i_nlink = 0; /* It is unlinked */80 inode->i_nlink = 0; /* It is unlinked */
81 init_file(file, shm_mnt, dentry, FMODE_WRITE | FMODE_READ,81 init_file(file, shm_mnt, dentry, FMODE_WRITE | FMODE_READ,
82 &ramfs_file_operations);82 &ramfs_file_operations);
83
84#ifndef CONFIG_MMU
85 error = ramfs_nommu_expand_for_mapping(inode, size);
86 if (error)
87 goto close_file;
88#endif
83 return file;89 return file;
84 90
85close_file:91close_file: