diff options
| -rw-r--r-- | fs/ext4/balloc.c | 21 | ||||
| -rw-r--r-- | fs/ext4/ext4.h | 9 | ||||
| -rw-r--r-- | fs/ext4/ext4_extents.h | 1 | ||||
| -rw-r--r-- | fs/ext4/extents.c | 6 | ||||
| -rw-r--r-- | fs/ext4/ialloc.c | 14 | ||||
| -rw-r--r-- | fs/ext4/inline.c | 39 | ||||
| -rw-r--r-- | fs/ext4/inode.c | 7 | ||||
| -rw-r--r-- | fs/ext4/mballoc.c | 6 | ||||
| -rw-r--r-- | fs/ext4/super.c | 99 | ||||
| -rw-r--r-- | fs/ext4/xattr.c | 40 | ||||
| -rw-r--r-- | fs/jbd2/transaction.c | 9 |
11 files changed, 155 insertions, 96 deletions
diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c index b00481c475cb..e68cefe08261 100644 --- a/fs/ext4/balloc.c +++ b/fs/ext4/balloc.c | |||
| @@ -184,7 +184,6 @@ static int ext4_init_block_bitmap(struct super_block *sb, | |||
| 184 | unsigned int bit, bit_max; | 184 | unsigned int bit, bit_max; |
| 185 | struct ext4_sb_info *sbi = EXT4_SB(sb); | 185 | struct ext4_sb_info *sbi = EXT4_SB(sb); |
| 186 | ext4_fsblk_t start, tmp; | 186 | ext4_fsblk_t start, tmp; |
| 187 | int flex_bg = 0; | ||
| 188 | 187 | ||
| 189 | J_ASSERT_BH(bh, buffer_locked(bh)); | 188 | J_ASSERT_BH(bh, buffer_locked(bh)); |
| 190 | 189 | ||
| @@ -207,22 +206,19 @@ static int ext4_init_block_bitmap(struct super_block *sb, | |||
| 207 | 206 | ||
| 208 | start = ext4_group_first_block_no(sb, block_group); | 207 | start = ext4_group_first_block_no(sb, block_group); |
| 209 | 208 | ||
| 210 | if (ext4_has_feature_flex_bg(sb)) | ||
| 211 | flex_bg = 1; | ||
| 212 | |||
| 213 | /* Set bits for block and inode bitmaps, and inode table */ | 209 | /* Set bits for block and inode bitmaps, and inode table */ |
| 214 | tmp = ext4_block_bitmap(sb, gdp); | 210 | tmp = ext4_block_bitmap(sb, gdp); |
| 215 | if (!flex_bg || ext4_block_in_group(sb, tmp, block_group)) | 211 | if (ext4_block_in_group(sb, tmp, block_group)) |
| 216 | ext4_set_bit(EXT4_B2C(sbi, tmp - start), bh->b_data); | 212 | ext4_set_bit(EXT4_B2C(sbi, tmp - start), bh->b_data); |
| 217 | 213 | ||
| 218 | tmp = ext4_inode_bitmap(sb, gdp); | 214 | tmp = ext4_inode_bitmap(sb, gdp); |
| 219 | if (!flex_bg || ext4_block_in_group(sb, tmp, block_group)) | 215 | if (ext4_block_in_group(sb, tmp, block_group)) |
| 220 | ext4_set_bit(EXT4_B2C(sbi, tmp - start), bh->b_data); | 216 | ext4_set_bit(EXT4_B2C(sbi, tmp - start), bh->b_data); |
| 221 | 217 | ||
| 222 | tmp = ext4_inode_table(sb, gdp); | 218 | tmp = ext4_inode_table(sb, gdp); |
| 223 | for (; tmp < ext4_inode_table(sb, gdp) + | 219 | for (; tmp < ext4_inode_table(sb, gdp) + |
| 224 | sbi->s_itb_per_group; tmp++) { | 220 | sbi->s_itb_per_group; tmp++) { |
| 225 | if (!flex_bg || ext4_block_in_group(sb, tmp, block_group)) | 221 | if (ext4_block_in_group(sb, tmp, block_group)) |
| 226 | ext4_set_bit(EXT4_B2C(sbi, tmp - start), bh->b_data); | 222 | ext4_set_bit(EXT4_B2C(sbi, tmp - start), bh->b_data); |
| 227 | } | 223 | } |
| 228 | 224 | ||
| @@ -442,7 +438,16 @@ ext4_read_block_bitmap_nowait(struct super_block *sb, ext4_group_t block_group) | |||
| 442 | goto verify; | 438 | goto verify; |
| 443 | } | 439 | } |
| 444 | ext4_lock_group(sb, block_group); | 440 | ext4_lock_group(sb, block_group); |
| 445 | if (desc->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) { | 441 | if (ext4_has_group_desc_csum(sb) && |
| 442 | (desc->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT))) { | ||
| 443 | if (block_group == 0) { | ||
| 444 | ext4_unlock_group(sb, block_group); | ||
| 445 | unlock_buffer(bh); | ||
| 446 | ext4_error(sb, "Block bitmap for bg 0 marked " | ||
| 447 | "uninitialized"); | ||
| 448 | err = -EFSCORRUPTED; | ||
| 449 | goto out; | ||
| 450 | } | ||
| 446 | err = ext4_init_block_bitmap(sb, bh, block_group, desc); | 451 | err = ext4_init_block_bitmap(sb, bh, block_group, desc); |
| 447 | set_bitmap_uptodate(bh); | 452 | set_bitmap_uptodate(bh); |
| 448 | set_buffer_uptodate(bh); | 453 | set_buffer_uptodate(bh); |
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 0b127853c584..7c7123f265c2 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h | |||
| @@ -1114,6 +1114,7 @@ struct ext4_inode_info { | |||
| 1114 | #define EXT4_MOUNT_DIOREAD_NOLOCK 0x400000 /* Enable support for dio read nolocking */ | 1114 | #define EXT4_MOUNT_DIOREAD_NOLOCK 0x400000 /* Enable support for dio read nolocking */ |
| 1115 | #define EXT4_MOUNT_JOURNAL_CHECKSUM 0x800000 /* Journal checksums */ | 1115 | #define EXT4_MOUNT_JOURNAL_CHECKSUM 0x800000 /* Journal checksums */ |
| 1116 | #define EXT4_MOUNT_JOURNAL_ASYNC_COMMIT 0x1000000 /* Journal Async Commit */ | 1116 | #define EXT4_MOUNT_JOURNAL_ASYNC_COMMIT 0x1000000 /* Journal Async Commit */ |
| 1117 | #define EXT4_MOUNT_WARN_ON_ERROR 0x2000000 /* Trigger WARN_ON on error */ | ||
| 1117 | #define EXT4_MOUNT_DELALLOC 0x8000000 /* Delalloc support */ | 1118 | #define EXT4_MOUNT_DELALLOC 0x8000000 /* Delalloc support */ |
| 1118 | #define EXT4_MOUNT_DATA_ERR_ABORT 0x10000000 /* Abort on file data write */ | 1119 | #define EXT4_MOUNT_DATA_ERR_ABORT 0x10000000 /* Abort on file data write */ |
| 1119 | #define EXT4_MOUNT_BLOCK_VALIDITY 0x20000000 /* Block validity checking */ | 1120 | #define EXT4_MOUNT_BLOCK_VALIDITY 0x20000000 /* Block validity checking */ |
| @@ -1507,11 +1508,6 @@ static inline struct ext4_inode_info *EXT4_I(struct inode *inode) | |||
| 1507 | static inline int ext4_valid_inum(struct super_block *sb, unsigned long ino) | 1508 | static inline int ext4_valid_inum(struct super_block *sb, unsigned long ino) |
| 1508 | { | 1509 | { |
| 1509 | return ino == EXT4_ROOT_INO || | 1510 | return ino == EXT4_ROOT_INO || |
| 1510 | ino == EXT4_USR_QUOTA_INO || | ||
| 1511 | ino == EXT4_GRP_QUOTA_INO || | ||
| 1512 | ino == EXT4_BOOT_LOADER_INO || | ||
| 1513 | ino == EXT4_JOURNAL_INO || | ||
| 1514 | ino == EXT4_RESIZE_INO || | ||
| 1515 | (ino >= EXT4_FIRST_INO(sb) && | 1511 | (ino >= EXT4_FIRST_INO(sb) && |
| 1516 | ino <= le32_to_cpu(EXT4_SB(sb)->s_es->s_inodes_count)); | 1512 | ino <= le32_to_cpu(EXT4_SB(sb)->s_es->s_inodes_count)); |
| 1517 | } | 1513 | } |
| @@ -3018,9 +3014,6 @@ extern int ext4_inline_data_fiemap(struct inode *inode, | |||
| 3018 | struct iomap; | 3014 | struct iomap; |
| 3019 | extern int ext4_inline_data_iomap(struct inode *inode, struct iomap *iomap); | 3015 | extern int ext4_inline_data_iomap(struct inode *inode, struct iomap *iomap); |
| 3020 | 3016 | ||
| 3021 | extern int ext4_try_to_evict_inline_data(handle_t *handle, | ||
| 3022 | struct inode *inode, | ||
| 3023 | int needed); | ||
| 3024 | extern int ext4_inline_data_truncate(struct inode *inode, int *has_inline); | 3017 | extern int ext4_inline_data_truncate(struct inode *inode, int *has_inline); |
| 3025 | 3018 | ||
| 3026 | extern int ext4_convert_inline_data(struct inode *inode); | 3019 | extern int ext4_convert_inline_data(struct inode *inode); |
diff --git a/fs/ext4/ext4_extents.h b/fs/ext4/ext4_extents.h index 98fb0c119c68..adf6668b596f 100644 --- a/fs/ext4/ext4_extents.h +++ b/fs/ext4/ext4_extents.h | |||
| @@ -91,6 +91,7 @@ struct ext4_extent_header { | |||
| 91 | }; | 91 | }; |
| 92 | 92 | ||
| 93 | #define EXT4_EXT_MAGIC cpu_to_le16(0xf30a) | 93 | #define EXT4_EXT_MAGIC cpu_to_le16(0xf30a) |
| 94 | #define EXT4_MAX_EXTENT_DEPTH 5 | ||
| 94 | 95 | ||
| 95 | #define EXT4_EXTENT_TAIL_OFFSET(hdr) \ | 96 | #define EXT4_EXTENT_TAIL_OFFSET(hdr) \ |
| 96 | (sizeof(struct ext4_extent_header) + \ | 97 | (sizeof(struct ext4_extent_header) + \ |
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 0057fe3f248d..8ce6fd5b10dd 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c | |||
| @@ -869,6 +869,12 @@ ext4_find_extent(struct inode *inode, ext4_lblk_t block, | |||
| 869 | 869 | ||
| 870 | eh = ext_inode_hdr(inode); | 870 | eh = ext_inode_hdr(inode); |
| 871 | depth = ext_depth(inode); | 871 | depth = ext_depth(inode); |
| 872 | if (depth < 0 || depth > EXT4_MAX_EXTENT_DEPTH) { | ||
| 873 | EXT4_ERROR_INODE(inode, "inode has invalid extent depth: %d", | ||
| 874 | depth); | ||
| 875 | ret = -EFSCORRUPTED; | ||
| 876 | goto err; | ||
| 877 | } | ||
| 872 | 878 | ||
| 873 | if (path) { | 879 | if (path) { |
| 874 | ext4_ext_drop_refs(path); | 880 | ext4_ext_drop_refs(path); |
diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c index f525f909b559..fb83750c1a14 100644 --- a/fs/ext4/ialloc.c +++ b/fs/ext4/ialloc.c | |||
| @@ -150,7 +150,16 @@ ext4_read_inode_bitmap(struct super_block *sb, ext4_group_t block_group) | |||
| 150 | } | 150 | } |
| 151 | 151 | ||
| 152 | ext4_lock_group(sb, block_group); | 152 | ext4_lock_group(sb, block_group); |
| 153 | if (desc->bg_flags & cpu_to_le16(EXT4_BG_INODE_UNINIT)) { | 153 | if (ext4_has_group_desc_csum(sb) && |
| 154 | (desc->bg_flags & cpu_to_le16(EXT4_BG_INODE_UNINIT))) { | ||
| 155 | if (block_group == 0) { | ||
| 156 | ext4_unlock_group(sb, block_group); | ||
| 157 | unlock_buffer(bh); | ||
| 158 | ext4_error(sb, "Inode bitmap for bg 0 marked " | ||
| 159 | "uninitialized"); | ||
| 160 | err = -EFSCORRUPTED; | ||
| 161 | goto out; | ||
| 162 | } | ||
| 154 | memset(bh->b_data, 0, (EXT4_INODES_PER_GROUP(sb) + 7) / 8); | 163 | memset(bh->b_data, 0, (EXT4_INODES_PER_GROUP(sb) + 7) / 8); |
| 155 | ext4_mark_bitmap_end(EXT4_INODES_PER_GROUP(sb), | 164 | ext4_mark_bitmap_end(EXT4_INODES_PER_GROUP(sb), |
| 156 | sb->s_blocksize * 8, bh->b_data); | 165 | sb->s_blocksize * 8, bh->b_data); |
| @@ -994,7 +1003,8 @@ got: | |||
| 994 | 1003 | ||
| 995 | /* recheck and clear flag under lock if we still need to */ | 1004 | /* recheck and clear flag under lock if we still need to */ |
| 996 | ext4_lock_group(sb, group); | 1005 | ext4_lock_group(sb, group); |
| 997 | if (gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) { | 1006 | if (ext4_has_group_desc_csum(sb) && |
| 1007 | (gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT))) { | ||
| 998 | gdp->bg_flags &= cpu_to_le16(~EXT4_BG_BLOCK_UNINIT); | 1008 | gdp->bg_flags &= cpu_to_le16(~EXT4_BG_BLOCK_UNINIT); |
| 999 | ext4_free_group_clusters_set(sb, gdp, | 1009 | ext4_free_group_clusters_set(sb, gdp, |
| 1000 | ext4_free_clusters_after_init(sb, group, gdp)); | 1010 | ext4_free_clusters_after_init(sb, group, gdp)); |
diff --git a/fs/ext4/inline.c b/fs/ext4/inline.c index 285ed1588730..e55a8bc870bd 100644 --- a/fs/ext4/inline.c +++ b/fs/ext4/inline.c | |||
| @@ -437,6 +437,7 @@ static int ext4_destroy_inline_data_nolock(handle_t *handle, | |||
| 437 | 437 | ||
| 438 | memset((void *)ext4_raw_inode(&is.iloc)->i_block, | 438 | memset((void *)ext4_raw_inode(&is.iloc)->i_block, |
| 439 | 0, EXT4_MIN_INLINE_DATA_SIZE); | 439 | 0, EXT4_MIN_INLINE_DATA_SIZE); |
| 440 | memset(ei->i_data, 0, EXT4_MIN_INLINE_DATA_SIZE); | ||
| 440 | 441 | ||
| 441 | if (ext4_has_feature_extents(inode->i_sb)) { | 442 | if (ext4_has_feature_extents(inode->i_sb)) { |
| 442 | if (S_ISDIR(inode->i_mode) || | 443 | if (S_ISDIR(inode->i_mode) || |
| @@ -886,11 +887,11 @@ retry_journal: | |||
| 886 | flags |= AOP_FLAG_NOFS; | 887 | flags |= AOP_FLAG_NOFS; |
| 887 | 888 | ||
| 888 | if (ret == -ENOSPC) { | 889 | if (ret == -ENOSPC) { |
| 890 | ext4_journal_stop(handle); | ||
| 889 | ret = ext4_da_convert_inline_data_to_extent(mapping, | 891 | ret = ext4_da_convert_inline_data_to_extent(mapping, |
| 890 | inode, | 892 | inode, |
| 891 | flags, | 893 | flags, |
| 892 | fsdata); | 894 | fsdata); |
| 893 | ext4_journal_stop(handle); | ||
| 894 | if (ret == -ENOSPC && | 895 | if (ret == -ENOSPC && |
| 895 | ext4_should_retry_alloc(inode->i_sb, &retries)) | 896 | ext4_should_retry_alloc(inode->i_sb, &retries)) |
| 896 | goto retry_journal; | 897 | goto retry_journal; |
| @@ -1890,42 +1891,6 @@ out: | |||
| 1890 | return (error < 0 ? error : 0); | 1891 | return (error < 0 ? error : 0); |
| 1891 | } | 1892 | } |
| 1892 | 1893 | ||
| 1893 | /* | ||
| 1894 | * Called during xattr set, and if we can sparse space 'needed', | ||
| 1895 | * just create the extent tree evict the data to the outer block. | ||
| 1896 | * | ||
| 1897 | * We use jbd2 instead of page cache to move data to the 1st block | ||
| 1898 | * so that the whole transaction can be committed as a whole and | ||
| 1899 | * the data isn't lost because of the delayed page cache write. | ||
| 1900 | */ | ||
| 1901 | int ext4_try_to_evict_inline_data(handle_t *handle, | ||
| 1902 | struct inode *inode, | ||
| 1903 | int needed) | ||
| 1904 | { | ||
| 1905 | int error; | ||
| 1906 | struct ext4_xattr_entry *entry; | ||
| 1907 | struct ext4_inode *raw_inode; | ||
| 1908 | struct ext4_iloc iloc; | ||
| 1909 | |||
| 1910 | error = ext4_get_inode_loc(inode, &iloc); | ||
| 1911 | if (error) | ||
| 1912 | return error; | ||
| 1913 | |||
| 1914 | raw_inode = ext4_raw_inode(&iloc); | ||
| 1915 | entry = (struct ext4_xattr_entry *)((void *)raw_inode + | ||
| 1916 | EXT4_I(inode)->i_inline_off); | ||
| 1917 | if (EXT4_XATTR_LEN(entry->e_name_len) + | ||
| 1918 | EXT4_XATTR_SIZE(le32_to_cpu(entry->e_value_size)) < needed) { | ||
| 1919 | error = -ENOSPC; | ||
| 1920 | goto out; | ||
| 1921 | } | ||
| 1922 | |||
| 1923 | error = ext4_convert_inline_data_nolock(handle, inode, &iloc); | ||
| 1924 | out: | ||
| 1925 | brelse(iloc.bh); | ||
| 1926 | return error; | ||
| 1927 | } | ||
| 1928 | |||
| 1929 | int ext4_inline_data_truncate(struct inode *inode, int *has_inline) | 1894 | int ext4_inline_data_truncate(struct inode *inode, int *has_inline) |
| 1930 | { | 1895 | { |
| 1931 | handle_t *handle; | 1896 | handle_t *handle; |
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 2ea07efbe016..7d6c10017bdf 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c | |||
| @@ -402,9 +402,9 @@ static int __check_block_validity(struct inode *inode, const char *func, | |||
| 402 | if (!ext4_data_block_valid(EXT4_SB(inode->i_sb), map->m_pblk, | 402 | if (!ext4_data_block_valid(EXT4_SB(inode->i_sb), map->m_pblk, |
| 403 | map->m_len)) { | 403 | map->m_len)) { |
| 404 | ext4_error_inode(inode, func, line, map->m_pblk, | 404 | ext4_error_inode(inode, func, line, map->m_pblk, |
| 405 | "lblock %lu mapped to illegal pblock " | 405 | "lblock %lu mapped to illegal pblock %llu " |
| 406 | "(length %d)", (unsigned long) map->m_lblk, | 406 | "(length %d)", (unsigned long) map->m_lblk, |
| 407 | map->m_len); | 407 | map->m_pblk, map->m_len); |
| 408 | return -EFSCORRUPTED; | 408 | return -EFSCORRUPTED; |
| 409 | } | 409 | } |
| 410 | return 0; | 410 | return 0; |
| @@ -4506,7 +4506,8 @@ static int __ext4_get_inode_loc(struct inode *inode, | |||
| 4506 | int inodes_per_block, inode_offset; | 4506 | int inodes_per_block, inode_offset; |
| 4507 | 4507 | ||
| 4508 | iloc->bh = NULL; | 4508 | iloc->bh = NULL; |
| 4509 | if (!ext4_valid_inum(sb, inode->i_ino)) | 4509 | if (inode->i_ino < EXT4_ROOT_INO || |
| 4510 | inode->i_ino > le32_to_cpu(EXT4_SB(sb)->s_es->s_inodes_count)) | ||
| 4510 | return -EFSCORRUPTED; | 4511 | return -EFSCORRUPTED; |
| 4511 | 4512 | ||
| 4512 | iloc->block_group = (inode->i_ino - 1) / EXT4_INODES_PER_GROUP(sb); | 4513 | iloc->block_group = (inode->i_ino - 1) / EXT4_INODES_PER_GROUP(sb); |
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index 6eae2b91aafa..f7ab34088162 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c | |||
| @@ -2423,7 +2423,8 @@ int ext4_mb_add_groupinfo(struct super_block *sb, ext4_group_t group, | |||
| 2423 | * initialize bb_free to be able to skip | 2423 | * initialize bb_free to be able to skip |
| 2424 | * empty groups without initialization | 2424 | * empty groups without initialization |
| 2425 | */ | 2425 | */ |
| 2426 | if (desc->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) { | 2426 | if (ext4_has_group_desc_csum(sb) && |
| 2427 | (desc->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT))) { | ||
| 2427 | meta_group_info[i]->bb_free = | 2428 | meta_group_info[i]->bb_free = |
| 2428 | ext4_free_clusters_after_init(sb, group, desc); | 2429 | ext4_free_clusters_after_init(sb, group, desc); |
| 2429 | } else { | 2430 | } else { |
| @@ -2989,7 +2990,8 @@ ext4_mb_mark_diskspace_used(struct ext4_allocation_context *ac, | |||
| 2989 | #endif | 2990 | #endif |
| 2990 | ext4_set_bits(bitmap_bh->b_data, ac->ac_b_ex.fe_start, | 2991 | ext4_set_bits(bitmap_bh->b_data, ac->ac_b_ex.fe_start, |
| 2991 | ac->ac_b_ex.fe_len); | 2992 | ac->ac_b_ex.fe_len); |
| 2992 | if (gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) { | 2993 | if (ext4_has_group_desc_csum(sb) && |
| 2994 | (gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT))) { | ||
| 2993 | gdp->bg_flags &= cpu_to_le16(~EXT4_BG_BLOCK_UNINIT); | 2995 | gdp->bg_flags &= cpu_to_le16(~EXT4_BG_BLOCK_UNINIT); |
| 2994 | ext4_free_group_clusters_set(sb, gdp, | 2996 | ext4_free_group_clusters_set(sb, gdp, |
| 2995 | ext4_free_clusters_after_init(sb, | 2997 | ext4_free_clusters_after_init(sb, |
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 0c4c2201b3aa..ba2396a7bd04 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
| @@ -405,6 +405,9 @@ static void ext4_journal_commit_callback(journal_t *journal, transaction_t *txn) | |||
| 405 | 405 | ||
| 406 | static void ext4_handle_error(struct super_block *sb) | 406 | static void ext4_handle_error(struct super_block *sb) |
| 407 | { | 407 | { |
| 408 | if (test_opt(sb, WARN_ON_ERROR)) | ||
| 409 | WARN_ON_ONCE(1); | ||
| 410 | |||
| 408 | if (sb_rdonly(sb)) | 411 | if (sb_rdonly(sb)) |
| 409 | return; | 412 | return; |
| 410 | 413 | ||
| @@ -740,6 +743,9 @@ __acquires(bitlock) | |||
| 740 | va_end(args); | 743 | va_end(args); |
| 741 | } | 744 | } |
| 742 | 745 | ||
| 746 | if (test_opt(sb, WARN_ON_ERROR)) | ||
| 747 | WARN_ON_ONCE(1); | ||
| 748 | |||
| 743 | if (test_opt(sb, ERRORS_CONT)) { | 749 | if (test_opt(sb, ERRORS_CONT)) { |
| 744 | ext4_commit_super(sb, 0); | 750 | ext4_commit_super(sb, 0); |
| 745 | return; | 751 | return; |
| @@ -1371,7 +1377,8 @@ enum { | |||
| 1371 | Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_jqfmt_vfsv1, Opt_quota, | 1377 | Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_jqfmt_vfsv1, Opt_quota, |
| 1372 | Opt_noquota, Opt_barrier, Opt_nobarrier, Opt_err, | 1378 | Opt_noquota, Opt_barrier, Opt_nobarrier, Opt_err, |
| 1373 | Opt_usrquota, Opt_grpquota, Opt_prjquota, Opt_i_version, Opt_dax, | 1379 | Opt_usrquota, Opt_grpquota, Opt_prjquota, Opt_i_version, Opt_dax, |
| 1374 | Opt_stripe, Opt_delalloc, Opt_nodelalloc, Opt_mblk_io_submit, | 1380 | Opt_stripe, Opt_delalloc, Opt_nodelalloc, Opt_warn_on_error, |
| 1381 | Opt_nowarn_on_error, Opt_mblk_io_submit, | ||
| 1375 | Opt_lazytime, Opt_nolazytime, Opt_debug_want_extra_isize, | 1382 | Opt_lazytime, Opt_nolazytime, Opt_debug_want_extra_isize, |
| 1376 | Opt_nomblk_io_submit, Opt_block_validity, Opt_noblock_validity, | 1383 | Opt_nomblk_io_submit, Opt_block_validity, Opt_noblock_validity, |
| 1377 | Opt_inode_readahead_blks, Opt_journal_ioprio, | 1384 | Opt_inode_readahead_blks, Opt_journal_ioprio, |
| @@ -1438,6 +1445,8 @@ static const match_table_t tokens = { | |||
| 1438 | {Opt_dax, "dax"}, | 1445 | {Opt_dax, "dax"}, |
| 1439 | {Opt_stripe, "stripe=%u"}, | 1446 | {Opt_stripe, "stripe=%u"}, |
| 1440 | {Opt_delalloc, "delalloc"}, | 1447 | {Opt_delalloc, "delalloc"}, |
| 1448 | {Opt_warn_on_error, "warn_on_error"}, | ||
| 1449 | {Opt_nowarn_on_error, "nowarn_on_error"}, | ||
| 1441 | {Opt_lazytime, "lazytime"}, | 1450 | {Opt_lazytime, "lazytime"}, |
| 1442 | {Opt_nolazytime, "nolazytime"}, | 1451 | {Opt_nolazytime, "nolazytime"}, |
| 1443 | {Opt_debug_want_extra_isize, "debug_want_extra_isize=%u"}, | 1452 | {Opt_debug_want_extra_isize, "debug_want_extra_isize=%u"}, |
| @@ -1602,6 +1611,8 @@ static const struct mount_opts { | |||
| 1602 | MOPT_EXT4_ONLY | MOPT_SET | MOPT_EXPLICIT}, | 1611 | MOPT_EXT4_ONLY | MOPT_SET | MOPT_EXPLICIT}, |
| 1603 | {Opt_nodelalloc, EXT4_MOUNT_DELALLOC, | 1612 | {Opt_nodelalloc, EXT4_MOUNT_DELALLOC, |
| 1604 | MOPT_EXT4_ONLY | MOPT_CLEAR}, | 1613 | MOPT_EXT4_ONLY | MOPT_CLEAR}, |
| 1614 | {Opt_warn_on_error, EXT4_MOUNT_WARN_ON_ERROR, MOPT_SET}, | ||
| 1615 | {Opt_nowarn_on_error, EXT4_MOUNT_WARN_ON_ERROR, MOPT_CLEAR}, | ||
| 1605 | {Opt_nojournal_checksum, EXT4_MOUNT_JOURNAL_CHECKSUM, | 1616 | {Opt_nojournal_checksum, EXT4_MOUNT_JOURNAL_CHECKSUM, |
| 1606 | MOPT_EXT4_ONLY | MOPT_CLEAR}, | 1617 | MOPT_EXT4_ONLY | MOPT_CLEAR}, |
| 1607 | {Opt_journal_checksum, EXT4_MOUNT_JOURNAL_CHECKSUM, | 1618 | {Opt_journal_checksum, EXT4_MOUNT_JOURNAL_CHECKSUM, |
| @@ -2331,6 +2342,7 @@ static int ext4_check_descriptors(struct super_block *sb, | |||
| 2331 | struct ext4_sb_info *sbi = EXT4_SB(sb); | 2342 | struct ext4_sb_info *sbi = EXT4_SB(sb); |
| 2332 | ext4_fsblk_t first_block = le32_to_cpu(sbi->s_es->s_first_data_block); | 2343 | ext4_fsblk_t first_block = le32_to_cpu(sbi->s_es->s_first_data_block); |
| 2333 | ext4_fsblk_t last_block; | 2344 | ext4_fsblk_t last_block; |
| 2345 | ext4_fsblk_t last_bg_block = sb_block + ext4_bg_num_gdb(sb, 0) + 1; | ||
| 2334 | ext4_fsblk_t block_bitmap; | 2346 | ext4_fsblk_t block_bitmap; |
| 2335 | ext4_fsblk_t inode_bitmap; | 2347 | ext4_fsblk_t inode_bitmap; |
| 2336 | ext4_fsblk_t inode_table; | 2348 | ext4_fsblk_t inode_table; |
| @@ -2363,6 +2375,14 @@ static int ext4_check_descriptors(struct super_block *sb, | |||
| 2363 | if (!sb_rdonly(sb)) | 2375 | if (!sb_rdonly(sb)) |
| 2364 | return 0; | 2376 | return 0; |
| 2365 | } | 2377 | } |
| 2378 | if (block_bitmap >= sb_block + 1 && | ||
| 2379 | block_bitmap <= last_bg_block) { | ||
| 2380 | ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: " | ||
| 2381 | "Block bitmap for group %u overlaps " | ||
| 2382 | "block group descriptors", i); | ||
| 2383 | if (!sb_rdonly(sb)) | ||
| 2384 | return 0; | ||
| 2385 | } | ||
| 2366 | if (block_bitmap < first_block || block_bitmap > last_block) { | 2386 | if (block_bitmap < first_block || block_bitmap > last_block) { |
| 2367 | ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: " | 2387 | ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: " |
| 2368 | "Block bitmap for group %u not in group " | 2388 | "Block bitmap for group %u not in group " |
| @@ -2377,6 +2397,14 @@ static int ext4_check_descriptors(struct super_block *sb, | |||
| 2377 | if (!sb_rdonly(sb)) | 2397 | if (!sb_rdonly(sb)) |
| 2378 | return 0; | 2398 | return 0; |
| 2379 | } | 2399 | } |
| 2400 | if (inode_bitmap >= sb_block + 1 && | ||
| 2401 | inode_bitmap <= last_bg_block) { | ||
| 2402 | ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: " | ||
| 2403 | "Inode bitmap for group %u overlaps " | ||
| 2404 | "block group descriptors", i); | ||
| 2405 | if (!sb_rdonly(sb)) | ||
| 2406 | return 0; | ||
| 2407 | } | ||
| 2380 | if (inode_bitmap < first_block || inode_bitmap > last_block) { | 2408 | if (inode_bitmap < first_block || inode_bitmap > last_block) { |
| 2381 | ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: " | 2409 | ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: " |
| 2382 | "Inode bitmap for group %u not in group " | 2410 | "Inode bitmap for group %u not in group " |
| @@ -2391,6 +2419,14 @@ static int ext4_check_descriptors(struct super_block *sb, | |||
| 2391 | if (!sb_rdonly(sb)) | 2419 | if (!sb_rdonly(sb)) |
| 2392 | return 0; | 2420 | return 0; |
| 2393 | } | 2421 | } |
| 2422 | if (inode_table >= sb_block + 1 && | ||
| 2423 | inode_table <= last_bg_block) { | ||
| 2424 | ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: " | ||
| 2425 | "Inode table for group %u overlaps " | ||
| 2426 | "block group descriptors", i); | ||
| 2427 | if (!sb_rdonly(sb)) | ||
| 2428 | return 0; | ||
| 2429 | } | ||
| 2394 | if (inode_table < first_block || | 2430 | if (inode_table < first_block || |
| 2395 | inode_table + sbi->s_itb_per_group - 1 > last_block) { | 2431 | inode_table + sbi->s_itb_per_group - 1 > last_block) { |
| 2396 | ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: " | 2432 | ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: " |
| @@ -3097,13 +3133,22 @@ static ext4_group_t ext4_has_uninit_itable(struct super_block *sb) | |||
| 3097 | ext4_group_t group, ngroups = EXT4_SB(sb)->s_groups_count; | 3133 | ext4_group_t group, ngroups = EXT4_SB(sb)->s_groups_count; |
| 3098 | struct ext4_group_desc *gdp = NULL; | 3134 | struct ext4_group_desc *gdp = NULL; |
| 3099 | 3135 | ||
| 3136 | if (!ext4_has_group_desc_csum(sb)) | ||
| 3137 | return ngroups; | ||
| 3138 | |||
| 3100 | for (group = 0; group < ngroups; group++) { | 3139 | for (group = 0; group < ngroups; group++) { |
| 3101 | gdp = ext4_get_group_desc(sb, group, NULL); | 3140 | gdp = ext4_get_group_desc(sb, group, NULL); |
| 3102 | if (!gdp) | 3141 | if (!gdp) |
| 3103 | continue; | 3142 | continue; |
| 3104 | 3143 | ||
| 3105 | if (!(gdp->bg_flags & cpu_to_le16(EXT4_BG_INODE_ZEROED))) | 3144 | if (gdp->bg_flags & cpu_to_le16(EXT4_BG_INODE_ZEROED)) |
| 3145 | continue; | ||
| 3146 | if (group != 0) | ||
| 3106 | break; | 3147 | break; |
| 3148 | ext4_error(sb, "Inode table for bg 0 marked as " | ||
| 3149 | "needing zeroing"); | ||
| 3150 | if (sb_rdonly(sb)) | ||
| 3151 | return ngroups; | ||
| 3107 | } | 3152 | } |
| 3108 | 3153 | ||
| 3109 | return group; | 3154 | return group; |
| @@ -3742,6 +3787,13 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
| 3742 | le32_to_cpu(es->s_log_block_size)); | 3787 | le32_to_cpu(es->s_log_block_size)); |
| 3743 | goto failed_mount; | 3788 | goto failed_mount; |
| 3744 | } | 3789 | } |
| 3790 | if (le32_to_cpu(es->s_log_cluster_size) > | ||
| 3791 | (EXT4_MAX_CLUSTER_LOG_SIZE - EXT4_MIN_BLOCK_LOG_SIZE)) { | ||
| 3792 | ext4_msg(sb, KERN_ERR, | ||
| 3793 | "Invalid log cluster size: %u", | ||
| 3794 | le32_to_cpu(es->s_log_cluster_size)); | ||
| 3795 | goto failed_mount; | ||
| 3796 | } | ||
| 3745 | 3797 | ||
| 3746 | if (le16_to_cpu(sbi->s_es->s_reserved_gdt_blocks) > (blocksize / 4)) { | 3798 | if (le16_to_cpu(sbi->s_es->s_reserved_gdt_blocks) > (blocksize / 4)) { |
| 3747 | ext4_msg(sb, KERN_ERR, | 3799 | ext4_msg(sb, KERN_ERR, |
| @@ -3806,6 +3858,11 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
| 3806 | } else { | 3858 | } else { |
| 3807 | sbi->s_inode_size = le16_to_cpu(es->s_inode_size); | 3859 | sbi->s_inode_size = le16_to_cpu(es->s_inode_size); |
| 3808 | sbi->s_first_ino = le32_to_cpu(es->s_first_ino); | 3860 | sbi->s_first_ino = le32_to_cpu(es->s_first_ino); |
| 3861 | if (sbi->s_first_ino < EXT4_GOOD_OLD_FIRST_INO) { | ||
| 3862 | ext4_msg(sb, KERN_ERR, "invalid first ino: %u", | ||
| 3863 | sbi->s_first_ino); | ||
| 3864 | goto failed_mount; | ||
| 3865 | } | ||
| 3809 | if ((sbi->s_inode_size < EXT4_GOOD_OLD_INODE_SIZE) || | 3866 | if ((sbi->s_inode_size < EXT4_GOOD_OLD_INODE_SIZE) || |
| 3810 | (!is_power_of_2(sbi->s_inode_size)) || | 3867 | (!is_power_of_2(sbi->s_inode_size)) || |
| 3811 | (sbi->s_inode_size > blocksize)) { | 3868 | (sbi->s_inode_size > blocksize)) { |
| @@ -3882,13 +3939,6 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
| 3882 | "block size (%d)", clustersize, blocksize); | 3939 | "block size (%d)", clustersize, blocksize); |
| 3883 | goto failed_mount; | 3940 | goto failed_mount; |
| 3884 | } | 3941 | } |
| 3885 | if (le32_to_cpu(es->s_log_cluster_size) > | ||
| 3886 | (EXT4_MAX_CLUSTER_LOG_SIZE - EXT4_MIN_BLOCK_LOG_SIZE)) { | ||
| 3887 | ext4_msg(sb, KERN_ERR, | ||
| 3888 | "Invalid log cluster size: %u", | ||
| 3889 | le32_to_cpu(es->s_log_cluster_size)); | ||
| 3890 | goto failed_mount; | ||
| 3891 | } | ||
| 3892 | sbi->s_cluster_bits = le32_to_cpu(es->s_log_cluster_size) - | 3942 | sbi->s_cluster_bits = le32_to_cpu(es->s_log_cluster_size) - |
| 3893 | le32_to_cpu(es->s_log_block_size); | 3943 | le32_to_cpu(es->s_log_block_size); |
| 3894 | sbi->s_clusters_per_group = | 3944 | sbi->s_clusters_per_group = |
| @@ -3909,10 +3959,10 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
| 3909 | } | 3959 | } |
| 3910 | } else { | 3960 | } else { |
| 3911 | if (clustersize != blocksize) { | 3961 | if (clustersize != blocksize) { |
| 3912 | ext4_warning(sb, "fragment/cluster size (%d) != " | 3962 | ext4_msg(sb, KERN_ERR, |
| 3913 | "block size (%d)", clustersize, | 3963 | "fragment/cluster size (%d) != " |
| 3914 | blocksize); | 3964 | "block size (%d)", clustersize, blocksize); |
| 3915 | clustersize = blocksize; | 3965 | goto failed_mount; |
| 3916 | } | 3966 | } |
| 3917 | if (sbi->s_blocks_per_group > blocksize * 8) { | 3967 | if (sbi->s_blocks_per_group > blocksize * 8) { |
| 3918 | ext4_msg(sb, KERN_ERR, | 3968 | ext4_msg(sb, KERN_ERR, |
| @@ -3966,6 +4016,13 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
| 3966 | ext4_blocks_count(es)); | 4016 | ext4_blocks_count(es)); |
| 3967 | goto failed_mount; | 4017 | goto failed_mount; |
| 3968 | } | 4018 | } |
| 4019 | if ((es->s_first_data_block == 0) && (es->s_log_block_size == 0) && | ||
| 4020 | (sbi->s_cluster_ratio == 1)) { | ||
| 4021 | ext4_msg(sb, KERN_WARNING, "bad geometry: first data " | ||
| 4022 | "block is 0 with a 1k block and cluster size"); | ||
| 4023 | goto failed_mount; | ||
| 4024 | } | ||
| 4025 | |||
| 3969 | blocks_count = (ext4_blocks_count(es) - | 4026 | blocks_count = (ext4_blocks_count(es) - |
| 3970 | le32_to_cpu(es->s_first_data_block) + | 4027 | le32_to_cpu(es->s_first_data_block) + |
| 3971 | EXT4_BLOCKS_PER_GROUP(sb) - 1); | 4028 | EXT4_BLOCKS_PER_GROUP(sb) - 1); |
| @@ -4001,6 +4058,14 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
| 4001 | ret = -ENOMEM; | 4058 | ret = -ENOMEM; |
| 4002 | goto failed_mount; | 4059 | goto failed_mount; |
| 4003 | } | 4060 | } |
| 4061 | if (((u64)sbi->s_groups_count * sbi->s_inodes_per_group) != | ||
| 4062 | le32_to_cpu(es->s_inodes_count)) { | ||
| 4063 | ext4_msg(sb, KERN_ERR, "inodes count not valid: %u vs %llu", | ||
| 4064 | le32_to_cpu(es->s_inodes_count), | ||
| 4065 | ((u64)sbi->s_groups_count * sbi->s_inodes_per_group)); | ||
| 4066 | ret = -EINVAL; | ||
| 4067 | goto failed_mount; | ||
| 4068 | } | ||
| 4004 | 4069 | ||
| 4005 | bgl_lock_init(sbi->s_blockgroup_lock); | 4070 | bgl_lock_init(sbi->s_blockgroup_lock); |
| 4006 | 4071 | ||
| @@ -4736,6 +4801,14 @@ static int ext4_commit_super(struct super_block *sb, int sync) | |||
| 4736 | 4801 | ||
| 4737 | if (!sbh || block_device_ejected(sb)) | 4802 | if (!sbh || block_device_ejected(sb)) |
| 4738 | return error; | 4803 | return error; |
| 4804 | |||
| 4805 | /* | ||
| 4806 | * The superblock bh should be mapped, but it might not be if the | ||
| 4807 | * device was hot-removed. Not much we can do but fail the I/O. | ||
| 4808 | */ | ||
| 4809 | if (!buffer_mapped(sbh)) | ||
| 4810 | return error; | ||
| 4811 | |||
| 4739 | /* | 4812 | /* |
| 4740 | * If the file system is mounted read-only, don't update the | 4813 | * If the file system is mounted read-only, don't update the |
| 4741 | * superblock write time. This avoids updating the superblock | 4814 | * superblock write time. This avoids updating the superblock |
diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c index fc4ced59c565..723df14f4084 100644 --- a/fs/ext4/xattr.c +++ b/fs/ext4/xattr.c | |||
| @@ -230,12 +230,12 @@ __ext4_xattr_check_block(struct inode *inode, struct buffer_head *bh, | |||
| 230 | { | 230 | { |
| 231 | int error = -EFSCORRUPTED; | 231 | int error = -EFSCORRUPTED; |
| 232 | 232 | ||
| 233 | if (buffer_verified(bh)) | ||
| 234 | return 0; | ||
| 235 | |||
| 236 | if (BHDR(bh)->h_magic != cpu_to_le32(EXT4_XATTR_MAGIC) || | 233 | if (BHDR(bh)->h_magic != cpu_to_le32(EXT4_XATTR_MAGIC) || |
| 237 | BHDR(bh)->h_blocks != cpu_to_le32(1)) | 234 | BHDR(bh)->h_blocks != cpu_to_le32(1)) |
| 238 | goto errout; | 235 | goto errout; |
| 236 | if (buffer_verified(bh)) | ||
| 237 | return 0; | ||
| 238 | |||
| 239 | error = -EFSBADCRC; | 239 | error = -EFSBADCRC; |
| 240 | if (!ext4_xattr_block_csum_verify(inode, bh)) | 240 | if (!ext4_xattr_block_csum_verify(inode, bh)) |
| 241 | goto errout; | 241 | goto errout; |
| @@ -1560,7 +1560,7 @@ static int ext4_xattr_set_entry(struct ext4_xattr_info *i, | |||
| 1560 | handle_t *handle, struct inode *inode, | 1560 | handle_t *handle, struct inode *inode, |
| 1561 | bool is_block) | 1561 | bool is_block) |
| 1562 | { | 1562 | { |
| 1563 | struct ext4_xattr_entry *last; | 1563 | struct ext4_xattr_entry *last, *next; |
| 1564 | struct ext4_xattr_entry *here = s->here; | 1564 | struct ext4_xattr_entry *here = s->here; |
| 1565 | size_t min_offs = s->end - s->base, name_len = strlen(i->name); | 1565 | size_t min_offs = s->end - s->base, name_len = strlen(i->name); |
| 1566 | int in_inode = i->in_inode; | 1566 | int in_inode = i->in_inode; |
| @@ -1595,7 +1595,13 @@ static int ext4_xattr_set_entry(struct ext4_xattr_info *i, | |||
| 1595 | 1595 | ||
| 1596 | /* Compute min_offs and last. */ | 1596 | /* Compute min_offs and last. */ |
| 1597 | last = s->first; | 1597 | last = s->first; |
| 1598 | for (; !IS_LAST_ENTRY(last); last = EXT4_XATTR_NEXT(last)) { | 1598 | for (; !IS_LAST_ENTRY(last); last = next) { |
| 1599 | next = EXT4_XATTR_NEXT(last); | ||
| 1600 | if ((void *)next >= s->end) { | ||
| 1601 | EXT4_ERROR_INODE(inode, "corrupted xattr entries"); | ||
| 1602 | ret = -EFSCORRUPTED; | ||
| 1603 | goto out; | ||
| 1604 | } | ||
| 1599 | if (!last->e_value_inum && last->e_value_size) { | 1605 | if (!last->e_value_inum && last->e_value_size) { |
| 1600 | size_t offs = le16_to_cpu(last->e_value_offs); | 1606 | size_t offs = le16_to_cpu(last->e_value_offs); |
| 1601 | if (offs < min_offs) | 1607 | if (offs < min_offs) |
| @@ -2206,23 +2212,8 @@ int ext4_xattr_ibody_inline_set(handle_t *handle, struct inode *inode, | |||
| 2206 | if (EXT4_I(inode)->i_extra_isize == 0) | 2212 | if (EXT4_I(inode)->i_extra_isize == 0) |
| 2207 | return -ENOSPC; | 2213 | return -ENOSPC; |
| 2208 | error = ext4_xattr_set_entry(i, s, handle, inode, false /* is_block */); | 2214 | error = ext4_xattr_set_entry(i, s, handle, inode, false /* is_block */); |
| 2209 | if (error) { | 2215 | if (error) |
| 2210 | if (error == -ENOSPC && | 2216 | return error; |
| 2211 | ext4_has_inline_data(inode)) { | ||
| 2212 | error = ext4_try_to_evict_inline_data(handle, inode, | ||
| 2213 | EXT4_XATTR_LEN(strlen(i->name) + | ||
| 2214 | EXT4_XATTR_SIZE(i->value_len))); | ||
| 2215 | if (error) | ||
| 2216 | return error; | ||
| 2217 | error = ext4_xattr_ibody_find(inode, i, is); | ||
| 2218 | if (error) | ||
| 2219 | return error; | ||
| 2220 | error = ext4_xattr_set_entry(i, s, handle, inode, | ||
| 2221 | false /* is_block */); | ||
| 2222 | } | ||
| 2223 | if (error) | ||
| 2224 | return error; | ||
| 2225 | } | ||
| 2226 | header = IHDR(inode, ext4_raw_inode(&is->iloc)); | 2217 | header = IHDR(inode, ext4_raw_inode(&is->iloc)); |
| 2227 | if (!IS_LAST_ENTRY(s->first)) { | 2218 | if (!IS_LAST_ENTRY(s->first)) { |
| 2228 | header->h_magic = cpu_to_le32(EXT4_XATTR_MAGIC); | 2219 | header->h_magic = cpu_to_le32(EXT4_XATTR_MAGIC); |
| @@ -2651,6 +2642,11 @@ static int ext4_xattr_make_inode_space(handle_t *handle, struct inode *inode, | |||
| 2651 | last = IFIRST(header); | 2642 | last = IFIRST(header); |
| 2652 | /* Find the entry best suited to be pushed into EA block */ | 2643 | /* Find the entry best suited to be pushed into EA block */ |
| 2653 | for (; !IS_LAST_ENTRY(last); last = EXT4_XATTR_NEXT(last)) { | 2644 | for (; !IS_LAST_ENTRY(last); last = EXT4_XATTR_NEXT(last)) { |
| 2645 | /* never move system.data out of the inode */ | ||
| 2646 | if ((last->e_name_len == 4) && | ||
| 2647 | (last->e_name_index == EXT4_XATTR_INDEX_SYSTEM) && | ||
| 2648 | !memcmp(last->e_name, "data", 4)) | ||
| 2649 | continue; | ||
| 2654 | total_size = EXT4_XATTR_LEN(last->e_name_len); | 2650 | total_size = EXT4_XATTR_LEN(last->e_name_len); |
| 2655 | if (!last->e_value_inum) | 2651 | if (!last->e_value_inum) |
| 2656 | total_size += EXT4_XATTR_SIZE( | 2652 | total_size += EXT4_XATTR_SIZE( |
diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c index 51dd68e67b0f..c0b66a7a795b 100644 --- a/fs/jbd2/transaction.c +++ b/fs/jbd2/transaction.c | |||
| @@ -1361,6 +1361,13 @@ int jbd2_journal_dirty_metadata(handle_t *handle, struct buffer_head *bh) | |||
| 1361 | if (jh->b_transaction == transaction && | 1361 | if (jh->b_transaction == transaction && |
| 1362 | jh->b_jlist != BJ_Metadata) { | 1362 | jh->b_jlist != BJ_Metadata) { |
| 1363 | jbd_lock_bh_state(bh); | 1363 | jbd_lock_bh_state(bh); |
| 1364 | if (jh->b_transaction == transaction && | ||
| 1365 | jh->b_jlist != BJ_Metadata) | ||
| 1366 | pr_err("JBD2: assertion failure: h_type=%u " | ||
| 1367 | "h_line_no=%u block_no=%llu jlist=%u\n", | ||
| 1368 | handle->h_type, handle->h_line_no, | ||
| 1369 | (unsigned long long) bh->b_blocknr, | ||
| 1370 | jh->b_jlist); | ||
| 1364 | J_ASSERT_JH(jh, jh->b_transaction != transaction || | 1371 | J_ASSERT_JH(jh, jh->b_transaction != transaction || |
| 1365 | jh->b_jlist == BJ_Metadata); | 1372 | jh->b_jlist == BJ_Metadata); |
| 1366 | jbd_unlock_bh_state(bh); | 1373 | jbd_unlock_bh_state(bh); |
| @@ -1380,11 +1387,11 @@ int jbd2_journal_dirty_metadata(handle_t *handle, struct buffer_head *bh) | |||
| 1380 | * of the transaction. This needs to be done | 1387 | * of the transaction. This needs to be done |
| 1381 | * once a transaction -bzzz | 1388 | * once a transaction -bzzz |
| 1382 | */ | 1389 | */ |
| 1383 | jh->b_modified = 1; | ||
| 1384 | if (handle->h_buffer_credits <= 0) { | 1390 | if (handle->h_buffer_credits <= 0) { |
| 1385 | ret = -ENOSPC; | 1391 | ret = -ENOSPC; |
| 1386 | goto out_unlock_bh; | 1392 | goto out_unlock_bh; |
| 1387 | } | 1393 | } |
| 1394 | jh->b_modified = 1; | ||
| 1388 | handle->h_buffer_credits--; | 1395 | handle->h_buffer_credits--; |
| 1389 | } | 1396 | } |
| 1390 | 1397 | ||
