aboutsummaryrefslogtreecommitdiffstats
path: root/mm/tiny-shmem.c
diff options
context:
space:
mode:
authorNick Piggin <npiggin@suse.de>2008-09-22 16:57:50 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-09-23 11:09:14 -0400
commitdb203d53d474aa068984e409d807628f5841da1b (patch)
tree7c4352513d8a108b916d2cbe16234346addf179c /mm/tiny-shmem.c
parent2d4c8266774188cda7f7e612e6dfb8ad12c579d5 (diff)
mm: tiny-shmem fix lock ordering: mmap_sem vs i_mutex
tiny-shmem calls do_truncate in shmem_file_setup. do_truncate takes i_mutex, and shmem_file_setup is called with mmap_sem held. However i_mutex nests outside mmap_sem. Copy the code in shmem.c to avoid this problem. [akpm@linux-foundation.org: coding-style fixes] Signed-off-by: Nick Piggin <npiggin@suse.de> Reported-and-tested-by: Ingo Molnar <mingo@elte.hu> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Matt Mackall <mpm@selenic.com> Cc: Hugh Dickins <hugh@veritas.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/tiny-shmem.c')
-rw-r--r--mm/tiny-shmem.c24
1 files changed, 9 insertions, 15 deletions
diff --git a/mm/tiny-shmem.c b/mm/tiny-shmem.c
index ae532f501943..d17cb6f6ab10 100644
--- a/mm/tiny-shmem.c
+++ b/mm/tiny-shmem.c
@@ -65,31 +65,25 @@ struct file *shmem_file_setup(char *name, loff_t size, unsigned long flags)
65 if (!dentry) 65 if (!dentry)
66 goto put_memory; 66 goto put_memory;
67 67
68 error = -ENOSPC;
69 inode = ramfs_get_inode(root->d_sb, S_IFREG | S_IRWXUGO, 0);
70 if (!inode)
71 goto put_dentry;
72
73 d_instantiate(dentry, inode);
74 error = -ENFILE; 68 error = -ENFILE;
75 file = alloc_file(shm_mnt, dentry, FMODE_WRITE | FMODE_READ, 69 file = get_empty_filp();
76 &ramfs_file_operations);
77 if (!file) 70 if (!file)
78 goto put_dentry; 71 goto put_dentry;
79 72
80 inode->i_nlink = 0; /* It is unlinked */ 73 error = -ENOSPC;
81 74 inode = ramfs_get_inode(root->d_sb, S_IFREG | S_IRWXUGO, 0);
82 /* notify everyone as to the change of file size */ 75 if (!inode)
83 error = do_truncate(dentry, size, 0, file);
84 if (error < 0)
85 goto close_file; 76 goto close_file;
86 77
78 d_instantiate(dentry, inode);
79 inode->i_size = size;
80 inode->i_nlink = 0; /* It is unlinked */
81 init_file(file, shm_mnt, dentry, FMODE_WRITE | FMODE_READ,
82 &ramfs_file_operations);
87 return file; 83 return file;
88 84
89close_file: 85close_file:
90 put_filp(file); 86 put_filp(file);
91 return ERR_PTR(error);
92
93put_dentry: 87put_dentry:
94 dput(dentry); 88 dput(dentry);
95put_memory: 89put_memory: