From: Greg Kroah-Hartman Date: Fri, 9 Sep 2016 14:12:06 +0000 (+0200) Subject: 4.7-stable patches X-Git-Tag: v3.14.79~10 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=97b07fa7fe2e9e7a1b49b2fa86a6f89b7bf319e4;p=thirdparty%2Fkernel%2Fstable-queue.git 4.7-stable patches added patches: ext4-avoid-deadlock-when-expanding-inode-size.patch ext4-avoid-modifying-checksum-fields-directly-during-checksum-verification.patch ext4-fix-xattr-shifting-when-expanding-inodes-part-2.patch ext4-fix-xattr-shifting-when-expanding-inodes.patch ext4-properly-align-shifted-xattrs-when-expanding-inodes.patch ext4-validate-that-metadata-blocks-do-not-overlap-superblock.patch irqchip-gic-allow-self-sgis-for-smp-on-up-configurations.patch --- diff --git a/queue-4.7/ext4-avoid-deadlock-when-expanding-inode-size.patch b/queue-4.7/ext4-avoid-deadlock-when-expanding-inode-size.patch new file mode 100644 index 00000000000..b7b874e17a7 --- /dev/null +++ b/queue-4.7/ext4-avoid-deadlock-when-expanding-inode-size.patch @@ -0,0 +1,90 @@ +From 2e81a4eeedcaa66e35f58b81e0755b87057ce392 Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Thu, 11 Aug 2016 12:38:55 -0400 +Subject: ext4: avoid deadlock when expanding inode size + +From: Jan Kara + +commit 2e81a4eeedcaa66e35f58b81e0755b87057ce392 upstream. + +When we need to move xattrs into external xattr block, we call +ext4_xattr_block_set() from ext4_expand_extra_isize_ea(). That may end +up calling ext4_mark_inode_dirty() again which will recurse back into +the inode expansion code leading to deadlocks. + +Protect from recursion using EXT4_STATE_NO_EXPAND inode flag and move +its management into ext4_expand_extra_isize_ea() since its manipulation +is safe there (due to xattr_sem) from possible races with +ext4_xattr_set_handle() which plays with it as well. + +Signed-off-by: Jan Kara +Signed-off-by: Theodore Ts'o +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/inode.c | 2 -- + fs/ext4/xattr.c | 19 +++++++++++++------ + 2 files changed, 13 insertions(+), 8 deletions(-) + +--- a/fs/ext4/inode.c ++++ b/fs/ext4/inode.c +@@ -5460,8 +5460,6 @@ int ext4_mark_inode_dirty(handle_t *hand + sbi->s_want_extra_isize, + iloc, handle); + if (ret) { +- ext4_set_inode_state(inode, +- EXT4_STATE_NO_EXPAND); + if (mnt_count != + le16_to_cpu(sbi->s_es->s_mnt_count)) { + ext4_warning(inode->i_sb, +--- a/fs/ext4/xattr.c ++++ b/fs/ext4/xattr.c +@@ -1357,12 +1357,14 @@ int ext4_expand_extra_isize_ea(struct in + int isize_diff; /* How much do we need to grow i_extra_isize */ + + down_write(&EXT4_I(inode)->xattr_sem); ++ /* ++ * Set EXT4_STATE_NO_EXPAND to avoid recursion when marking inode dirty ++ */ ++ ext4_set_inode_state(inode, EXT4_STATE_NO_EXPAND); + retry: + isize_diff = new_extra_isize - EXT4_I(inode)->i_extra_isize; +- if (EXT4_I(inode)->i_extra_isize >= new_extra_isize) { +- up_write(&EXT4_I(inode)->xattr_sem); +- return 0; +- } ++ if (EXT4_I(inode)->i_extra_isize >= new_extra_isize) ++ goto out; + + header = IHDR(inode, raw_inode); + entry = IFIRST(header); +@@ -1391,8 +1393,7 @@ retry: + (void *)header, total_ino, + inode->i_sb->s_blocksize); + EXT4_I(inode)->i_extra_isize = new_extra_isize; +- error = 0; +- goto cleanup; ++ goto out; + } + + /* +@@ -1552,6 +1553,8 @@ retry: + kfree(bs); + } + brelse(bh); ++out: ++ ext4_clear_inode_state(inode, EXT4_STATE_NO_EXPAND); + up_write(&EXT4_I(inode)->xattr_sem); + return 0; + +@@ -1563,6 +1566,10 @@ cleanup: + kfree(is); + kfree(bs); + brelse(bh); ++ /* ++ * We deliberately leave EXT4_STATE_NO_EXPAND set here since inode ++ * size expansion failed. ++ */ + up_write(&EXT4_I(inode)->xattr_sem); + return error; + } diff --git a/queue-4.7/ext4-avoid-modifying-checksum-fields-directly-during-checksum-verification.patch b/queue-4.7/ext4-avoid-modifying-checksum-fields-directly-during-checksum-verification.patch new file mode 100644 index 00000000000..32fbe0ce058 --- /dev/null +++ b/queue-4.7/ext4-avoid-modifying-checksum-fields-directly-during-checksum-verification.patch @@ -0,0 +1,174 @@ +From b47820edd1634dc1208f9212b7ecfb4230610a23 Mon Sep 17 00:00:00 2001 +From: Daeho Jeong +Date: Sun, 3 Jul 2016 17:51:39 -0400 +Subject: ext4: avoid modifying checksum fields directly during checksum verification + +From: Daeho Jeong + +commit b47820edd1634dc1208f9212b7ecfb4230610a23 upstream. + +We temporally change checksum fields in buffers of some types of +metadata into '0' for verifying the checksum values. By doing this +without locking the buffer, some metadata's checksums, which are +being committed or written back to the storage, could be damaged. +In our test, several metadata blocks were found with damaged metadata +checksum value during recovery process. When we only verify the +checksum value, we have to avoid modifying checksum fields directly. + +Signed-off-by: Daeho Jeong +Signed-off-by: Youngjin Gil +Signed-off-by: Theodore Ts'o +Reviewed-by: Darrick J. Wong +Cc: Török Edwin +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/inode.c | 38 ++++++++++++++++++++++---------------- + fs/ext4/namei.c | 9 ++++----- + fs/ext4/super.c | 18 +++++++++--------- + fs/ext4/xattr.c | 13 +++++++------ + 4 files changed, 42 insertions(+), 36 deletions(-) + +--- a/fs/ext4/inode.c ++++ b/fs/ext4/inode.c +@@ -51,25 +51,31 @@ static __u32 ext4_inode_csum(struct inod + struct ext4_inode_info *ei) + { + struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); +- __u16 csum_lo; +- __u16 csum_hi = 0; + __u32 csum; ++ __u16 dummy_csum = 0; ++ int offset = offsetof(struct ext4_inode, i_checksum_lo); ++ unsigned int csum_size = sizeof(dummy_csum); + +- csum_lo = le16_to_cpu(raw->i_checksum_lo); +- raw->i_checksum_lo = 0; +- if (EXT4_INODE_SIZE(inode->i_sb) > EXT4_GOOD_OLD_INODE_SIZE && +- EXT4_FITS_IN_INODE(raw, ei, i_checksum_hi)) { +- csum_hi = le16_to_cpu(raw->i_checksum_hi); +- raw->i_checksum_hi = 0; +- } +- +- csum = ext4_chksum(sbi, ei->i_csum_seed, (__u8 *)raw, +- EXT4_INODE_SIZE(inode->i_sb)); ++ csum = ext4_chksum(sbi, ei->i_csum_seed, (__u8 *)raw, offset); ++ csum = ext4_chksum(sbi, csum, (__u8 *)&dummy_csum, csum_size); ++ offset += csum_size; ++ csum = ext4_chksum(sbi, csum, (__u8 *)raw + offset, ++ EXT4_GOOD_OLD_INODE_SIZE - offset); + +- raw->i_checksum_lo = cpu_to_le16(csum_lo); +- if (EXT4_INODE_SIZE(inode->i_sb) > EXT4_GOOD_OLD_INODE_SIZE && +- EXT4_FITS_IN_INODE(raw, ei, i_checksum_hi)) +- raw->i_checksum_hi = cpu_to_le16(csum_hi); ++ if (EXT4_INODE_SIZE(inode->i_sb) > EXT4_GOOD_OLD_INODE_SIZE) { ++ offset = offsetof(struct ext4_inode, i_checksum_hi); ++ csum = ext4_chksum(sbi, csum, (__u8 *)raw + ++ EXT4_GOOD_OLD_INODE_SIZE, ++ offset - EXT4_GOOD_OLD_INODE_SIZE); ++ if (EXT4_FITS_IN_INODE(raw, ei, i_checksum_hi)) { ++ csum = ext4_chksum(sbi, csum, (__u8 *)&dummy_csum, ++ csum_size); ++ offset += csum_size; ++ csum = ext4_chksum(sbi, csum, (__u8 *)raw + offset, ++ EXT4_INODE_SIZE(inode->i_sb) - ++ offset); ++ } ++ } + + return csum; + } +--- a/fs/ext4/namei.c ++++ b/fs/ext4/namei.c +@@ -420,15 +420,14 @@ static __le32 ext4_dx_csum(struct inode + struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); + struct ext4_inode_info *ei = EXT4_I(inode); + __u32 csum; +- __le32 save_csum; + int size; ++ __u32 dummy_csum = 0; ++ int offset = offsetof(struct dx_tail, dt_checksum); + + size = count_offset + (count * sizeof(struct dx_entry)); +- save_csum = t->dt_checksum; +- t->dt_checksum = 0; + csum = ext4_chksum(sbi, ei->i_csum_seed, (__u8 *)dirent, size); +- csum = ext4_chksum(sbi, csum, (__u8 *)t, sizeof(struct dx_tail)); +- t->dt_checksum = save_csum; ++ csum = ext4_chksum(sbi, csum, (__u8 *)t, offset); ++ csum = ext4_chksum(sbi, csum, (__u8 *)&dummy_csum, sizeof(dummy_csum)); + + return cpu_to_le32(csum); + } +--- a/fs/ext4/super.c ++++ b/fs/ext4/super.c +@@ -2068,23 +2068,25 @@ failed: + static __le16 ext4_group_desc_csum(struct super_block *sb, __u32 block_group, + struct ext4_group_desc *gdp) + { +- int offset; ++ int offset = offsetof(struct ext4_group_desc, bg_checksum); + __u16 crc = 0; + __le32 le_group = cpu_to_le32(block_group); + struct ext4_sb_info *sbi = EXT4_SB(sb); + + if (ext4_has_metadata_csum(sbi->s_sb)) { + /* Use new metadata_csum algorithm */ +- __le16 save_csum; + __u32 csum32; ++ __u16 dummy_csum = 0; + +- save_csum = gdp->bg_checksum; +- gdp->bg_checksum = 0; + csum32 = ext4_chksum(sbi, sbi->s_csum_seed, (__u8 *)&le_group, + sizeof(le_group)); +- csum32 = ext4_chksum(sbi, csum32, (__u8 *)gdp, +- sbi->s_desc_size); +- gdp->bg_checksum = save_csum; ++ csum32 = ext4_chksum(sbi, csum32, (__u8 *)gdp, offset); ++ csum32 = ext4_chksum(sbi, csum32, (__u8 *)&dummy_csum, ++ sizeof(dummy_csum)); ++ offset += sizeof(dummy_csum); ++ if (offset < sbi->s_desc_size) ++ csum32 = ext4_chksum(sbi, csum32, (__u8 *)gdp + offset, ++ sbi->s_desc_size - offset); + + crc = csum32 & 0xFFFF; + goto out; +@@ -2094,8 +2096,6 @@ static __le16 ext4_group_desc_csum(struc + if (!ext4_has_feature_gdt_csum(sb)) + return 0; + +- offset = offsetof(struct ext4_group_desc, bg_checksum); +- + crc = crc16(~0, sbi->s_es->s_uuid, sizeof(sbi->s_es->s_uuid)); + crc = crc16(crc, (__u8 *)&le_group, sizeof(le_group)); + crc = crc16(crc, (__u8 *)gdp, offset); +--- a/fs/ext4/xattr.c ++++ b/fs/ext4/xattr.c +@@ -121,17 +121,18 @@ static __le32 ext4_xattr_block_csum(stru + { + struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); + __u32 csum; +- __le32 save_csum; + __le64 dsk_block_nr = cpu_to_le64(block_nr); ++ __u32 dummy_csum = 0; ++ int offset = offsetof(struct ext4_xattr_header, h_checksum); + +- save_csum = hdr->h_checksum; +- hdr->h_checksum = 0; + csum = ext4_chksum(sbi, sbi->s_csum_seed, (__u8 *)&dsk_block_nr, + sizeof(dsk_block_nr)); +- csum = ext4_chksum(sbi, csum, (__u8 *)hdr, +- EXT4_BLOCK_SIZE(inode->i_sb)); ++ csum = ext4_chksum(sbi, csum, (__u8 *)hdr, offset); ++ csum = ext4_chksum(sbi, csum, (__u8 *)&dummy_csum, sizeof(dummy_csum)); ++ offset += sizeof(dummy_csum); ++ csum = ext4_chksum(sbi, csum, (__u8 *)hdr + offset, ++ EXT4_BLOCK_SIZE(inode->i_sb) - offset); + +- hdr->h_checksum = save_csum; + return cpu_to_le32(csum); + } + diff --git a/queue-4.7/ext4-fix-xattr-shifting-when-expanding-inodes-part-2.patch b/queue-4.7/ext4-fix-xattr-shifting-when-expanding-inodes-part-2.patch new file mode 100644 index 00000000000..688571ae921 --- /dev/null +++ b/queue-4.7/ext4-fix-xattr-shifting-when-expanding-inodes-part-2.patch @@ -0,0 +1,48 @@ +From 418c12d08dc64a45107c467ec1ba29b5e69b0715 Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Thu, 11 Aug 2016 11:58:32 -0400 +Subject: ext4: fix xattr shifting when expanding inodes part 2 + +From: Jan Kara + +commit 418c12d08dc64a45107c467ec1ba29b5e69b0715 upstream. + +When multiple xattrs need to be moved out of inode, we did not properly +recompute total size of xattr headers in the inode and the new header +position. Thus when moving the second and further xattr we asked +ext4_xattr_shift_entries() to move too much and from the wrong place, +resulting in possible xattr value corruption or general memory +corruption. + +Signed-off-by: Jan Kara +Signed-off-by: Theodore Ts'o +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/xattr.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/fs/ext4/xattr.c ++++ b/fs/ext4/xattr.c +@@ -1515,6 +1515,7 @@ retry: + error = ext4_xattr_ibody_set(handle, inode, &i, is); + if (error) + goto cleanup; ++ total_ino -= entry_size; + + entry = IFIRST(header); + if (entry_size + EXT4_XATTR_SIZE(size) >= isize_diff) +@@ -1525,11 +1526,11 @@ retry: + ext4_xattr_shift_entries(entry, -shift_bytes, + (void *)raw_inode + EXT4_GOOD_OLD_INODE_SIZE + + EXT4_I(inode)->i_extra_isize + shift_bytes, +- (void *)header, total_ino - entry_size, +- inode->i_sb->s_blocksize); ++ (void *)header, total_ino, inode->i_sb->s_blocksize); + + isize_diff -= shift_bytes; + EXT4_I(inode)->i_extra_isize += shift_bytes; ++ header = IHDR(inode, raw_inode); + + i.name = b_entry_name; + i.value = buffer; diff --git a/queue-4.7/ext4-fix-xattr-shifting-when-expanding-inodes.patch b/queue-4.7/ext4-fix-xattr-shifting-when-expanding-inodes.patch new file mode 100644 index 00000000000..c5e7f52b7c0 --- /dev/null +++ b/queue-4.7/ext4-fix-xattr-shifting-when-expanding-inodes.patch @@ -0,0 +1,115 @@ +From d0141191a20289f8955c1e03dad08e42e6f71ca9 Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Thu, 11 Aug 2016 11:50:30 -0400 +Subject: ext4: fix xattr shifting when expanding inodes + +From: Jan Kara + +commit d0141191a20289f8955c1e03dad08e42e6f71ca9 upstream. + +The code in ext4_expand_extra_isize_ea() treated new_extra_isize +argument sometimes as the desired target i_extra_isize and sometimes as +the amount by which we need to grow current i_extra_isize. These happen +to coincide when i_extra_isize is 0 which used to be the common case and +so nobody noticed this until recently when we added i_projid to the +inode and so i_extra_isize now needs to grow from 28 to 32 bytes. + +The result of these bugs was that we sometimes unnecessarily decided to +move xattrs out of inode even if there was enough space and we often +ended up corrupting in-inode xattrs because arguments to +ext4_xattr_shift_entries() were just wrong. This could demonstrate +itself as BUG_ON in ext4_xattr_shift_entries() triggering. + +Fix the problem by introducing new isize_diff variable and use it where +appropriate. + +Reported-by: Dave Chinner +Signed-off-by: Jan Kara +Signed-off-by: Theodore Ts'o +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/xattr.c | 27 ++++++++++++++------------- + 1 file changed, 14 insertions(+), 13 deletions(-) + +--- a/fs/ext4/xattr.c ++++ b/fs/ext4/xattr.c +@@ -1352,11 +1352,13 @@ int ext4_expand_extra_isize_ea(struct in + size_t min_offs, free; + int total_ino; + void *base, *start, *end; +- int extra_isize = 0, error = 0, tried_min_extra_isize = 0; ++ int error = 0, tried_min_extra_isize = 0; + int s_min_extra_isize = le16_to_cpu(EXT4_SB(inode->i_sb)->s_es->s_min_extra_isize); ++ int isize_diff; /* How much do we need to grow i_extra_isize */ + + down_write(&EXT4_I(inode)->xattr_sem); + retry: ++ isize_diff = new_extra_isize - EXT4_I(inode)->i_extra_isize; + if (EXT4_I(inode)->i_extra_isize >= new_extra_isize) { + up_write(&EXT4_I(inode)->xattr_sem); + return 0; +@@ -1381,7 +1383,7 @@ retry: + goto cleanup; + + free = ext4_xattr_free_space(last, &min_offs, base, &total_ino); +- if (free >= new_extra_isize) { ++ if (free >= isize_diff) { + entry = IFIRST(header); + ext4_xattr_shift_entries(entry, EXT4_I(inode)->i_extra_isize + - new_extra_isize, (void *)raw_inode + +@@ -1413,7 +1415,7 @@ retry: + end = bh->b_data + bh->b_size; + min_offs = end - base; + free = ext4_xattr_free_space(first, &min_offs, base, NULL); +- if (free < new_extra_isize) { ++ if (free < isize_diff) { + if (!tried_min_extra_isize && s_min_extra_isize) { + tried_min_extra_isize++; + new_extra_isize = s_min_extra_isize; +@@ -1427,7 +1429,7 @@ retry: + free = inode->i_sb->s_blocksize; + } + +- while (new_extra_isize > 0) { ++ while (isize_diff > 0) { + size_t offs, size, entry_size; + struct ext4_xattr_entry *small_entry = NULL; + struct ext4_xattr_info i = { +@@ -1458,7 +1460,7 @@ retry: + EXT4_XATTR_SIZE(le32_to_cpu(last->e_value_size)) + + EXT4_XATTR_LEN(last->e_name_len); + if (total_size <= free && total_size < min_total_size) { +- if (total_size < new_extra_isize) { ++ if (total_size < isize_diff) { + small_entry = last; + } else { + entry = last; +@@ -1515,20 +1517,19 @@ retry: + goto cleanup; + + entry = IFIRST(header); +- if (entry_size + EXT4_XATTR_SIZE(size) >= new_extra_isize) +- shift_bytes = new_extra_isize; ++ if (entry_size + EXT4_XATTR_SIZE(size) >= isize_diff) ++ shift_bytes = isize_diff; + else + shift_bytes = entry_size + size; + /* Adjust the offsets and shift the remaining entries ahead */ +- ext4_xattr_shift_entries(entry, EXT4_I(inode)->i_extra_isize - +- shift_bytes, (void *)raw_inode + +- EXT4_GOOD_OLD_INODE_SIZE + extra_isize + shift_bytes, ++ ext4_xattr_shift_entries(entry, -shift_bytes, ++ (void *)raw_inode + EXT4_GOOD_OLD_INODE_SIZE + ++ EXT4_I(inode)->i_extra_isize + shift_bytes, + (void *)header, total_ino - entry_size, + inode->i_sb->s_blocksize); + +- extra_isize += shift_bytes; +- new_extra_isize -= shift_bytes; +- EXT4_I(inode)->i_extra_isize = extra_isize; ++ isize_diff -= shift_bytes; ++ EXT4_I(inode)->i_extra_isize += shift_bytes; + + i.name = b_entry_name; + i.value = buffer; diff --git a/queue-4.7/ext4-properly-align-shifted-xattrs-when-expanding-inodes.patch b/queue-4.7/ext4-properly-align-shifted-xattrs-when-expanding-inodes.patch new file mode 100644 index 00000000000..489882ebd6a --- /dev/null +++ b/queue-4.7/ext4-properly-align-shifted-xattrs-when-expanding-inodes.patch @@ -0,0 +1,32 @@ +From 443a8c41cd49de66a3fda45b32b9860ea0292b84 Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Thu, 11 Aug 2016 12:00:01 -0400 +Subject: ext4: properly align shifted xattrs when expanding inodes + +From: Jan Kara + +commit 443a8c41cd49de66a3fda45b32b9860ea0292b84 upstream. + +We did not count with the padding of xattr value when computing desired +shift of xattrs in the inode when expanding i_extra_isize. As a result +we could create unaligned start of inline xattrs. Account for alignment +properly. + +Signed-off-by: Jan Kara +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/xattr.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/ext4/xattr.c ++++ b/fs/ext4/xattr.c +@@ -1521,7 +1521,7 @@ retry: + if (entry_size + EXT4_XATTR_SIZE(size) >= isize_diff) + shift_bytes = isize_diff; + else +- shift_bytes = entry_size + size; ++ shift_bytes = entry_size + EXT4_XATTR_SIZE(size); + /* Adjust the offsets and shift the remaining entries ahead */ + ext4_xattr_shift_entries(entry, -shift_bytes, + (void *)raw_inode + EXT4_GOOD_OLD_INODE_SIZE + diff --git a/queue-4.7/ext4-validate-that-metadata-blocks-do-not-overlap-superblock.patch b/queue-4.7/ext4-validate-that-metadata-blocks-do-not-overlap-superblock.patch new file mode 100644 index 00000000000..c7126ccdb27 --- /dev/null +++ b/queue-4.7/ext4-validate-that-metadata-blocks-do-not-overlap-superblock.patch @@ -0,0 +1,78 @@ +From 829fa70dddadf9dd041d62b82cd7cea63943899d Mon Sep 17 00:00:00 2001 +From: Theodore Ts'o +Date: Mon, 1 Aug 2016 00:51:02 -0400 +Subject: ext4: validate that metadata blocks do not overlap superblock + +From: Theodore Ts'o + +commit 829fa70dddadf9dd041d62b82cd7cea63943899d upstream. + +A number of fuzzing failures seem to be caused by allocation bitmaps +or other metadata blocks being pointed at the superblock. + +This can cause kernel BUG or WARNings once the superblock is +overwritten, so validate the group descriptor blocks to make sure this +doesn't happen. + +Signed-off-by: Theodore Ts'o +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/super.c | 18 +++++++++++++++++- + 1 file changed, 17 insertions(+), 1 deletion(-) + +--- a/fs/ext4/super.c ++++ b/fs/ext4/super.c +@@ -2131,6 +2131,7 @@ void ext4_group_desc_csum_set(struct sup + + /* Called at mount-time, super-block is locked */ + static int ext4_check_descriptors(struct super_block *sb, ++ ext4_fsblk_t sb_block, + ext4_group_t *first_not_zeroed) + { + struct ext4_sb_info *sbi = EXT4_SB(sb); +@@ -2161,6 +2162,11 @@ static int ext4_check_descriptors(struct + grp = i; + + block_bitmap = ext4_block_bitmap(sb, gdp); ++ if (block_bitmap == sb_block) { ++ ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: " ++ "Block bitmap for group %u overlaps " ++ "superblock", i); ++ } + 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 " +@@ -2168,6 +2174,11 @@ static int ext4_check_descriptors(struct + return 0; + } + inode_bitmap = ext4_inode_bitmap(sb, gdp); ++ if (inode_bitmap == sb_block) { ++ ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: " ++ "Inode bitmap for group %u overlaps " ++ "superblock", i); ++ } + 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 " +@@ -2175,6 +2186,11 @@ static int ext4_check_descriptors(struct + return 0; + } + inode_table = ext4_inode_table(sb, gdp); ++ if (inode_table == sb_block) { ++ ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: " ++ "Inode table for group %u overlaps " ++ "superblock", i); ++ } + if (inode_table < first_block || + inode_table + sbi->s_itb_per_group - 1 > last_block) { + ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: " +@@ -3677,7 +3693,7 @@ static int ext4_fill_super(struct super_ + goto failed_mount2; + } + } +- if (!ext4_check_descriptors(sb, &first_not_zeroed)) { ++ if (!ext4_check_descriptors(sb, logical_sb_block, &first_not_zeroed)) { + ext4_msg(sb, KERN_ERR, "group descriptors corrupted!"); + ret = -EFSCORRUPTED; + goto failed_mount2; diff --git a/queue-4.7/irqchip-gic-allow-self-sgis-for-smp-on-up-configurations.patch b/queue-4.7/irqchip-gic-allow-self-sgis-for-smp-on-up-configurations.patch new file mode 100644 index 00000000000..da6185619d1 --- /dev/null +++ b/queue-4.7/irqchip-gic-allow-self-sgis-for-smp-on-up-configurations.patch @@ -0,0 +1,37 @@ +From 059e232089e45b0befc9933d31209c225e08b426 Mon Sep 17 00:00:00 2001 +From: Marc Zyngier +Date: Tue, 9 Aug 2016 07:50:44 +0100 +Subject: irqchip/gic: Allow self-SGIs for SMP on UP configurations + +From: Marc Zyngier + +commit 059e232089e45b0befc9933d31209c225e08b426 upstream. + +On systems where a single CPU is present, the GIC may not support +having SGIs delivered to a target list. In that case, we use the +self-SGI mechanism to allow the interrupt to be delivered locally. + +Tested-by: Fabio Estevam +Signed-off-by: Marc Zyngier +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/irqchip/irq-gic.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/drivers/irqchip/irq-gic.c ++++ b/drivers/irqchip/irq-gic.c +@@ -769,6 +769,13 @@ static void gic_raise_softirq(const stru + int cpu; + unsigned long flags, map = 0; + ++ if (unlikely(nr_cpu_ids == 1)) { ++ /* Only one CPU? let's do a self-IPI... */ ++ writel_relaxed(2 << 24 | irq, ++ gic_data_dist_base(&gic_data[0]) + GIC_DIST_SOFTINT); ++ return; ++ } ++ + raw_spin_lock_irqsave(&irq_controller_lock, flags); + + /* Convert our logical CPU mask into a physical one. */ diff --git a/queue-4.7/series b/queue-4.7/series index 43d702ba980..d7bd01a5da9 100644 --- a/queue-4.7/series +++ b/queue-4.7/series @@ -4,3 +4,10 @@ kernel-add-noaudit-variant-of-ns_capable.patch net-use-ns_capable_noaudit-when-determining-net-sysctl-permissions.patch fs-check-for-invalid-i_uid-in-may_follow_link.patch cred-reject-inodes-with-invalid-ids-in-set_create_file_as.patch +irqchip-gic-allow-self-sgis-for-smp-on-up-configurations.patch +ext4-validate-that-metadata-blocks-do-not-overlap-superblock.patch +ext4-fix-xattr-shifting-when-expanding-inodes.patch +ext4-fix-xattr-shifting-when-expanding-inodes-part-2.patch +ext4-properly-align-shifted-xattrs-when-expanding-inodes.patch +ext4-avoid-deadlock-when-expanding-inode-size.patch +ext4-avoid-modifying-checksum-fields-directly-during-checksum-verification.patch