diff options
author | Djalal Harouni <tixxdz@opendz.org> | 2012-01-02 20:31:52 -0500 |
---|---|---|
committer | Jan Kara <jack@suse.cz> | 2012-01-09 07:52:10 -0500 |
commit | 6c2155b9cc5a193e85194bbeaae2e2e4512dd597 (patch) | |
tree | fe2e0af12ebdb2bff009f47ccdfebd8dcde2b3a2 | |
parent | 853a0c25baf96b028de1654bea1e0c8857eadf3d (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>
-rw-r--r-- | fs/ext3/ioctl.c | 6 | ||||
-rw-r--r-- | fs/ext4/ioctl.c | 6 |
2 files changed, 10 insertions, 2 deletions
diff --git a/fs/ext3/ioctl.c b/fs/ext3/ioctl.c index ba1b54e23cae..e7b2ed9d36cc 100644 --- a/fs/ext3/ioctl.c +++ b/fs/ext3/ioctl.c | |||
@@ -134,10 +134,11 @@ flags_out: | |||
134 | goto setversion_out; | 134 | goto setversion_out; |
135 | } | 135 | } |
136 | 136 | ||
137 | mutex_lock(&inode->i_mutex); | ||
137 | handle = ext3_journal_start(inode, 1); | 138 | handle = ext3_journal_start(inode, 1); |
138 | if (IS_ERR(handle)) { | 139 | if (IS_ERR(handle)) { |
139 | err = PTR_ERR(handle); | 140 | err = PTR_ERR(handle); |
140 | goto setversion_out; | 141 | goto unlock_out; |
141 | } | 142 | } |
142 | err = ext3_reserve_inode_write(handle, inode, &iloc); | 143 | err = ext3_reserve_inode_write(handle, inode, &iloc); |
143 | if (err == 0) { | 144 | if (err == 0) { |
@@ -146,6 +147,9 @@ flags_out: | |||
146 | err = ext3_mark_iloc_dirty(handle, inode, &iloc); | 147 | err = ext3_mark_iloc_dirty(handle, inode, &iloc); |
147 | } | 148 | } |
148 | ext3_journal_stop(handle); | 149 | ext3_journal_stop(handle); |
150 | |||
151 | unlock_out: | ||
152 | mutex_unlock(&inode->i_mutex); | ||
149 | setversion_out: | 153 | setversion_out: |
150 | mnt_drop_write(filp->f_path.mnt); | 154 | mnt_drop_write(filp->f_path.mnt); |
151 | return err; | 155 | return err; |
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 | |||
175 | unlock_out: | ||
176 | mutex_unlock(&inode->i_mutex); | ||
173 | setversion_out: | 177 | setversion_out: |
174 | mnt_drop_write(filp->f_path.mnt); | 178 | mnt_drop_write(filp->f_path.mnt); |
175 | return err; | 179 | return err; |