diff options
author | Peng Tao <bergwolf@gmail.com> | 2009-07-13 09:30:17 -0400 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2009-07-13 09:30:17 -0400 |
commit | ac046f1d6121ccdda6db66bd88acd52418f489b2 (patch) | |
tree | 3a52ddd6ae7663b0cdd52a9eab059711626ae491 | |
parent | e6b5d30104db5f34110678ecab14988f1f1eff63 (diff) |
ext4: fix null handler of ioctls in no journal mode
The EXT4_IOC_GROUP_ADD and EXT4_IOC_GROUP_EXTEND ioctls should not
flush the journal in no_journal mode. Otherwise, running resize2fs on
a mounted no_journal partition triggers the following error messages:
BUG: unable to handle kernel NULL pointer dereference at 00000014
IP: [<c039d282>] _spin_lock+0x8/0x19
*pde = 00000000
Oops: 0002 [#1] SMP
Signed-off-by: Peng Tao <bergwolf@gmail.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
-rw-r--r-- | fs/ext4/ioctl.c | 20 |
1 files changed, 12 insertions, 8 deletions
diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c index bb415408fdb6..01f149aea841 100644 --- a/fs/ext4/ioctl.c +++ b/fs/ext4/ioctl.c | |||
@@ -192,7 +192,7 @@ setversion_out: | |||
192 | case EXT4_IOC_GROUP_EXTEND: { | 192 | case EXT4_IOC_GROUP_EXTEND: { |
193 | ext4_fsblk_t n_blocks_count; | 193 | ext4_fsblk_t n_blocks_count; |
194 | struct super_block *sb = inode->i_sb; | 194 | struct super_block *sb = inode->i_sb; |
195 | int err, err2; | 195 | int err, err2=0; |
196 | 196 | ||
197 | if (!capable(CAP_SYS_RESOURCE)) | 197 | if (!capable(CAP_SYS_RESOURCE)) |
198 | return -EPERM; | 198 | return -EPERM; |
@@ -205,9 +205,11 @@ setversion_out: | |||
205 | return err; | 205 | return err; |
206 | 206 | ||
207 | err = ext4_group_extend(sb, EXT4_SB(sb)->s_es, n_blocks_count); | 207 | err = ext4_group_extend(sb, EXT4_SB(sb)->s_es, n_blocks_count); |
208 | jbd2_journal_lock_updates(EXT4_SB(sb)->s_journal); | 208 | if (EXT4_SB(sb)->s_journal) { |
209 | err2 = jbd2_journal_flush(EXT4_SB(sb)->s_journal); | 209 | jbd2_journal_lock_updates(EXT4_SB(sb)->s_journal); |
210 | jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal); | 210 | err2 = jbd2_journal_flush(EXT4_SB(sb)->s_journal); |
211 | jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal); | ||
212 | } | ||
211 | if (err == 0) | 213 | if (err == 0) |
212 | err = err2; | 214 | err = err2; |
213 | mnt_drop_write(filp->f_path.mnt); | 215 | mnt_drop_write(filp->f_path.mnt); |
@@ -252,7 +254,7 @@ setversion_out: | |||
252 | case EXT4_IOC_GROUP_ADD: { | 254 | case EXT4_IOC_GROUP_ADD: { |
253 | struct ext4_new_group_data input; | 255 | struct ext4_new_group_data input; |
254 | struct super_block *sb = inode->i_sb; | 256 | struct super_block *sb = inode->i_sb; |
255 | int err, err2; | 257 | int err, err2=0; |
256 | 258 | ||
257 | if (!capable(CAP_SYS_RESOURCE)) | 259 | if (!capable(CAP_SYS_RESOURCE)) |
258 | return -EPERM; | 260 | return -EPERM; |
@@ -266,9 +268,11 @@ setversion_out: | |||
266 | return err; | 268 | return err; |
267 | 269 | ||
268 | err = ext4_group_add(sb, &input); | 270 | err = ext4_group_add(sb, &input); |
269 | jbd2_journal_lock_updates(EXT4_SB(sb)->s_journal); | 271 | if (EXT4_SB(sb)->s_journal) { |
270 | err2 = jbd2_journal_flush(EXT4_SB(sb)->s_journal); | 272 | jbd2_journal_lock_updates(EXT4_SB(sb)->s_journal); |
271 | jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal); | 273 | err2 = jbd2_journal_flush(EXT4_SB(sb)->s_journal); |
274 | jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal); | ||
275 | } | ||
272 | if (err == 0) | 276 | if (err == 0) |
273 | err = err2; | 277 | err = err2; |
274 | mnt_drop_write(filp->f_path.mnt); | 278 | mnt_drop_write(filp->f_path.mnt); |