diff options
Diffstat (limited to 'fs/ext4/super.c')
-rw-r--r-- | fs/ext4/super.c | 48 |
1 files changed, 36 insertions, 12 deletions
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 175b68c60968..d0d8c76c7edb 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
@@ -510,6 +510,14 @@ static struct inode *ext4_alloc_inode(struct super_block *sb) | |||
510 | 510 | ||
511 | static void ext4_destroy_inode(struct inode *inode) | 511 | static void ext4_destroy_inode(struct inode *inode) |
512 | { | 512 | { |
513 | if (!list_empty(&(EXT4_I(inode)->i_orphan))) { | ||
514 | printk("EXT4 Inode %p: orphan list check failed!\n", | ||
515 | EXT4_I(inode)); | ||
516 | print_hex_dump(KERN_INFO, "", DUMP_PREFIX_ADDRESS, 16, 4, | ||
517 | EXT4_I(inode), sizeof(struct ext4_inode_info), | ||
518 | true); | ||
519 | dump_stack(); | ||
520 | } | ||
513 | kmem_cache_free(ext4_inode_cachep, EXT4_I(inode)); | 521 | kmem_cache_free(ext4_inode_cachep, EXT4_I(inode)); |
514 | } | 522 | } |
515 | 523 | ||
@@ -2150,6 +2158,7 @@ static int ext4_create_journal(struct super_block * sb, | |||
2150 | unsigned int journal_inum) | 2158 | unsigned int journal_inum) |
2151 | { | 2159 | { |
2152 | journal_t *journal; | 2160 | journal_t *journal; |
2161 | int err; | ||
2153 | 2162 | ||
2154 | if (sb->s_flags & MS_RDONLY) { | 2163 | if (sb->s_flags & MS_RDONLY) { |
2155 | printk(KERN_ERR "EXT4-fs: readonly filesystem when trying to " | 2164 | printk(KERN_ERR "EXT4-fs: readonly filesystem when trying to " |
@@ -2157,13 +2166,15 @@ static int ext4_create_journal(struct super_block * sb, | |||
2157 | return -EROFS; | 2166 | return -EROFS; |
2158 | } | 2167 | } |
2159 | 2168 | ||
2160 | if (!(journal = ext4_get_journal(sb, journal_inum))) | 2169 | journal = ext4_get_journal(sb, journal_inum); |
2170 | if (!journal) | ||
2161 | return -EINVAL; | 2171 | return -EINVAL; |
2162 | 2172 | ||
2163 | printk(KERN_INFO "EXT4-fs: creating new journal on inode %u\n", | 2173 | printk(KERN_INFO "EXT4-fs: creating new journal on inode %u\n", |
2164 | journal_inum); | 2174 | journal_inum); |
2165 | 2175 | ||
2166 | if (jbd2_journal_create(journal)) { | 2176 | err = jbd2_journal_create(journal); |
2177 | if (err) { | ||
2167 | printk(KERN_ERR "EXT4-fs: error creating journal.\n"); | 2178 | printk(KERN_ERR "EXT4-fs: error creating journal.\n"); |
2168 | jbd2_journal_destroy(journal); | 2179 | jbd2_journal_destroy(journal); |
2169 | return -EIO; | 2180 | return -EIO; |
@@ -2214,12 +2225,14 @@ static void ext4_mark_recovery_complete(struct super_block * sb, | |||
2214 | 2225 | ||
2215 | jbd2_journal_lock_updates(journal); | 2226 | jbd2_journal_lock_updates(journal); |
2216 | jbd2_journal_flush(journal); | 2227 | jbd2_journal_flush(journal); |
2228 | lock_super(sb); | ||
2217 | if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER) && | 2229 | if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER) && |
2218 | sb->s_flags & MS_RDONLY) { | 2230 | sb->s_flags & MS_RDONLY) { |
2219 | EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER); | 2231 | EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER); |
2220 | sb->s_dirt = 0; | 2232 | sb->s_dirt = 0; |
2221 | ext4_commit_super(sb, es, 1); | 2233 | ext4_commit_super(sb, es, 1); |
2222 | } | 2234 | } |
2235 | unlock_super(sb); | ||
2223 | jbd2_journal_unlock_updates(journal); | 2236 | jbd2_journal_unlock_updates(journal); |
2224 | } | 2237 | } |
2225 | 2238 | ||
@@ -2408,7 +2421,13 @@ static int ext4_remount (struct super_block * sb, int * flags, char * data) | |||
2408 | (sbi->s_mount_state & EXT4_VALID_FS)) | 2421 | (sbi->s_mount_state & EXT4_VALID_FS)) |
2409 | es->s_state = cpu_to_le16(sbi->s_mount_state); | 2422 | es->s_state = cpu_to_le16(sbi->s_mount_state); |
2410 | 2423 | ||
2424 | /* | ||
2425 | * We have to unlock super so that we can wait for | ||
2426 | * transactions. | ||
2427 | */ | ||
2428 | unlock_super(sb); | ||
2411 | ext4_mark_recovery_complete(sb, es); | 2429 | ext4_mark_recovery_complete(sb, es); |
2430 | lock_super(sb); | ||
2412 | } else { | 2431 | } else { |
2413 | __le32 ret; | 2432 | __le32 ret; |
2414 | if ((ret = EXT4_HAS_RO_COMPAT_FEATURE(sb, | 2433 | if ((ret = EXT4_HAS_RO_COMPAT_FEATURE(sb, |
@@ -2481,19 +2500,19 @@ static int ext4_statfs (struct dentry * dentry, struct kstatfs * buf) | |||
2481 | struct super_block *sb = dentry->d_sb; | 2500 | struct super_block *sb = dentry->d_sb; |
2482 | struct ext4_sb_info *sbi = EXT4_SB(sb); | 2501 | struct ext4_sb_info *sbi = EXT4_SB(sb); |
2483 | struct ext4_super_block *es = sbi->s_es; | 2502 | struct ext4_super_block *es = sbi->s_es; |
2484 | ext4_fsblk_t overhead; | ||
2485 | int i; | ||
2486 | u64 fsid; | 2503 | u64 fsid; |
2487 | 2504 | ||
2488 | if (test_opt (sb, MINIX_DF)) | 2505 | if (test_opt(sb, MINIX_DF)) { |
2489 | overhead = 0; | 2506 | sbi->s_overhead_last = 0; |
2490 | else { | 2507 | } else if (sbi->s_blocks_last != le32_to_cpu(es->s_blocks_count)) { |
2491 | unsigned long ngroups; | 2508 | unsigned long ngroups = sbi->s_groups_count, i; |
2492 | ngroups = EXT4_SB(sb)->s_groups_count; | 2509 | ext4_fsblk_t overhead = 0; |
2493 | smp_rmb(); | 2510 | smp_rmb(); |
2494 | 2511 | ||
2495 | /* | 2512 | /* |
2496 | * Compute the overhead (FS structures) | 2513 | * Compute the overhead (FS structures). This is constant |
2514 | * for a given filesystem unless the number of block groups | ||
2515 | * changes so we cache the previous value until it does. | ||
2497 | */ | 2516 | */ |
2498 | 2517 | ||
2499 | /* | 2518 | /* |
@@ -2517,18 +2536,23 @@ static int ext4_statfs (struct dentry * dentry, struct kstatfs * buf) | |||
2517 | * Every block group has an inode bitmap, a block | 2536 | * Every block group has an inode bitmap, a block |
2518 | * bitmap, and an inode table. | 2537 | * bitmap, and an inode table. |
2519 | */ | 2538 | */ |
2520 | overhead += (ngroups * (2 + EXT4_SB(sb)->s_itb_per_group)); | 2539 | overhead += ngroups * (2 + sbi->s_itb_per_group); |
2540 | sbi->s_overhead_last = overhead; | ||
2541 | smp_wmb(); | ||
2542 | sbi->s_blocks_last = le32_to_cpu(es->s_blocks_count); | ||
2521 | } | 2543 | } |
2522 | 2544 | ||
2523 | buf->f_type = EXT4_SUPER_MAGIC; | 2545 | buf->f_type = EXT4_SUPER_MAGIC; |
2524 | buf->f_bsize = sb->s_blocksize; | 2546 | buf->f_bsize = sb->s_blocksize; |
2525 | buf->f_blocks = ext4_blocks_count(es) - overhead; | 2547 | buf->f_blocks = ext4_blocks_count(es) - sbi->s_overhead_last; |
2526 | buf->f_bfree = percpu_counter_sum(&sbi->s_freeblocks_counter); | 2548 | buf->f_bfree = percpu_counter_sum(&sbi->s_freeblocks_counter); |
2549 | es->s_free_blocks_count = cpu_to_le32(buf->f_bfree); | ||
2527 | buf->f_bavail = buf->f_bfree - ext4_r_blocks_count(es); | 2550 | buf->f_bavail = buf->f_bfree - ext4_r_blocks_count(es); |
2528 | if (buf->f_bfree < ext4_r_blocks_count(es)) | 2551 | if (buf->f_bfree < ext4_r_blocks_count(es)) |
2529 | buf->f_bavail = 0; | 2552 | buf->f_bavail = 0; |
2530 | buf->f_files = le32_to_cpu(es->s_inodes_count); | 2553 | buf->f_files = le32_to_cpu(es->s_inodes_count); |
2531 | buf->f_ffree = percpu_counter_sum(&sbi->s_freeinodes_counter); | 2554 | buf->f_ffree = percpu_counter_sum(&sbi->s_freeinodes_counter); |
2555 | es->s_free_inodes_count = cpu_to_le32(buf->f_ffree); | ||
2532 | buf->f_namelen = EXT4_NAME_LEN; | 2556 | buf->f_namelen = EXT4_NAME_LEN; |
2533 | fsid = le64_to_cpup((void *)es->s_uuid) ^ | 2557 | fsid = le64_to_cpup((void *)es->s_uuid) ^ |
2534 | le64_to_cpup((void *)es->s_uuid + sizeof(u64)); | 2558 | le64_to_cpup((void *)es->s_uuid + sizeof(u64)); |