diff options
| author | Blagovest Kolenichev <bkolenichev@codeaurora.org> | 2018-07-11 08:31:19 -0700 |
|---|---|---|
| committer | Srinivasarao P <spathi@codeaurora.org> | 2018-07-18 15:09:28 +0530 |
| commit | df1c139ee74a8c6a2bc35112d02f32ef654dfafb (patch) | |
| tree | 717137876588d24f052118821afc6e6b4cd1d8ec /fs/ext4/super.c | |
| parent | 4049db73f1a32cd633827f479cb25fdcd231d7f4 (diff) | |
| parent | 789274d6967db4c8eeba291dc618c84698dc9803 (diff) | |
Merge android-4.4.140 (789274d) into msm-4.4
* refs/heads/tmp-789274d
Linux 4.4.140
staging: comedi: quatech_daqp_cs: fix no-op loop daqp_ao_insn_write()
netfilter: nf_log: don't hold nf_log_mutex during user access
mtd: cfi_cmdset_0002: Change erase functions to check chip good only
mtd: cfi_cmdset_0002: Change erase functions to retry for error
mtd: cfi_cmdset_0002: Change definition naming to retry write operation
dm bufio: don't take the lock in dm_bufio_shrink_count
mtd: rawnand: mxc: set spare area size register explicitly
dm bufio: drop the lock when doing GFP_NOIO allocation
dm bufio: avoid sleeping while holding the dm_bufio lock
mm, page_alloc: do not break __GFP_THISNODE by zonelist reset
media: cx25840: Use subdev host data for PLL override
x86/mce: Fix incorrect "Machine check from unknown source" message
x86/mce: Detect local MCEs properly
HID: debug: check length before copy_to_user()
HID: hiddev: fix potential Spectre v1
HID: i2c-hid: Fix "incomplete report" noise
ext4: check superblock mapped prior to committing
ext4: add more mount time checks of the superblock
ext4: add more inode number paranoia checks
ext4: clear i_data in ext4_inode_info when removing inline data
ext4: include the illegal physical block in the bad map ext4_error msg
ext4: verify the depth of extent tree in ext4_find_extent()
ext4: only look at the bg_flags field if it is valid
ext4: always check block group bounds in ext4_init_block_bitmap()
ext4: make sure bitmaps and the inode table don't overlap with bg descriptors
jbd2: don't mark block as modified if the handle is out of credits
cifs: Fix infinite loop when using hard mount option
drbd: fix access after free
s390: Correct register corruption in critical section cleanup
scsi: sg: mitigate read/write abuse
tracing: Fix missing return symbol in function_graph output
mm: hugetlb: yield when prepping struct pages
ubi: fastmap: Correctly handle interrupted erasures in EBA
ARM: dts: imx6q: Use correct SDMA script for SPI5 core
netfilter: nf_tables: use WARN_ON_ONCE instead of BUG_ON in nft_do_chain()
nvme-pci: initialize queue memory before interrupts
kprobes/x86: Do not modify singlestep buffer while resuming
ipv4: Fix error return value in fib_convert_metrics()
i2c: rcar: fix resume by always initializing registers before transfer
ath10k: fix rfc1042 header retrieval in QCA4019 with eth decap mode
x86/boot: Fix early command-line parsing when matching at end
n_tty: Access echo_* variables carefully.
staging: android: ion: Return an ERR_PTR in ion_map_kernel
n_tty: Fix stall at n_tty_receive_char_special().
USB: serial: cp210x: add Silicon Labs IDs for Windows Update
USB: serial: cp210x: add CESINEL device ids
usb: cdc_acm: Add quirk for Uniden UBC125 scanner
Change-Id: I01c4fc4b6354c28a7d8ff391ff515096ed4d3da4
Signed-off-by: Blagovest Kolenichev <bkolenichev@codeaurora.org>
Signed-off-by: Srinivasarao P <spathi@codeaurora.org>
Diffstat (limited to 'fs/ext4/super.c')
| -rw-r--r-- | fs/ext4/super.c | 86 |
1 files changed, 74 insertions, 12 deletions
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 8cff133ff5f3..c5ba22bdeaa9 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -2101,6 +2101,7 @@ static int ext4_check_descriptors(struct super_block *sb, struct ext4_sb_info *sbi = EXT4_SB(sb); ext4_fsblk_t first_block = le32_to_cpu(sbi->s_es->s_first_data_block); ext4_fsblk_t last_block; + ext4_fsblk_t last_bg_block = sb_block + ext4_bg_num_gdb(sb, 0) + 1; ext4_fsblk_t block_bitmap; ext4_fsblk_t inode_bitmap; ext4_fsblk_t inode_table; @@ -2133,6 +2134,14 @@ static int ext4_check_descriptors(struct super_block *sb, if (!(sb->s_flags & MS_RDONLY)) return 0; } + if (block_bitmap >= sb_block + 1 && + block_bitmap <= last_bg_block) { + ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: " + "Block bitmap for group %u overlaps " + "block group descriptors", i); + if (!(sb->s_flags & MS_RDONLY)) + return 0; + } if (block_bitmap < first_block || block_bitmap > last_block) { ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: " "Block bitmap for group %u not in group " @@ -2147,6 +2156,14 @@ static int ext4_check_descriptors(struct super_block *sb, if (!(sb->s_flags & MS_RDONLY)) return 0; } + if (inode_bitmap >= sb_block + 1 && + inode_bitmap <= last_bg_block) { + ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: " + "Inode bitmap for group %u overlaps " + "block group descriptors", i); + if (!(sb->s_flags & MS_RDONLY)) + return 0; + } if (inode_bitmap < first_block || inode_bitmap > last_block) { ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: " "Inode bitmap for group %u not in group " @@ -2161,6 +2178,14 @@ static int ext4_check_descriptors(struct super_block *sb, if (!(sb->s_flags & MS_RDONLY)) return 0; } + if (inode_table >= sb_block + 1 && + inode_table <= last_bg_block) { + ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: " + "Inode table for group %u overlaps " + "block group descriptors", i); + if (!(sb->s_flags & MS_RDONLY)) + return 0; + } if (inode_table < first_block || inode_table + sbi->s_itb_per_group - 1 > last_block) { ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: " @@ -2841,13 +2866,22 @@ static ext4_group_t ext4_has_uninit_itable(struct super_block *sb) ext4_group_t group, ngroups = EXT4_SB(sb)->s_groups_count; struct ext4_group_desc *gdp = NULL; + if (!ext4_has_group_desc_csum(sb)) + return ngroups; + for (group = 0; group < ngroups; group++) { gdp = ext4_get_group_desc(sb, group, NULL); if (!gdp) continue; - if (!(gdp->bg_flags & cpu_to_le16(EXT4_BG_INODE_ZEROED))) + if (gdp->bg_flags & cpu_to_le16(EXT4_BG_INODE_ZEROED)) + continue; + if (group != 0) break; + ext4_error(sb, "Inode table for bg 0 marked as " + "needing zeroing"); + if (sb->s_flags & MS_RDONLY) + return ngroups; } return group; @@ -3450,6 +3484,13 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) le32_to_cpu(es->s_log_block_size)); goto failed_mount; } + if (le32_to_cpu(es->s_log_cluster_size) > + (EXT4_MAX_CLUSTER_LOG_SIZE - EXT4_MIN_BLOCK_LOG_SIZE)) { + ext4_msg(sb, KERN_ERR, + "Invalid log cluster size: %u", + le32_to_cpu(es->s_log_cluster_size)); + goto failed_mount; + } if (le16_to_cpu(sbi->s_es->s_reserved_gdt_blocks) > (blocksize / 4)) { ext4_msg(sb, KERN_ERR, @@ -3514,6 +3555,11 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) } else { sbi->s_inode_size = le16_to_cpu(es->s_inode_size); sbi->s_first_ino = le32_to_cpu(es->s_first_ino); + if (sbi->s_first_ino < EXT4_GOOD_OLD_FIRST_INO) { + ext4_msg(sb, KERN_ERR, "invalid first ino: %u", + sbi->s_first_ino); + goto failed_mount; + } if ((sbi->s_inode_size < EXT4_GOOD_OLD_INODE_SIZE) || (!is_power_of_2(sbi->s_inode_size)) || (sbi->s_inode_size > blocksize)) { @@ -3590,13 +3636,6 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) "block size (%d)", clustersize, blocksize); goto failed_mount; } - if (le32_to_cpu(es->s_log_cluster_size) > - (EXT4_MAX_CLUSTER_LOG_SIZE - EXT4_MIN_BLOCK_LOG_SIZE)) { - ext4_msg(sb, KERN_ERR, - "Invalid log cluster size: %u", - le32_to_cpu(es->s_log_cluster_size)); - goto failed_mount; - } sbi->s_cluster_bits = le32_to_cpu(es->s_log_cluster_size) - le32_to_cpu(es->s_log_block_size); sbi->s_clusters_per_group = @@ -3617,10 +3656,10 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) } } else { if (clustersize != blocksize) { - ext4_warning(sb, "fragment/cluster size (%d) != " - "block size (%d)", clustersize, - blocksize); - clustersize = blocksize; + ext4_msg(sb, KERN_ERR, + "fragment/cluster size (%d) != " + "block size (%d)", clustersize, blocksize); + goto failed_mount; } if (sbi->s_blocks_per_group > blocksize * 8) { ext4_msg(sb, KERN_ERR, @@ -3674,6 +3713,13 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) ext4_blocks_count(es)); goto failed_mount; } + if ((es->s_first_data_block == 0) && (es->s_log_block_size == 0) && + (sbi->s_cluster_ratio == 1)) { + ext4_msg(sb, KERN_WARNING, "bad geometry: first data " + "block is 0 with a 1k block and cluster size"); + goto failed_mount; + } + blocks_count = (ext4_blocks_count(es) - le32_to_cpu(es->s_first_data_block) + EXT4_BLOCKS_PER_GROUP(sb) - 1); @@ -3709,6 +3755,14 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) ret = -ENOMEM; goto failed_mount; } + if (((u64)sbi->s_groups_count * sbi->s_inodes_per_group) != + le32_to_cpu(es->s_inodes_count)) { + ext4_msg(sb, KERN_ERR, "inodes count not valid: %u vs %llu", + le32_to_cpu(es->s_inodes_count), + ((u64)sbi->s_groups_count * sbi->s_inodes_per_group)); + ret = -EINVAL; + goto failed_mount; + } bgl_lock_init(sbi->s_blockgroup_lock); @@ -4391,6 +4445,14 @@ static int ext4_commit_super(struct super_block *sb, int sync) if (!sbh || block_device_ejected(sb)) return error; + + /* + * The superblock bh should be mapped, but it might not be if the + * device was hot-removed. Not much we can do but fail the I/O. + */ + if (!buffer_mapped(sbh)) + return error; + if (buffer_write_io_error(sbh)) { /* * Oh, dear. A previous attempt to write the |
