aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4/super.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ext4/super.c')
-rw-r--r--fs/ext4/super.c96
1 files changed, 68 insertions, 28 deletions
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 1d12e4f7d69f..b91dffd7a031 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -62,6 +62,43 @@ static void ext4_unlockfs(struct super_block *sb);
62static void ext4_write_super (struct super_block * sb); 62static void ext4_write_super (struct super_block * sb);
63static void ext4_write_super_lockfs(struct super_block *sb); 63static void ext4_write_super_lockfs(struct super_block *sb);
64 64
65
66ext4_fsblk_t ext4_block_bitmap(struct ext4_group_desc *bg)
67{
68 return le32_to_cpu(bg->bg_block_bitmap) |
69 ((ext4_fsblk_t)le16_to_cpu(bg->bg_block_bitmap_hi) << 32);
70}
71
72ext4_fsblk_t ext4_inode_bitmap(struct ext4_group_desc *bg)
73{
74 return le32_to_cpu(bg->bg_inode_bitmap) |
75 ((ext4_fsblk_t)le16_to_cpu(bg->bg_inode_bitmap_hi) << 32);
76}
77
78ext4_fsblk_t ext4_inode_table(struct ext4_group_desc *bg)
79{
80 return le32_to_cpu(bg->bg_inode_table) |
81 ((ext4_fsblk_t)le16_to_cpu(bg->bg_inode_table_hi) << 32);
82}
83
84void ext4_block_bitmap_set(struct ext4_group_desc *bg, ext4_fsblk_t blk)
85{
86 bg->bg_block_bitmap = cpu_to_le32((u32)blk);
87 bg->bg_block_bitmap_hi = cpu_to_le16(blk >> 32);
88}
89
90void ext4_inode_bitmap_set(struct ext4_group_desc *bg, ext4_fsblk_t blk)
91{
92 bg->bg_inode_bitmap = cpu_to_le32((u32)blk);
93 bg->bg_inode_bitmap_hi = cpu_to_le16(blk >> 32);
94}
95
96void ext4_inode_table_set(struct ext4_group_desc *bg, ext4_fsblk_t blk)
97{
98 bg->bg_inode_table = cpu_to_le32((u32)blk);
99 bg->bg_inode_table_hi = cpu_to_le16(blk >> 32);
100}
101
65/* 102/*
66 * Wrappers for jbd2_journal_start/end. 103 * Wrappers for jbd2_journal_start/end.
67 * 104 *
@@ -1182,6 +1219,9 @@ static int ext4_check_descriptors (struct super_block * sb)
1182 struct ext4_sb_info *sbi = EXT4_SB(sb); 1219 struct ext4_sb_info *sbi = EXT4_SB(sb);
1183 ext4_fsblk_t first_block = le32_to_cpu(sbi->s_es->s_first_data_block); 1220 ext4_fsblk_t first_block = le32_to_cpu(sbi->s_es->s_first_data_block);
1184 ext4_fsblk_t last_block; 1221 ext4_fsblk_t last_block;
1222 ext4_fsblk_t block_bitmap;
1223 ext4_fsblk_t inode_bitmap;
1224 ext4_fsblk_t inode_table;
1185 struct ext4_group_desc * gdp = NULL; 1225 struct ext4_group_desc * gdp = NULL;
1186 int desc_block = 0; 1226 int desc_block = 0;
1187 int i; 1227 int i;
@@ -1191,7 +1231,7 @@ static int ext4_check_descriptors (struct super_block * sb)
1191 for (i = 0; i < sbi->s_groups_count; i++) 1231 for (i = 0; i < sbi->s_groups_count; i++)
1192 { 1232 {
1193 if (i == sbi->s_groups_count - 1) 1233 if (i == sbi->s_groups_count - 1)
1194 last_block = le32_to_cpu(sbi->s_es->s_blocks_count) - 1; 1234 last_block = ext4_blocks_count(sbi->s_es) - 1;
1195 else 1235 else
1196 last_block = first_block + 1236 last_block = first_block +
1197 (EXT4_BLOCKS_PER_GROUP(sb) - 1); 1237 (EXT4_BLOCKS_PER_GROUP(sb) - 1);
@@ -1199,42 +1239,39 @@ static int ext4_check_descriptors (struct super_block * sb)
1199 if ((i % EXT4_DESC_PER_BLOCK(sb)) == 0) 1239 if ((i % EXT4_DESC_PER_BLOCK(sb)) == 0)
1200 gdp = (struct ext4_group_desc *) 1240 gdp = (struct ext4_group_desc *)
1201 sbi->s_group_desc[desc_block++]->b_data; 1241 sbi->s_group_desc[desc_block++]->b_data;
1202 if (le32_to_cpu(gdp->bg_block_bitmap) < first_block || 1242 block_bitmap = ext4_block_bitmap(gdp);
1203 le32_to_cpu(gdp->bg_block_bitmap) > last_block) 1243 if (block_bitmap < first_block || block_bitmap > last_block)
1204 { 1244 {
1205 ext4_error (sb, "ext4_check_descriptors", 1245 ext4_error (sb, "ext4_check_descriptors",
1206 "Block bitmap for group %d" 1246 "Block bitmap for group %d"
1207 " not in group (block %lu)!", 1247 " not in group (block "E3FSBLK")!",
1208 i, (unsigned long) 1248 i, block_bitmap);
1209 le32_to_cpu(gdp->bg_block_bitmap));
1210 return 0; 1249 return 0;
1211 } 1250 }
1212 if (le32_to_cpu(gdp->bg_inode_bitmap) < first_block || 1251 inode_bitmap = ext4_inode_bitmap(gdp);
1213 le32_to_cpu(gdp->bg_inode_bitmap) > last_block) 1252 if (inode_bitmap < first_block || inode_bitmap > last_block)
1214 { 1253 {
1215 ext4_error (sb, "ext4_check_descriptors", 1254 ext4_error (sb, "ext4_check_descriptors",
1216 "Inode bitmap for group %d" 1255 "Inode bitmap for group %d"
1217 " not in group (block %lu)!", 1256 " not in group (block "E3FSBLK")!",
1218 i, (unsigned long) 1257 i, inode_bitmap);
1219 le32_to_cpu(gdp->bg_inode_bitmap));
1220 return 0; 1258 return 0;
1221 } 1259 }
1222 if (le32_to_cpu(gdp->bg_inode_table) < first_block || 1260 inode_table = ext4_inode_table(gdp);
1223 le32_to_cpu(gdp->bg_inode_table) + sbi->s_itb_per_group > 1261 if (inode_table < first_block ||
1224 last_block) 1262 inode_table + sbi->s_itb_per_group > last_block)
1225 { 1263 {
1226 ext4_error (sb, "ext4_check_descriptors", 1264 ext4_error (sb, "ext4_check_descriptors",
1227 "Inode table for group %d" 1265 "Inode table for group %d"
1228 " not in group (block %lu)!", 1266 " not in group (block "E3FSBLK")!",
1229 i, (unsigned long) 1267 i, inode_table);
1230 le32_to_cpu(gdp->bg_inode_table));
1231 return 0; 1268 return 0;
1232 } 1269 }
1233 first_block += EXT4_BLOCKS_PER_GROUP(sb); 1270 first_block += EXT4_BLOCKS_PER_GROUP(sb);
1234 gdp++; 1271 gdp++;
1235 } 1272 }
1236 1273
1237 sbi->s_es->s_free_blocks_count=cpu_to_le32(ext4_count_free_blocks(sb)); 1274 ext4_free_blocks_count_set(sbi->s_es, ext4_count_free_blocks(sb));
1238 sbi->s_es->s_free_inodes_count=cpu_to_le32(ext4_count_free_inodes(sb)); 1275 sbi->s_es->s_free_inodes_count=cpu_to_le32(ext4_count_free_inodes(sb));
1239 return 1; 1276 return 1;
1240} 1277}
@@ -1411,6 +1448,7 @@ static int ext4_fill_super (struct super_block *sb, void *data, int silent)
1411 int i; 1448 int i;
1412 int needs_recovery; 1449 int needs_recovery;
1413 __le32 features; 1450 __le32 features;
1451 __u64 blocks_count;
1414 1452
1415 sbi = kzalloc(sizeof(*sbi), GFP_KERNEL); 1453 sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
1416 if (!sbi) 1454 if (!sbi)
@@ -1620,7 +1658,7 @@ static int ext4_fill_super (struct super_block *sb, void *data, int silent)
1620 goto failed_mount; 1658 goto failed_mount;
1621 } 1659 }
1622 1660
1623 if (le32_to_cpu(es->s_blocks_count) > 1661 if (ext4_blocks_count(es) >
1624 (sector_t)(~0ULL) >> (sb->s_blocksize_bits - 9)) { 1662 (sector_t)(~0ULL) >> (sb->s_blocksize_bits - 9)) {
1625 printk(KERN_ERR "EXT4-fs: filesystem on %s:" 1663 printk(KERN_ERR "EXT4-fs: filesystem on %s:"
1626 " too large to mount safely\n", sb->s_id); 1664 " too large to mount safely\n", sb->s_id);
@@ -1632,9 +1670,11 @@ static int ext4_fill_super (struct super_block *sb, void *data, int silent)
1632 1670
1633 if (EXT4_BLOCKS_PER_GROUP(sb) == 0) 1671 if (EXT4_BLOCKS_PER_GROUP(sb) == 0)
1634 goto cantfind_ext4; 1672 goto cantfind_ext4;
1635 sbi->s_groups_count = ((le32_to_cpu(es->s_blocks_count) - 1673 blocks_count = (ext4_blocks_count(es) -
1636 le32_to_cpu(es->s_first_data_block) - 1) 1674 le32_to_cpu(es->s_first_data_block) +
1637 / EXT4_BLOCKS_PER_GROUP(sb)) + 1; 1675 EXT4_BLOCKS_PER_GROUP(sb) - 1);
1676 do_div(blocks_count, EXT4_BLOCKS_PER_GROUP(sb));
1677 sbi->s_groups_count = blocks_count;
1638 db_count = (sbi->s_groups_count + EXT4_DESC_PER_BLOCK(sb) - 1) / 1678 db_count = (sbi->s_groups_count + EXT4_DESC_PER_BLOCK(sb) - 1) /
1639 EXT4_DESC_PER_BLOCK(sb); 1679 EXT4_DESC_PER_BLOCK(sb);
1640 sbi->s_group_desc = kmalloc(db_count * sizeof (struct buffer_head *), 1680 sbi->s_group_desc = kmalloc(db_count * sizeof (struct buffer_head *),
@@ -1949,7 +1989,7 @@ static journal_t *ext4_get_dev_journal(struct super_block *sb,
1949 goto out_bdev; 1989 goto out_bdev;
1950 } 1990 }
1951 1991
1952 len = le32_to_cpu(es->s_blocks_count); 1992 len = ext4_blocks_count(es);
1953 start = sb_block + 1; 1993 start = sb_block + 1;
1954 brelse(bh); /* we're done with the superblock */ 1994 brelse(bh); /* we're done with the superblock */
1955 1995
@@ -2119,7 +2159,7 @@ static void ext4_commit_super (struct super_block * sb,
2119 if (!sbh) 2159 if (!sbh)
2120 return; 2160 return;
2121 es->s_wtime = cpu_to_le32(get_seconds()); 2161 es->s_wtime = cpu_to_le32(get_seconds());
2122 es->s_free_blocks_count = cpu_to_le32(ext4_count_free_blocks(sb)); 2162 ext4_free_blocks_count_set(es, ext4_count_free_blocks(sb));
2123 es->s_free_inodes_count = cpu_to_le32(ext4_count_free_inodes(sb)); 2163 es->s_free_inodes_count = cpu_to_le32(ext4_count_free_inodes(sb));
2124 BUFFER_TRACE(sbh, "marking dirty"); 2164 BUFFER_TRACE(sbh, "marking dirty");
2125 mark_buffer_dirty(sbh); 2165 mark_buffer_dirty(sbh);
@@ -2312,7 +2352,7 @@ static int ext4_remount (struct super_block * sb, int * flags, char * data)
2312 ext4_init_journal_params(sb, sbi->s_journal); 2352 ext4_init_journal_params(sb, sbi->s_journal);
2313 2353
2314 if ((*flags & MS_RDONLY) != (sb->s_flags & MS_RDONLY) || 2354 if ((*flags & MS_RDONLY) != (sb->s_flags & MS_RDONLY) ||
2315 n_blocks_count > le32_to_cpu(es->s_blocks_count)) { 2355 n_blocks_count > ext4_blocks_count(es)) {
2316 if (sbi->s_mount_opt & EXT4_MOUNT_ABORT) { 2356 if (sbi->s_mount_opt & EXT4_MOUNT_ABORT) {
2317 err = -EROFS; 2357 err = -EROFS;
2318 goto restore_opts; 2358 goto restore_opts;
@@ -2431,10 +2471,10 @@ static int ext4_statfs (struct dentry * dentry, struct kstatfs * buf)
2431 2471
2432 buf->f_type = EXT4_SUPER_MAGIC; 2472 buf->f_type = EXT4_SUPER_MAGIC;
2433 buf->f_bsize = sb->s_blocksize; 2473 buf->f_bsize = sb->s_blocksize;
2434 buf->f_blocks = le32_to_cpu(es->s_blocks_count) - overhead; 2474 buf->f_blocks = ext4_blocks_count(es) - overhead;
2435 buf->f_bfree = percpu_counter_sum(&sbi->s_freeblocks_counter); 2475 buf->f_bfree = percpu_counter_sum(&sbi->s_freeblocks_counter);
2436 buf->f_bavail = buf->f_bfree - le32_to_cpu(es->s_r_blocks_count); 2476 buf->f_bavail = buf->f_bfree - ext4_r_blocks_count(es);
2437 if (buf->f_bfree < le32_to_cpu(es->s_r_blocks_count)) 2477 if (buf->f_bfree < ext4_r_blocks_count(es))
2438 buf->f_bavail = 0; 2478 buf->f_bavail = 0;
2439 buf->f_files = le32_to_cpu(es->s_inodes_count); 2479 buf->f_files = le32_to_cpu(es->s_inodes_count);
2440 buf->f_ffree = percpu_counter_sum(&sbi->s_freeinodes_counter); 2480 buf->f_ffree = percpu_counter_sum(&sbi->s_freeinodes_counter);