Commit 4b19de6d authored by Nick Piggin's avatar Nick Piggin Committed by Linus Torvalds

mm: tiny-shmem nommu fix

The previous patch db203d53 ("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.
Acked-by: default avatarDavid Howells <dhowells@redhat.com>
Acked-by: default avatarHugh Dickins <hugh@veritas.com>
Signed-off-by: default avatarNick Piggin <npiggin@suse.de>
Cc: Matt Mackall <mpm@selenic.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 6c1b7f68
...@@ -58,7 +58,7 @@ const struct inode_operations ramfs_file_inode_operations = { ...@@ -58,7 +58,7 @@ const struct inode_operations ramfs_file_inode_operations = {
* size 0 on the assumption that it's going to be used for an mmap of shared * size 0 on the assumption that it's going to be used for an mmap of shared
* memory * memory
*/ */
static int ramfs_nommu_expand_for_mapping(struct inode *inode, size_t newsize) int ramfs_nommu_expand_for_mapping(struct inode *inode, size_t newsize)
{ {
struct pagevec lru_pvec; struct pagevec lru_pvec;
unsigned long npages, xpages, loop, limit; unsigned long npages, xpages, loop, limit;
......
...@@ -6,6 +6,7 @@ extern int ramfs_get_sb(struct file_system_type *fs_type, ...@@ -6,6 +6,7 @@ extern int ramfs_get_sb(struct file_system_type *fs_type,
int flags, const char *dev_name, void *data, struct vfsmount *mnt); int flags, const char *dev_name, void *data, struct vfsmount *mnt);
#ifndef CONFIG_MMU #ifndef CONFIG_MMU
extern int ramfs_nommu_expand_for_mapping(struct inode *inode, size_t newsize);
extern unsigned long ramfs_nommu_get_unmapped_area(struct file *file, extern unsigned long ramfs_nommu_get_unmapped_area(struct file *file,
unsigned long addr, unsigned long addr,
unsigned long len, unsigned long len,
......
...@@ -80,6 +80,12 @@ struct file *shmem_file_setup(char *name, loff_t size, unsigned long flags) ...@@ -80,6 +80,12 @@ struct file *shmem_file_setup(char *name, loff_t size, unsigned long flags)
inode->i_nlink = 0; /* It is unlinked */ inode->i_nlink = 0; /* It is unlinked */
init_file(file, shm_mnt, dentry, FMODE_WRITE | FMODE_READ, init_file(file, shm_mnt, dentry, FMODE_WRITE | FMODE_READ,
&ramfs_file_operations); &ramfs_file_operations);
#ifndef CONFIG_MMU
error = ramfs_nommu_expand_for_mapping(inode, size);
if (error)
goto close_file;
#endif
return file; return file;
close_file: close_file:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment