Orphan cleanup procedure is complex task and may fail due to number of reasons. Handle errors from orphan_cleanp according to predefined per-sb errors behavior flags. Signed-off-by: Dmitry Monakhov <dmonakhov@xxxxxxxxxx> --- fs/ext3/super.c | 29 ++++++++++++++++++++--------- 1 files changed, 20 insertions(+), 9 deletions(-) diff --git a/fs/ext3/super.c b/fs/ext3/super.c index e844acc..72d979a 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c @@ -1422,23 +1422,24 @@ static int ext3_check_descriptors(struct super_block *sb) * e2fsck was run on this filesystem, and it must have already done the orphan * inode cleanup for us, so we can safely abort without any further action. */ -static void ext3_orphan_cleanup (struct super_block * sb, +static int ext3_orphan_cleanup (struct super_block * sb, struct ext3_super_block * es) { unsigned int s_flags = sb->s_flags; int nr_orphans = 0, nr_truncates = 0; + int ret = 0; #ifdef CONFIG_QUOTA int i; #endif if (!es->s_last_orphan) { jbd_debug(4, "no orphan inodes to clean up\n"); - return; + return ret; } if (bdev_read_only(sb->s_bdev)) { ext3_msg(sb, KERN_ERR, "error: write access " "unavailable, skipping orphan cleanup."); - return; + return ret; } if (EXT3_SB(sb)->s_mount_state & EXT3_ERROR_FS) { @@ -1447,7 +1448,7 @@ static void ext3_orphan_cleanup (struct super_block * sb, "clearing orphan list.\n"); es->s_last_orphan = 0; jbd_debug(1, "Skipping orphan recovery on fs with errors.\n"); - return; + return ret; } if (s_flags & MS_RDONLY) { @@ -1460,11 +1461,14 @@ static void ext3_orphan_cleanup (struct super_block * sb, /* Turn on quotas so that they are updated correctly */ for (i = 0; i < MAXQUOTAS; i++) { if (EXT3_SB(sb)->s_qf_names[i]) { - int ret = ext3_quota_on_mount(sb, i); - if (ret < 0) + ret = ext3_quota_on_mount(sb, i); + if (ret < 0) { ext3_msg(sb, KERN_ERR, "error: cannot turn on journaled " "quota: %d", ret); + if (!test_opt (sb, ERRORS_CONT)) + goto out; + } } } #endif @@ -1498,7 +1502,7 @@ static void ext3_orphan_cleanup (struct super_block * sb, } iput(inode); /* The delete magic happens here! */ } - +out: #define PLURAL(x) (x), ((x)==1) ? "" : "s" if (nr_orphans) @@ -1507,6 +1511,9 @@ static void ext3_orphan_cleanup (struct super_block * sb, if (nr_truncates) ext3_msg(sb, KERN_INFO, "%d truncate%s cleaned up", PLURAL(nr_truncates)); + if (ret) + ext3_msg(sb, KERN_ERR, "Error %d wile orphan cleanup", ret); + #ifdef CONFIG_QUOTA /* Turn quotas off */ for (i = 0; i < MAXQUOTAS; i++) { @@ -1515,6 +1522,7 @@ static void ext3_orphan_cleanup (struct super_block * sb, } #endif sb->s_flags = s_flags; /* Restore MS_RDONLY status */ + return ret; } /* @@ -2019,7 +2027,11 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent) ext3_setup_super (sb, es, sb->s_flags & MS_RDONLY); EXT3_SB(sb)->s_mount_state |= EXT3_ORPHAN_FS; - ext3_orphan_cleanup(sb, es); + ret = ext3_orphan_cleanup(sb, es); + + if (ret) + goto failed_mount4; + EXT3_SB(sb)->s_mount_state &= ~EXT3_ORPHAN_FS; if (needs_recovery) ext3_msg(sb, KERN_INFO, "recovery complete"); @@ -2038,7 +2050,6 @@ cantfind_ext3: "error: can't find ext3 filesystem on dev %s.", sb->s_id); goto failed_mount; - failed_mount4: journal_destroy(sbi->s_journal); failed_mount3: -- 1.6.6.1 -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html