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/ext4/super.c | 29 +++++++++++++++++++++-------- 1 files changed, 21 insertions(+), 8 deletions(-) diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 03db4af..a794707 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -1962,23 +1962,24 @@ static int ext4_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 ext4_orphan_cleanup(struct super_block *sb, +static int ext4_orphan_cleanup(struct super_block *sb, struct ext4_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 0; } if (bdev_read_only(sb->s_bdev)) { ext4_msg(sb, KERN_ERR, "write access " "unavailable, skipping orphan cleanup"); - return; + return 0; } if (EXT4_SB(sb)->s_mount_state & EXT4_ERROR_FS) { @@ -1987,7 +1988,7 @@ static void ext4_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 0; } if (s_flags & MS_RDONLY) { @@ -2000,11 +2001,13 @@ static void ext4_orphan_cleanup(struct super_block *sb, /* Turn on quotas so that they are updated correctly */ for (i = 0; i < MAXQUOTAS; i++) { if (EXT4_SB(sb)->s_qf_names[i]) { - int ret = ext4_quota_on_mount(sb, i); - if (ret < 0) + ret = ext4_quota_on_mount(sb, i); + if (ret < 0) { ext4_msg(sb, KERN_ERR, "Cannot turn on journaled " "quota: error %d", ret); + goto out; + } } } #endif @@ -2040,13 +2043,16 @@ static void ext4_orphan_cleanup(struct super_block *sb, } #define PLURAL(x) (x), ((x) == 1) ? "" : "s" - +out: if (nr_orphans) ext4_msg(sb, KERN_INFO, "%d orphan inode%s deleted", PLURAL(nr_orphans)); if (nr_truncates) ext4_msg(sb, KERN_INFO, "%d truncate%s cleaned up", PLURAL(nr_truncates)); + if (ret) + ext4_msg(sb, KERN_ERR, "Error %d wile orphan cleanup", ret); + #ifdef CONFIG_QUOTA /* Turn quotas off */ for (i = 0; i < MAXQUOTAS; i++) { @@ -2055,6 +2061,7 @@ static void ext4_orphan_cleanup(struct super_block *sb, } #endif sb->s_flags = s_flags; /* Restore MS_RDONLY status */ + return ret; } /* @@ -3020,7 +3027,13 @@ no_journal: }; EXT4_SB(sb)->s_mount_state |= EXT4_ORPHAN_FS; - ext4_orphan_cleanup(sb, es); + ret = ext4_orphan_cleanup(sb, es); + if (err) { + ext4_mb_release(sb); + ext4_ext_release(sb); + goto failed_mount4; + } + EXT4_SB(sb)->s_mount_state &= ~EXT4_ORPHAN_FS; if (needs_recovery) { ext4_msg(sb, KERN_INFO, "recovery complete"); -- 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