diff options
author | Hidehiro Kawai <hidehiro.kawai.ez@hitachi.com> | 2008-10-22 17:15:01 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-10-23 11:55:01 -0400 |
commit | 2d7c820e56ce83b23daee9eb5343730fb309418e (patch) | |
tree | a64db3f90c8826a03c591be492faaf64ab7bf14a /fs/ext3/ioctl.c | |
parent | 4afe978530702c934dfdb11f54073136818b2119 (diff) |
ext3: add checks for errors from jbd
If the journal has aborted due to a checkpointing failure, we have to
keep the contents of the journal space. Otherwise, the filesystem will
lose uncheckpointed metadata completely and become inconsistent. To
avoid this, we need to keep needs_recovery flag if checkpoint has
failed.
With this patch, ext3_put_super() detects a checkpointing failure from
the return value of journal_destroy(), then it invokes ext3_abort() to
make the filesystem read only and keep needs_recovery flag. Errors
from journal_flush() are also handled by this patch in some places.
Signed-off-by: Hidehiro Kawai <hidehiro.kawai.ez@hitachi.com>
Cc: Jan Kara <jack@ucw.cz>
Cc: Stephen Rothwell <sfr@canb.auug.org.au>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: <linux-ext4@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/ext3/ioctl.c')
-rw-r--r-- | fs/ext3/ioctl.c | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/fs/ext3/ioctl.c b/fs/ext3/ioctl.c index 0d0c70151642..b7394d05ee8e 100644 --- a/fs/ext3/ioctl.c +++ b/fs/ext3/ioctl.c | |||
@@ -239,7 +239,7 @@ setrsvsz_out: | |||
239 | case EXT3_IOC_GROUP_EXTEND: { | 239 | case EXT3_IOC_GROUP_EXTEND: { |
240 | ext3_fsblk_t n_blocks_count; | 240 | ext3_fsblk_t n_blocks_count; |
241 | struct super_block *sb = inode->i_sb; | 241 | struct super_block *sb = inode->i_sb; |
242 | int err; | 242 | int err, err2; |
243 | 243 | ||
244 | if (!capable(CAP_SYS_RESOURCE)) | 244 | if (!capable(CAP_SYS_RESOURCE)) |
245 | return -EPERM; | 245 | return -EPERM; |
@@ -254,8 +254,10 @@ setrsvsz_out: | |||
254 | } | 254 | } |
255 | err = ext3_group_extend(sb, EXT3_SB(sb)->s_es, n_blocks_count); | 255 | err = ext3_group_extend(sb, EXT3_SB(sb)->s_es, n_blocks_count); |
256 | journal_lock_updates(EXT3_SB(sb)->s_journal); | 256 | journal_lock_updates(EXT3_SB(sb)->s_journal); |
257 | journal_flush(EXT3_SB(sb)->s_journal); | 257 | err2 = journal_flush(EXT3_SB(sb)->s_journal); |
258 | journal_unlock_updates(EXT3_SB(sb)->s_journal); | 258 | journal_unlock_updates(EXT3_SB(sb)->s_journal); |
259 | if (err == 0) | ||
260 | err = err2; | ||
259 | group_extend_out: | 261 | group_extend_out: |
260 | mnt_drop_write(filp->f_path.mnt); | 262 | mnt_drop_write(filp->f_path.mnt); |
261 | return err; | 263 | return err; |
@@ -263,7 +265,7 @@ group_extend_out: | |||
263 | case EXT3_IOC_GROUP_ADD: { | 265 | case EXT3_IOC_GROUP_ADD: { |
264 | struct ext3_new_group_data input; | 266 | struct ext3_new_group_data input; |
265 | struct super_block *sb = inode->i_sb; | 267 | struct super_block *sb = inode->i_sb; |
266 | int err; | 268 | int err, err2; |
267 | 269 | ||
268 | if (!capable(CAP_SYS_RESOURCE)) | 270 | if (!capable(CAP_SYS_RESOURCE)) |
269 | return -EPERM; | 271 | return -EPERM; |
@@ -280,8 +282,10 @@ group_extend_out: | |||
280 | 282 | ||
281 | err = ext3_group_add(sb, &input); | 283 | err = ext3_group_add(sb, &input); |
282 | journal_lock_updates(EXT3_SB(sb)->s_journal); | 284 | journal_lock_updates(EXT3_SB(sb)->s_journal); |
283 | journal_flush(EXT3_SB(sb)->s_journal); | 285 | err2 = journal_flush(EXT3_SB(sb)->s_journal); |
284 | journal_unlock_updates(EXT3_SB(sb)->s_journal); | 286 | journal_unlock_updates(EXT3_SB(sb)->s_journal); |
287 | if (err == 0) | ||
288 | err = err2; | ||
285 | group_add_out: | 289 | group_add_out: |
286 | mnt_drop_write(filp->f_path.mnt); | 290 | mnt_drop_write(filp->f_path.mnt); |
287 | return err; | 291 | return err; |