aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext3/super.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ext3/super.c')
-rw-r--r--fs/ext3/super.c52
1 files changed, 39 insertions, 13 deletions
diff --git a/fs/ext3/super.c b/fs/ext3/super.c
index 6e3062913a92..4f84dc86628a 100644
--- a/fs/ext3/super.c
+++ b/fs/ext3/super.c
@@ -29,12 +29,14 @@
29#include <linux/parser.h> 29#include <linux/parser.h>
30#include <linux/smp_lock.h> 30#include <linux/smp_lock.h>
31#include <linux/buffer_head.h> 31#include <linux/buffer_head.h>
32#include <linux/exportfs.h>
32#include <linux/vfs.h> 33#include <linux/vfs.h>
33#include <linux/random.h> 34#include <linux/random.h>
34#include <linux/mount.h> 35#include <linux/mount.h>
35#include <linux/namei.h> 36#include <linux/namei.h>
36#include <linux/quotaops.h> 37#include <linux/quotaops.h>
37#include <linux/seq_file.h> 38#include <linux/seq_file.h>
39#include <linux/log2.h>
38 40
39#include <asm/uaccess.h> 41#include <asm/uaccess.h>
40 42
@@ -459,6 +461,14 @@ static struct inode *ext3_alloc_inode(struct super_block *sb)
459 461
460static void ext3_destroy_inode(struct inode *inode) 462static void ext3_destroy_inode(struct inode *inode)
461{ 463{
464 if (!list_empty(&(EXT3_I(inode)->i_orphan))) {
465 printk("EXT3 Inode %p: orphan list check failed!\n",
466 EXT3_I(inode));
467 print_hex_dump(KERN_INFO, "", DUMP_PREFIX_ADDRESS, 16, 4,
468 EXT3_I(inode), sizeof(struct ext3_inode_info),
469 false);
470 dump_stack();
471 }
462 kmem_cache_free(ext3_inode_cachep, EXT3_I(inode)); 472 kmem_cache_free(ext3_inode_cachep, EXT3_I(inode));
463} 473}
464 474
@@ -1566,7 +1576,7 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent)
1566 sbi->s_inode_size = le16_to_cpu(es->s_inode_size); 1576 sbi->s_inode_size = le16_to_cpu(es->s_inode_size);
1567 sbi->s_first_ino = le32_to_cpu(es->s_first_ino); 1577 sbi->s_first_ino = le32_to_cpu(es->s_first_ino);
1568 if ((sbi->s_inode_size < EXT3_GOOD_OLD_INODE_SIZE) || 1578 if ((sbi->s_inode_size < EXT3_GOOD_OLD_INODE_SIZE) ||
1569 (sbi->s_inode_size & (sbi->s_inode_size - 1)) || 1579 (!is_power_of_2(sbi->s_inode_size)) ||
1570 (sbi->s_inode_size > blocksize)) { 1580 (sbi->s_inode_size > blocksize)) {
1571 printk (KERN_ERR 1581 printk (KERN_ERR
1572 "EXT3-fs: unsupported inode size: %d\n", 1582 "EXT3-fs: unsupported inode size: %d\n",
@@ -2075,6 +2085,7 @@ static int ext3_create_journal(struct super_block * sb,
2075 unsigned int journal_inum) 2085 unsigned int journal_inum)
2076{ 2086{
2077 journal_t *journal; 2087 journal_t *journal;
2088 int err;
2078 2089
2079 if (sb->s_flags & MS_RDONLY) { 2090 if (sb->s_flags & MS_RDONLY) {
2080 printk(KERN_ERR "EXT3-fs: readonly filesystem when trying to " 2091 printk(KERN_ERR "EXT3-fs: readonly filesystem when trying to "
@@ -2082,13 +2093,15 @@ static int ext3_create_journal(struct super_block * sb,
2082 return -EROFS; 2093 return -EROFS;
2083 } 2094 }
2084 2095
2085 if (!(journal = ext3_get_journal(sb, journal_inum))) 2096 journal = ext3_get_journal(sb, journal_inum);
2097 if (!journal)
2086 return -EINVAL; 2098 return -EINVAL;
2087 2099
2088 printk(KERN_INFO "EXT3-fs: creating new journal on inode %u\n", 2100 printk(KERN_INFO "EXT3-fs: creating new journal on inode %u\n",
2089 journal_inum); 2101 journal_inum);
2090 2102
2091 if (journal_create(journal)) { 2103 err = journal_create(journal);
2104 if (err) {
2092 printk(KERN_ERR "EXT3-fs: error creating journal.\n"); 2105 printk(KERN_ERR "EXT3-fs: error creating journal.\n");
2093 journal_destroy(journal); 2106 journal_destroy(journal);
2094 return -EIO; 2107 return -EIO;
@@ -2139,12 +2152,14 @@ static void ext3_mark_recovery_complete(struct super_block * sb,
2139 2152
2140 journal_lock_updates(journal); 2153 journal_lock_updates(journal);
2141 journal_flush(journal); 2154 journal_flush(journal);
2155 lock_super(sb);
2142 if (EXT3_HAS_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER) && 2156 if (EXT3_HAS_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER) &&
2143 sb->s_flags & MS_RDONLY) { 2157 sb->s_flags & MS_RDONLY) {
2144 EXT3_CLEAR_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER); 2158 EXT3_CLEAR_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER);
2145 sb->s_dirt = 0; 2159 sb->s_dirt = 0;
2146 ext3_commit_super(sb, es, 1); 2160 ext3_commit_super(sb, es, 1);
2147 } 2161 }
2162 unlock_super(sb);
2148 journal_unlock_updates(journal); 2163 journal_unlock_updates(journal);
2149} 2164}
2150 2165
@@ -2333,7 +2348,13 @@ static int ext3_remount (struct super_block * sb, int * flags, char * data)
2333 (sbi->s_mount_state & EXT3_VALID_FS)) 2348 (sbi->s_mount_state & EXT3_VALID_FS))
2334 es->s_state = cpu_to_le16(sbi->s_mount_state); 2349 es->s_state = cpu_to_le16(sbi->s_mount_state);
2335 2350
2351 /*
2352 * We have to unlock super so that we can wait for
2353 * transactions.
2354 */
2355 unlock_super(sb);
2336 ext3_mark_recovery_complete(sb, es); 2356 ext3_mark_recovery_complete(sb, es);
2357 lock_super(sb);
2337 } else { 2358 } else {
2338 __le32 ret; 2359 __le32 ret;
2339 if ((ret = EXT3_HAS_RO_COMPAT_FEATURE(sb, 2360 if ((ret = EXT3_HAS_RO_COMPAT_FEATURE(sb,
@@ -2406,19 +2427,19 @@ static int ext3_statfs (struct dentry * dentry, struct kstatfs * buf)
2406 struct super_block *sb = dentry->d_sb; 2427 struct super_block *sb = dentry->d_sb;
2407 struct ext3_sb_info *sbi = EXT3_SB(sb); 2428 struct ext3_sb_info *sbi = EXT3_SB(sb);
2408 struct ext3_super_block *es = sbi->s_es; 2429 struct ext3_super_block *es = sbi->s_es;
2409 ext3_fsblk_t overhead;
2410 int i;
2411 u64 fsid; 2430 u64 fsid;
2412 2431
2413 if (test_opt (sb, MINIX_DF)) 2432 if (test_opt(sb, MINIX_DF)) {
2414 overhead = 0; 2433 sbi->s_overhead_last = 0;
2415 else { 2434 } else if (sbi->s_blocks_last != le32_to_cpu(es->s_blocks_count)) {
2416 unsigned long ngroups; 2435 unsigned long ngroups = sbi->s_groups_count, i;
2417 ngroups = EXT3_SB(sb)->s_groups_count; 2436 ext3_fsblk_t overhead = 0;
2418 smp_rmb(); 2437 smp_rmb();
2419 2438
2420 /* 2439 /*
2421 * Compute the overhead (FS structures) 2440 * Compute the overhead (FS structures). This is constant
2441 * for a given filesystem unless the number of block groups
2442 * changes so we cache the previous value until it does.
2422 */ 2443 */
2423 2444
2424 /* 2445 /*
@@ -2442,18 +2463,23 @@ static int ext3_statfs (struct dentry * dentry, struct kstatfs * buf)
2442 * Every block group has an inode bitmap, a block 2463 * Every block group has an inode bitmap, a block
2443 * bitmap, and an inode table. 2464 * bitmap, and an inode table.
2444 */ 2465 */
2445 overhead += (ngroups * (2 + EXT3_SB(sb)->s_itb_per_group)); 2466 overhead += ngroups * (2 + sbi->s_itb_per_group);
2467 sbi->s_overhead_last = overhead;
2468 smp_wmb();
2469 sbi->s_blocks_last = le32_to_cpu(es->s_blocks_count);
2446 } 2470 }
2447 2471
2448 buf->f_type = EXT3_SUPER_MAGIC; 2472 buf->f_type = EXT3_SUPER_MAGIC;
2449 buf->f_bsize = sb->s_blocksize; 2473 buf->f_bsize = sb->s_blocksize;
2450 buf->f_blocks = le32_to_cpu(es->s_blocks_count) - overhead; 2474 buf->f_blocks = le32_to_cpu(es->s_blocks_count) - sbi->s_overhead_last;
2451 buf->f_bfree = percpu_counter_sum(&sbi->s_freeblocks_counter); 2475 buf->f_bfree = percpu_counter_sum(&sbi->s_freeblocks_counter);
2476 es->s_free_blocks_count = cpu_to_le32(buf->f_bfree);
2452 buf->f_bavail = buf->f_bfree - le32_to_cpu(es->s_r_blocks_count); 2477 buf->f_bavail = buf->f_bfree - le32_to_cpu(es->s_r_blocks_count);
2453 if (buf->f_bfree < le32_to_cpu(es->s_r_blocks_count)) 2478 if (buf->f_bfree < le32_to_cpu(es->s_r_blocks_count))
2454 buf->f_bavail = 0; 2479 buf->f_bavail = 0;
2455 buf->f_files = le32_to_cpu(es->s_inodes_count); 2480 buf->f_files = le32_to_cpu(es->s_inodes_count);
2456 buf->f_ffree = percpu_counter_sum(&sbi->s_freeinodes_counter); 2481 buf->f_ffree = percpu_counter_sum(&sbi->s_freeinodes_counter);
2482 es->s_free_inodes_count = cpu_to_le32(buf->f_ffree);
2457 buf->f_namelen = EXT3_NAME_LEN; 2483 buf->f_namelen = EXT3_NAME_LEN;
2458 fsid = le64_to_cpup((void *)es->s_uuid) ^ 2484 fsid = le64_to_cpup((void *)es->s_uuid) ^
2459 le64_to_cpup((void *)es->s_uuid + sizeof(u64)); 2485 le64_to_cpup((void *)es->s_uuid + sizeof(u64));