diff options
Diffstat (limited to 'fs/ext4/super.c')
| -rw-r--r-- | fs/ext4/super.c | 155 |
1 files changed, 88 insertions, 67 deletions
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 8f4f079e6b9a..a6b1ab734728 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
| @@ -45,6 +45,7 @@ | |||
| 45 | #include "ext4_jbd2.h" | 45 | #include "ext4_jbd2.h" |
| 46 | #include "xattr.h" | 46 | #include "xattr.h" |
| 47 | #include "acl.h" | 47 | #include "acl.h" |
| 48 | #include "mballoc.h" | ||
| 48 | 49 | ||
| 49 | #define CREATE_TRACE_POINTS | 50 | #define CREATE_TRACE_POINTS |
| 50 | #include <trace/events/ext4.h> | 51 | #include <trace/events/ext4.h> |
| @@ -344,7 +345,8 @@ static const char *ext4_decode_error(struct super_block *sb, int errno, | |||
| 344 | errstr = "Out of memory"; | 345 | errstr = "Out of memory"; |
| 345 | break; | 346 | break; |
| 346 | case -EROFS: | 347 | case -EROFS: |
| 347 | if (!sb || EXT4_SB(sb)->s_journal->j_flags & JBD2_ABORT) | 348 | if (!sb || (EXT4_SB(sb)->s_journal && |
| 349 | EXT4_SB(sb)->s_journal->j_flags & JBD2_ABORT)) | ||
| 348 | errstr = "Journal has aborted"; | 350 | errstr = "Journal has aborted"; |
| 349 | else | 351 | else |
| 350 | errstr = "Readonly filesystem"; | 352 | errstr = "Readonly filesystem"; |
| @@ -1279,11 +1281,9 @@ static int parse_options(char *options, struct super_block *sb, | |||
| 1279 | *journal_devnum = option; | 1281 | *journal_devnum = option; |
| 1280 | break; | 1282 | break; |
| 1281 | case Opt_journal_checksum: | 1283 | case Opt_journal_checksum: |
| 1282 | set_opt(sbi->s_mount_opt, JOURNAL_CHECKSUM); | 1284 | break; /* Kept for backwards compatibility */ |
| 1283 | break; | ||
| 1284 | case Opt_journal_async_commit: | 1285 | case Opt_journal_async_commit: |
| 1285 | set_opt(sbi->s_mount_opt, JOURNAL_ASYNC_COMMIT); | 1286 | set_opt(sbi->s_mount_opt, JOURNAL_ASYNC_COMMIT); |
| 1286 | set_opt(sbi->s_mount_opt, JOURNAL_CHECKSUM); | ||
| 1287 | break; | 1287 | break; |
| 1288 | case Opt_noload: | 1288 | case Opt_noload: |
| 1289 | set_opt(sbi->s_mount_opt, NOLOAD); | 1289 | set_opt(sbi->s_mount_opt, NOLOAD); |
| @@ -1695,12 +1695,12 @@ static int ext4_fill_flex_info(struct super_block *sb) | |||
| 1695 | gdp = ext4_get_group_desc(sb, i, NULL); | 1695 | gdp = ext4_get_group_desc(sb, i, NULL); |
| 1696 | 1696 | ||
| 1697 | flex_group = ext4_flex_group(sbi, i); | 1697 | flex_group = ext4_flex_group(sbi, i); |
| 1698 | atomic_set(&sbi->s_flex_groups[flex_group].free_inodes, | 1698 | atomic_add(ext4_free_inodes_count(sb, gdp), |
| 1699 | ext4_free_inodes_count(sb, gdp)); | 1699 | &sbi->s_flex_groups[flex_group].free_inodes); |
| 1700 | atomic_set(&sbi->s_flex_groups[flex_group].free_blocks, | 1700 | atomic_add(ext4_free_blks_count(sb, gdp), |
| 1701 | ext4_free_blks_count(sb, gdp)); | 1701 | &sbi->s_flex_groups[flex_group].free_blocks); |
| 1702 | atomic_set(&sbi->s_flex_groups[flex_group].used_dirs, | 1702 | atomic_add(ext4_used_dirs_count(sb, gdp), |
| 1703 | ext4_used_dirs_count(sb, gdp)); | 1703 | &sbi->s_flex_groups[flex_group].used_dirs); |
| 1704 | } | 1704 | } |
| 1705 | 1705 | ||
| 1706 | return 1; | 1706 | return 1; |
| @@ -2253,6 +2253,49 @@ static struct kobj_type ext4_ktype = { | |||
| 2253 | .release = ext4_sb_release, | 2253 | .release = ext4_sb_release, |
| 2254 | }; | 2254 | }; |
| 2255 | 2255 | ||
| 2256 | /* | ||
| 2257 | * Check whether this filesystem can be mounted based on | ||
| 2258 | * the features present and the RDONLY/RDWR mount requested. | ||
| 2259 | * Returns 1 if this filesystem can be mounted as requested, | ||
| 2260 | * 0 if it cannot be. | ||
| 2261 | */ | ||
| 2262 | static int ext4_feature_set_ok(struct super_block *sb, int readonly) | ||
| 2263 | { | ||
| 2264 | if (EXT4_HAS_INCOMPAT_FEATURE(sb, ~EXT4_FEATURE_INCOMPAT_SUPP)) { | ||
| 2265 | ext4_msg(sb, KERN_ERR, | ||
| 2266 | "Couldn't mount because of " | ||
| 2267 | "unsupported optional features (%x)", | ||
| 2268 | (le32_to_cpu(EXT4_SB(sb)->s_es->s_feature_incompat) & | ||
| 2269 | ~EXT4_FEATURE_INCOMPAT_SUPP)); | ||
| 2270 | return 0; | ||
| 2271 | } | ||
| 2272 | |||
| 2273 | if (readonly) | ||
| 2274 | return 1; | ||
| 2275 | |||
| 2276 | /* Check that feature set is OK for a read-write mount */ | ||
| 2277 | if (EXT4_HAS_RO_COMPAT_FEATURE(sb, ~EXT4_FEATURE_RO_COMPAT_SUPP)) { | ||
| 2278 | ext4_msg(sb, KERN_ERR, "couldn't mount RDWR because of " | ||
| 2279 | "unsupported optional features (%x)", | ||
| 2280 | (le32_to_cpu(EXT4_SB(sb)->s_es->s_feature_ro_compat) & | ||
| 2281 | ~EXT4_FEATURE_RO_COMPAT_SUPP)); | ||
| 2282 | return 0; | ||
| 2283 | } | ||
| 2284 | /* | ||
| 2285 | * Large file size enabled file system can only be mounted | ||
| 2286 | * read-write on 32-bit systems if kernel is built with CONFIG_LBDAF | ||
| 2287 | */ | ||
| 2288 | if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_HUGE_FILE)) { | ||
| 2289 | if (sizeof(blkcnt_t) < sizeof(u64)) { | ||
| 2290 | ext4_msg(sb, KERN_ERR, "Filesystem with huge files " | ||
| 2291 | "cannot be mounted RDWR without " | ||
| 2292 | "CONFIG_LBDAF"); | ||
| 2293 | return 0; | ||
| 2294 | } | ||
| 2295 | } | ||
| 2296 | return 1; | ||
| 2297 | } | ||
| 2298 | |||
| 2256 | static int ext4_fill_super(struct super_block *sb, void *data, int silent) | 2299 | static int ext4_fill_super(struct super_block *sb, void *data, int silent) |
| 2257 | __releases(kernel_lock) | 2300 | __releases(kernel_lock) |
| 2258 | __acquires(kernel_lock) | 2301 | __acquires(kernel_lock) |
| @@ -2274,7 +2317,6 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
| 2274 | unsigned int db_count; | 2317 | unsigned int db_count; |
| 2275 | unsigned int i; | 2318 | unsigned int i; |
| 2276 | int needs_recovery, has_huge_files; | 2319 | int needs_recovery, has_huge_files; |
| 2277 | int features; | ||
| 2278 | __u64 blocks_count; | 2320 | __u64 blocks_count; |
| 2279 | int err; | 2321 | int err; |
| 2280 | unsigned int journal_ioprio = DEFAULT_JOURNAL_IOPRIO; | 2322 | unsigned int journal_ioprio = DEFAULT_JOURNAL_IOPRIO; |
| @@ -2401,39 +2443,9 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
| 2401 | * previously didn't change the revision level when setting the flags, | 2443 | * previously didn't change the revision level when setting the flags, |
| 2402 | * so there is a chance incompat flags are set on a rev 0 filesystem. | 2444 | * so there is a chance incompat flags are set on a rev 0 filesystem. |
| 2403 | */ | 2445 | */ |
| 2404 | features = EXT4_HAS_INCOMPAT_FEATURE(sb, ~EXT4_FEATURE_INCOMPAT_SUPP); | 2446 | if (!ext4_feature_set_ok(sb, (sb->s_flags & MS_RDONLY))) |
| 2405 | if (features) { | ||
| 2406 | ext4_msg(sb, KERN_ERR, | ||
| 2407 | "Couldn't mount because of " | ||
| 2408 | "unsupported optional features (%x)", | ||
| 2409 | (le32_to_cpu(EXT4_SB(sb)->s_es->s_feature_incompat) & | ||
| 2410 | ~EXT4_FEATURE_INCOMPAT_SUPP)); | ||
| 2411 | goto failed_mount; | ||
| 2412 | } | ||
| 2413 | features = EXT4_HAS_RO_COMPAT_FEATURE(sb, ~EXT4_FEATURE_RO_COMPAT_SUPP); | ||
| 2414 | if (!(sb->s_flags & MS_RDONLY) && features) { | ||
| 2415 | ext4_msg(sb, KERN_ERR, | ||
| 2416 | "Couldn't mount RDWR because of " | ||
| 2417 | "unsupported optional features (%x)", | ||
| 2418 | (le32_to_cpu(EXT4_SB(sb)->s_es->s_feature_ro_compat) & | ||
| 2419 | ~EXT4_FEATURE_RO_COMPAT_SUPP)); | ||
| 2420 | goto failed_mount; | 2447 | goto failed_mount; |
| 2421 | } | 2448 | |
| 2422 | has_huge_files = EXT4_HAS_RO_COMPAT_FEATURE(sb, | ||
| 2423 | EXT4_FEATURE_RO_COMPAT_HUGE_FILE); | ||
| 2424 | if (has_huge_files) { | ||
| 2425 | /* | ||
| 2426 | * Large file size enabled file system can only be | ||
| 2427 | * mount if kernel is build with CONFIG_LBDAF | ||
| 2428 | */ | ||
| 2429 | if (sizeof(root->i_blocks) < sizeof(u64) && | ||
| 2430 | !(sb->s_flags & MS_RDONLY)) { | ||
| 2431 | ext4_msg(sb, KERN_ERR, "Filesystem with huge " | ||
| 2432 | "files cannot be mounted read-write " | ||
| 2433 | "without CONFIG_LBDAF"); | ||
| 2434 | goto failed_mount; | ||
| 2435 | } | ||
| 2436 | } | ||
| 2437 | blocksize = BLOCK_SIZE << le32_to_cpu(es->s_log_block_size); | 2449 | blocksize = BLOCK_SIZE << le32_to_cpu(es->s_log_block_size); |
| 2438 | 2450 | ||
| 2439 | if (blocksize < EXT4_MIN_BLOCK_SIZE || | 2451 | if (blocksize < EXT4_MIN_BLOCK_SIZE || |
| @@ -2469,6 +2481,8 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
| 2469 | } | 2481 | } |
| 2470 | } | 2482 | } |
| 2471 | 2483 | ||
| 2484 | has_huge_files = EXT4_HAS_RO_COMPAT_FEATURE(sb, | ||
| 2485 | EXT4_FEATURE_RO_COMPAT_HUGE_FILE); | ||
| 2472 | sbi->s_bitmap_maxbytes = ext4_max_bitmap_size(sb->s_blocksize_bits, | 2486 | sbi->s_bitmap_maxbytes = ext4_max_bitmap_size(sb->s_blocksize_bits, |
| 2473 | has_huge_files); | 2487 | has_huge_files); |
| 2474 | sb->s_maxbytes = ext4_max_size(sb->s_blocksize_bits, has_huge_files); | 2488 | sb->s_maxbytes = ext4_max_size(sb->s_blocksize_bits, has_huge_files); |
| @@ -2549,12 +2563,19 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
| 2549 | goto failed_mount; | 2563 | goto failed_mount; |
| 2550 | } | 2564 | } |
| 2551 | 2565 | ||
| 2552 | if (ext4_blocks_count(es) > | 2566 | /* |
| 2553 | (sector_t)(~0ULL) >> (sb->s_blocksize_bits - 9)) { | 2567 | * Test whether we have more sectors than will fit in sector_t, |
| 2568 | * and whether the max offset is addressable by the page cache. | ||
| 2569 | */ | ||
| 2570 | if ((ext4_blocks_count(es) > | ||
| 2571 | (sector_t)(~0ULL) >> (sb->s_blocksize_bits - 9)) || | ||
| 2572 | (ext4_blocks_count(es) > | ||
| 2573 | (pgoff_t)(~0ULL) >> (PAGE_CACHE_SHIFT - sb->s_blocksize_bits))) { | ||
| 2554 | ext4_msg(sb, KERN_ERR, "filesystem" | 2574 | ext4_msg(sb, KERN_ERR, "filesystem" |
| 2555 | " too large to mount safely"); | 2575 | " too large to mount safely on this system"); |
| 2556 | if (sizeof(sector_t) < 8) | 2576 | if (sizeof(sector_t) < 8) |
| 2557 | ext4_msg(sb, KERN_WARNING, "CONFIG_LBDAF not enabled"); | 2577 | ext4_msg(sb, KERN_WARNING, "CONFIG_LBDAF not enabled"); |
| 2578 | ret = -EFBIG; | ||
| 2558 | goto failed_mount; | 2579 | goto failed_mount; |
| 2559 | } | 2580 | } |
| 2560 | 2581 | ||
| @@ -2595,6 +2616,8 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
| 2595 | goto failed_mount; | 2616 | goto failed_mount; |
| 2596 | } | 2617 | } |
| 2597 | sbi->s_groups_count = blocks_count; | 2618 | sbi->s_groups_count = blocks_count; |
| 2619 | sbi->s_blockfile_groups = min_t(ext4_group_t, sbi->s_groups_count, | ||
| 2620 | (EXT4_MAX_BLOCK_FILE_PHYS / EXT4_BLOCKS_PER_GROUP(sb))); | ||
| 2598 | db_count = (sbi->s_groups_count + EXT4_DESC_PER_BLOCK(sb) - 1) / | 2621 | db_count = (sbi->s_groups_count + EXT4_DESC_PER_BLOCK(sb) - 1) / |
| 2599 | EXT4_DESC_PER_BLOCK(sb); | 2622 | EXT4_DESC_PER_BLOCK(sb); |
| 2600 | sbi->s_group_desc = kmalloc(db_count * sizeof(struct buffer_head *), | 2623 | sbi->s_group_desc = kmalloc(db_count * sizeof(struct buffer_head *), |
| @@ -2729,20 +2752,14 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
| 2729 | goto failed_mount4; | 2752 | goto failed_mount4; |
| 2730 | } | 2753 | } |
| 2731 | 2754 | ||
| 2732 | if (test_opt(sb, JOURNAL_ASYNC_COMMIT)) { | 2755 | jbd2_journal_set_features(sbi->s_journal, |
| 2733 | jbd2_journal_set_features(sbi->s_journal, | 2756 | JBD2_FEATURE_COMPAT_CHECKSUM, 0, 0); |
| 2734 | JBD2_FEATURE_COMPAT_CHECKSUM, 0, | 2757 | if (test_opt(sb, JOURNAL_ASYNC_COMMIT)) |
| 2758 | jbd2_journal_set_features(sbi->s_journal, 0, 0, | ||
| 2735 | JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT); | 2759 | JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT); |
| 2736 | } else if (test_opt(sb, JOURNAL_CHECKSUM)) { | 2760 | else |
| 2737 | jbd2_journal_set_features(sbi->s_journal, | ||
| 2738 | JBD2_FEATURE_COMPAT_CHECKSUM, 0, 0); | ||
| 2739 | jbd2_journal_clear_features(sbi->s_journal, 0, 0, | 2761 | jbd2_journal_clear_features(sbi->s_journal, 0, 0, |
| 2740 | JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT); | 2762 | JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT); |
| 2741 | } else { | ||
| 2742 | jbd2_journal_clear_features(sbi->s_journal, | ||
| 2743 | JBD2_FEATURE_COMPAT_CHECKSUM, 0, | ||
| 2744 | JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT); | ||
| 2745 | } | ||
| 2746 | 2763 | ||
| 2747 | /* We have now updated the journal if required, so we can | 2764 | /* We have now updated the journal if required, so we can |
| 2748 | * validate the data journaling mode. */ | 2765 | * validate the data journaling mode. */ |
| @@ -3208,7 +3225,18 @@ static int ext4_commit_super(struct super_block *sb, int sync) | |||
| 3208 | clear_buffer_write_io_error(sbh); | 3225 | clear_buffer_write_io_error(sbh); |
| 3209 | set_buffer_uptodate(sbh); | 3226 | set_buffer_uptodate(sbh); |
| 3210 | } | 3227 | } |
| 3211 | es->s_wtime = cpu_to_le32(get_seconds()); | 3228 | /* |
| 3229 | * If the file system is mounted read-only, don't update the | ||
| 3230 | * superblock write time. This avoids updating the superblock | ||
| 3231 | * write time when we are mounting the root file system | ||
| 3232 | * read/only but we need to replay the journal; at that point, | ||
| 3233 | * for people who are east of GMT and who make their clock | ||
| 3234 | * tick in localtime for Windows bug-for-bug compatibility, | ||
| 3235 | * the clock is set in the future, and this will cause e2fsck | ||
| 3236 | * to complain and force a full file system check. | ||
| 3237 | */ | ||
| 3238 | if (!(sb->s_flags & MS_RDONLY)) | ||
| 3239 | es->s_wtime = cpu_to_le32(get_seconds()); | ||
| 3212 | es->s_kbytes_written = | 3240 | es->s_kbytes_written = |
| 3213 | cpu_to_le64(EXT4_SB(sb)->s_kbytes_written + | 3241 | cpu_to_le64(EXT4_SB(sb)->s_kbytes_written + |
| 3214 | ((part_stat_read(sb->s_bdev->bd_part, sectors[1]) - | 3242 | ((part_stat_read(sb->s_bdev->bd_part, sectors[1]) - |
| @@ -3477,18 +3505,11 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data) | |||
| 3477 | if (sbi->s_journal) | 3505 | if (sbi->s_journal) |
| 3478 | ext4_mark_recovery_complete(sb, es); | 3506 | ext4_mark_recovery_complete(sb, es); |
| 3479 | } else { | 3507 | } else { |
| 3480 | int ret; | 3508 | /* Make sure we can mount this feature set readwrite */ |
| 3481 | if ((ret = EXT4_HAS_RO_COMPAT_FEATURE(sb, | 3509 | if (!ext4_feature_set_ok(sb, 0)) { |
| 3482 | ~EXT4_FEATURE_RO_COMPAT_SUPP))) { | ||
| 3483 | ext4_msg(sb, KERN_WARNING, "couldn't " | ||
| 3484 | "remount RDWR because of unsupported " | ||
| 3485 | "optional features (%x)", | ||
| 3486 | (le32_to_cpu(sbi->s_es->s_feature_ro_compat) & | ||
| 3487 | ~EXT4_FEATURE_RO_COMPAT_SUPP)); | ||
| 3488 | err = -EROFS; | 3510 | err = -EROFS; |
| 3489 | goto restore_opts; | 3511 | goto restore_opts; |
| 3490 | } | 3512 | } |
| 3491 | |||
| 3492 | /* | 3513 | /* |
| 3493 | * Make sure the group descriptor checksums | 3514 | * Make sure the group descriptor checksums |
| 3494 | * are sane. If they aren't, refuse to remount r/w. | 3515 | * are sane. If they aren't, refuse to remount r/w. |
