diff options
author | Dmitry Monakhov <dmonakhov@openvz.org> | 2010-04-12 15:46:00 -0400 |
---|---|---|
committer | Jan Kara <jack@suse.cz> | 2010-05-21 13:30:38 -0400 |
commit | 41d1a636b813867339db52e12377ca132d54700f (patch) | |
tree | 5f970b318e17291b0c7b0b7b3a1d4ac81422d0f9 /fs/ext3/super.c | |
parent | 524e4a1d102bdcee37297c0b763e945827b33ab8 (diff) |
ext3: init statistics after journal recovery v2
Currently block/inode/dir counters are initialized before journal was
recovered. In fact after journal recovery this info will probably
change which results in incorrect numbers returned from statfs(2).
BUG:#15768
Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
Signed-off-by: Jan Kara <jack@suse.cz>
Diffstat (limited to 'fs/ext3/super.c')
-rw-r--r-- | fs/ext3/super.c | 44 |
1 files changed, 21 insertions, 23 deletions
diff --git a/fs/ext3/super.c b/fs/ext3/super.c index 1bee604cc6cd..6b6e49de0916 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c | |||
@@ -1890,21 +1890,6 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent) | |||
1890 | get_random_bytes(&sbi->s_next_generation, sizeof(u32)); | 1890 | get_random_bytes(&sbi->s_next_generation, sizeof(u32)); |
1891 | spin_lock_init(&sbi->s_next_gen_lock); | 1891 | spin_lock_init(&sbi->s_next_gen_lock); |
1892 | 1892 | ||
1893 | err = percpu_counter_init(&sbi->s_freeblocks_counter, | ||
1894 | ext3_count_free_blocks(sb)); | ||
1895 | if (!err) { | ||
1896 | err = percpu_counter_init(&sbi->s_freeinodes_counter, | ||
1897 | ext3_count_free_inodes(sb)); | ||
1898 | } | ||
1899 | if (!err) { | ||
1900 | err = percpu_counter_init(&sbi->s_dirs_counter, | ||
1901 | ext3_count_dirs(sb)); | ||
1902 | } | ||
1903 | if (err) { | ||
1904 | ext3_msg(sb, KERN_ERR, "error: insufficient memory"); | ||
1905 | goto failed_mount3; | ||
1906 | } | ||
1907 | |||
1908 | /* per fileystem reservation list head & lock */ | 1893 | /* per fileystem reservation list head & lock */ |
1909 | spin_lock_init(&sbi->s_rsv_window_lock); | 1894 | spin_lock_init(&sbi->s_rsv_window_lock); |
1910 | sbi->s_rsv_window_root = RB_ROOT; | 1895 | sbi->s_rsv_window_root = RB_ROOT; |
@@ -1945,15 +1930,29 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent) | |||
1945 | if (!test_opt(sb, NOLOAD) && | 1930 | if (!test_opt(sb, NOLOAD) && |
1946 | EXT3_HAS_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_HAS_JOURNAL)) { | 1931 | EXT3_HAS_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_HAS_JOURNAL)) { |
1947 | if (ext3_load_journal(sb, es, journal_devnum)) | 1932 | if (ext3_load_journal(sb, es, journal_devnum)) |
1948 | goto failed_mount3; | 1933 | goto failed_mount2; |
1949 | } else if (journal_inum) { | 1934 | } else if (journal_inum) { |
1950 | if (ext3_create_journal(sb, es, journal_inum)) | 1935 | if (ext3_create_journal(sb, es, journal_inum)) |
1951 | goto failed_mount3; | 1936 | goto failed_mount2; |
1952 | } else { | 1937 | } else { |
1953 | if (!silent) | 1938 | if (!silent) |
1954 | ext3_msg(sb, KERN_ERR, | 1939 | ext3_msg(sb, KERN_ERR, |
1955 | "error: no journal found. " | 1940 | "error: no journal found. " |
1956 | "mounting ext3 over ext2?"); | 1941 | "mounting ext3 over ext2?"); |
1942 | goto failed_mount2; | ||
1943 | } | ||
1944 | err = percpu_counter_init(&sbi->s_freeblocks_counter, | ||
1945 | ext3_count_free_blocks(sb)); | ||
1946 | if (!err) { | ||
1947 | err = percpu_counter_init(&sbi->s_freeinodes_counter, | ||
1948 | ext3_count_free_inodes(sb)); | ||
1949 | } | ||
1950 | if (!err) { | ||
1951 | err = percpu_counter_init(&sbi->s_dirs_counter, | ||
1952 | ext3_count_dirs(sb)); | ||
1953 | } | ||
1954 | if (err) { | ||
1955 | ext3_msg(sb, KERN_ERR, "error: insufficient memory"); | ||
1957 | goto failed_mount3; | 1956 | goto failed_mount3; |
1958 | } | 1957 | } |
1959 | 1958 | ||
@@ -1978,7 +1977,7 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent) | |||
1978 | ext3_msg(sb, KERN_ERR, | 1977 | ext3_msg(sb, KERN_ERR, |
1979 | "error: journal does not support " | 1978 | "error: journal does not support " |
1980 | "requested data journaling mode"); | 1979 | "requested data journaling mode"); |
1981 | goto failed_mount4; | 1980 | goto failed_mount3; |
1982 | } | 1981 | } |
1983 | default: | 1982 | default: |
1984 | break; | 1983 | break; |
@@ -2001,19 +2000,19 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent) | |||
2001 | if (IS_ERR(root)) { | 2000 | if (IS_ERR(root)) { |
2002 | ext3_msg(sb, KERN_ERR, "error: get root inode failed"); | 2001 | ext3_msg(sb, KERN_ERR, "error: get root inode failed"); |
2003 | ret = PTR_ERR(root); | 2002 | ret = PTR_ERR(root); |
2004 | goto failed_mount4; | 2003 | goto failed_mount3; |
2005 | } | 2004 | } |
2006 | if (!S_ISDIR(root->i_mode) || !root->i_blocks || !root->i_size) { | 2005 | if (!S_ISDIR(root->i_mode) || !root->i_blocks || !root->i_size) { |
2007 | iput(root); | 2006 | iput(root); |
2008 | ext3_msg(sb, KERN_ERR, "error: corrupt root inode, run e2fsck"); | 2007 | ext3_msg(sb, KERN_ERR, "error: corrupt root inode, run e2fsck"); |
2009 | goto failed_mount4; | 2008 | goto failed_mount3; |
2010 | } | 2009 | } |
2011 | sb->s_root = d_alloc_root(root); | 2010 | sb->s_root = d_alloc_root(root); |
2012 | if (!sb->s_root) { | 2011 | if (!sb->s_root) { |
2013 | ext3_msg(sb, KERN_ERR, "error: get root dentry failed"); | 2012 | ext3_msg(sb, KERN_ERR, "error: get root dentry failed"); |
2014 | iput(root); | 2013 | iput(root); |
2015 | ret = -ENOMEM; | 2014 | ret = -ENOMEM; |
2016 | goto failed_mount4; | 2015 | goto failed_mount3; |
2017 | } | 2016 | } |
2018 | 2017 | ||
2019 | ext3_setup_super (sb, es, sb->s_flags & MS_RDONLY); | 2018 | ext3_setup_super (sb, es, sb->s_flags & MS_RDONLY); |
@@ -2039,12 +2038,11 @@ cantfind_ext3: | |||
2039 | sb->s_id); | 2038 | sb->s_id); |
2040 | goto failed_mount; | 2039 | goto failed_mount; |
2041 | 2040 | ||
2042 | failed_mount4: | ||
2043 | journal_destroy(sbi->s_journal); | ||
2044 | failed_mount3: | 2041 | failed_mount3: |
2045 | percpu_counter_destroy(&sbi->s_freeblocks_counter); | 2042 | percpu_counter_destroy(&sbi->s_freeblocks_counter); |
2046 | percpu_counter_destroy(&sbi->s_freeinodes_counter); | 2043 | percpu_counter_destroy(&sbi->s_freeinodes_counter); |
2047 | percpu_counter_destroy(&sbi->s_dirs_counter); | 2044 | percpu_counter_destroy(&sbi->s_dirs_counter); |
2045 | journal_destroy(sbi->s_journal); | ||
2048 | failed_mount2: | 2046 | failed_mount2: |
2049 | for (i = 0; i < db_count; i++) | 2047 | for (i = 0; i < db_count; i++) |
2050 | brelse(sbi->s_group_desc[i]); | 2048 | brelse(sbi->s_group_desc[i]); |