aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Monakhov <dmonakhov@openvz.org>2010-04-12 15:46:00 -0400
committerJan Kara <jack@suse.cz>2010-05-21 13:30:38 -0400
commit41d1a636b813867339db52e12377ca132d54700f (patch)
tree5f970b318e17291b0c7b0b7b3a1d4ac81422d0f9
parent524e4a1d102bdcee37297c0b763e945827b33ab8 (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>
-rw-r--r--fs/ext3/super.c44
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
2042failed_mount4:
2043 journal_destroy(sbi->s_journal);
2044failed_mount3: 2041failed_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);
2048failed_mount2: 2046failed_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]);