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