aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4
diff options
context:
space:
mode:
authorDjalal Harouni <tixxdz@opendz.org>2012-01-02 20:31:52 -0500
committerJan Kara <jack@suse.cz>2012-01-09 07:52:10 -0500
commit6c2155b9cc5a193e85194bbeaae2e2e4512dd597 (patch)
treefe2e0af12ebdb2bff009f47ccdfebd8dcde2b3a2 /fs/ext4
parent853a0c25baf96b028de1654bea1e0c8857eadf3d (diff)
ext{3,4}: Fix potential race when setversion ioctl updates inode
The EXT{3,4}_IOC_SETVERSION ioctl() updates i_ctime and i_generation without i_mutex. This can lead to a race with the other operations that update i_ctime. This is not a big issue but let's make the ioctl consistent with how we handle e.g. other timestamp updates and use i_mutex to protect inode changes. Signed-off-by: Djalal Harouni <tixxdz@opendz.org> Signed-off-by: Jan Kara <jack@suse.cz>
Diffstat (limited to 'fs/ext4')
-rw-r--r--fs/ext4/ioctl.c6
1 files changed, 5 insertions, 1 deletions
diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c
index a56796814d6a..46a8de6f2089 100644
--- a/fs/ext4/ioctl.c
+++ b/fs/ext4/ioctl.c
@@ -158,10 +158,11 @@ flags_out:
158 goto setversion_out; 158 goto setversion_out;
159 } 159 }
160 160
161 mutex_lock(&inode->i_mutex);
161 handle = ext4_journal_start(inode, 1); 162 handle = ext4_journal_start(inode, 1);
162 if (IS_ERR(handle)) { 163 if (IS_ERR(handle)) {
163 err = PTR_ERR(handle); 164 err = PTR_ERR(handle);
164 goto setversion_out; 165 goto unlock_out;
165 } 166 }
166 err = ext4_reserve_inode_write(handle, inode, &iloc); 167 err = ext4_reserve_inode_write(handle, inode, &iloc);
167 if (err == 0) { 168 if (err == 0) {
@@ -170,6 +171,9 @@ flags_out:
170 err = ext4_mark_iloc_dirty(handle, inode, &iloc); 171 err = ext4_mark_iloc_dirty(handle, inode, &iloc);
171 } 172 }
172 ext4_journal_stop(handle); 173 ext4_journal_stop(handle);
174
175unlock_out:
176 mutex_unlock(&inode->i_mutex);
173setversion_out: 177setversion_out:
174 mnt_drop_write(filp->f_path.mnt); 178 mnt_drop_write(filp->f_path.mnt);
175 return err; 179 return err;