summaryrefslogtreecommitdiff
path: root/fs/ext4
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@google.com>2018-09-29 07:51:37 -0700
committerGreg Kroah-Hartman <gregkh@google.com>2018-09-29 07:51:37 -0700
commit624c095947925bb8a8555015b841d8a4ec673a45 (patch)
treef221926c18ac3451cc4446a5ccf780771ab4ca08 /fs/ext4
parent85b352c447569d3e8a6788df96c904512b1048dc (diff)
parent9c6cd3f3a4b8194e82fa927bc00028c7a505e3b3 (diff)
Merge 4.4.159 into android-4.4
Changes in 4.4.159 NFC: Fix possible memory corruption when handling SHDLC I-Frame commands NFC: Fix the number of pipes ASoC: cs4265: fix MMTLR Data switch control ALSA: bebob: use address returned by kmalloc() instead of kernel stack for streaming DMA mapping ALSA: emu10k1: fix possible info leak to userspace on SNDRV_EMU10K1_IOCTL_INFO platform/x86: alienware-wmi: Correct a memory leak xen/netfront: don't bug in case of too many frags xen/x86/vpmu: Zero struct pt_regs before calling into sample handling code ring-buffer: Allow for rescheduling when removing pages mm: shmem.c: Correctly annotate new inodes for lockdep gso_segment: Reset skb->mac_len after modifying network header ipv6: fix possible use-after-free in ip6_xmit() net/appletalk: fix minor pointer leak to userspace in SIOCFINDIPDDPRT net: hp100: fix always-true check for link up state neighbour: confirm neigh entries when ARP packet is received scsi: target: iscsi: Use hex2bin instead of a re-implementation ocfs2: fix ocfs2 read block panic drm/nouveau/drm/nouveau: Use pm_runtime_get_noresume() in connector_detect() tty: vt_ioctl: fix potential Spectre v1 ext4: avoid divide by zero fault when deleting corrupted inline directories ext4: recalucate superblock checksum after updating free blocks/inodes ext4: fix online resize's handling of a too-small final block group ext4: fix online resizing for bigalloc file systems with a 1k block size ext4: don't mark mmp buffer head dirty arm64: Add trace_hardirqs_off annotation in ret_to_user HID: sony: Update device ids HID: sony: Support DS4 dongle iw_cxgb4: only allow 1 flush on user qps Linux 4.4.159 Change-Id: I98239ca60783ca69147f2f11034138fc22e2af65 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
Diffstat (limited to 'fs/ext4')
-rw-r--r--fs/ext4/dir.c20
-rw-r--r--fs/ext4/inline.c4
-rw-r--r--fs/ext4/mmp.c1
-rw-r--r--fs/ext4/resize.c23
-rw-r--r--fs/ext4/super.c2
5 files changed, 36 insertions, 14 deletions
diff --git a/fs/ext4/dir.c b/fs/ext4/dir.c
index 6d17f31a31d7..8eb768bbf5b5 100644
--- a/fs/ext4/dir.c
+++ b/fs/ext4/dir.c
@@ -74,7 +74,7 @@ int __ext4_check_dir_entry(const char *function, unsigned int line,
else if (unlikely(rlen < EXT4_DIR_REC_LEN(de->name_len)))
error_msg = "rec_len is too small for name_len";
else if (unlikely(((char *) de - buf) + rlen > size))
- error_msg = "directory entry across range";
+ error_msg = "directory entry overrun";
else if (unlikely(le32_to_cpu(de->inode) >
le32_to_cpu(EXT4_SB(dir->i_sb)->s_es->s_inodes_count)))
error_msg = "inode out of bounds";
@@ -83,18 +83,16 @@ int __ext4_check_dir_entry(const char *function, unsigned int line,
if (filp)
ext4_error_file(filp, function, line, bh->b_blocknr,
- "bad entry in directory: %s - offset=%u(%u), "
- "inode=%u, rec_len=%d, name_len=%d",
- error_msg, (unsigned) (offset % size),
- offset, le32_to_cpu(de->inode),
- rlen, de->name_len);
+ "bad entry in directory: %s - offset=%u, "
+ "inode=%u, rec_len=%d, name_len=%d, size=%d",
+ error_msg, offset, le32_to_cpu(de->inode),
+ rlen, de->name_len, size);
else
ext4_error_inode(dir, function, line, bh->b_blocknr,
- "bad entry in directory: %s - offset=%u(%u), "
- "inode=%u, rec_len=%d, name_len=%d",
- error_msg, (unsigned) (offset % size),
- offset, le32_to_cpu(de->inode),
- rlen, de->name_len);
+ "bad entry in directory: %s - offset=%u, "
+ "inode=%u, rec_len=%d, name_len=%d, size=%d",
+ error_msg, offset, le32_to_cpu(de->inode),
+ rlen, de->name_len, size);
return 1;
}
diff --git a/fs/ext4/inline.c b/fs/ext4/inline.c
index 72883bc6fc32..f1375d3ad5c1 100644
--- a/fs/ext4/inline.c
+++ b/fs/ext4/inline.c
@@ -1770,6 +1770,7 @@ int empty_inline_dir(struct inode *dir, int *has_inline_data)
{
int err, inline_size;
struct ext4_iloc iloc;
+ size_t inline_len;
void *inline_pos;
unsigned int offset;
struct ext4_dir_entry_2 *de;
@@ -1797,8 +1798,9 @@ int empty_inline_dir(struct inode *dir, int *has_inline_data)
goto out;
}
+ inline_len = ext4_get_inline_size(dir);
offset = EXT4_INLINE_DOTDOT_SIZE;
- while (offset < dir->i_size) {
+ while (offset < inline_len) {
de = ext4_get_inline_entry(dir, &iloc, offset,
&inline_pos, &inline_size);
if (ext4_check_dir_entry(dir, NULL, de,
diff --git a/fs/ext4/mmp.c b/fs/ext4/mmp.c
index 0a512aa81bf7..4c9d799955d1 100644
--- a/fs/ext4/mmp.c
+++ b/fs/ext4/mmp.c
@@ -48,7 +48,6 @@ static int write_mmp_block(struct super_block *sb, struct buffer_head *bh)
*/
sb_start_write(sb);
ext4_mmp_csum_set(sb, mmp);
- mark_buffer_dirty(bh);
lock_buffer(bh);
bh->b_end_io = end_buffer_write_sync;
get_bh(bh);
diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c
index d2421fd38833..783280ebc2fe 100644
--- a/fs/ext4/resize.c
+++ b/fs/ext4/resize.c
@@ -18,6 +18,7 @@
int ext4_resize_begin(struct super_block *sb)
{
+ struct ext4_sb_info *sbi = EXT4_SB(sb);
int ret = 0;
if (!capable(CAP_SYS_RESOURCE))
@@ -28,7 +29,7 @@ int ext4_resize_begin(struct super_block *sb)
* because the user tools have no way of handling this. Probably a
* bad time to do it anyways.
*/
- if (EXT4_SB(sb)->s_sbh->b_blocknr !=
+ if (EXT4_B2C(sbi, sbi->s_sbh->b_blocknr) !=
le32_to_cpu(EXT4_SB(sb)->s_es->s_first_data_block)) {
ext4_warning(sb, "won't resize using backup superblock at %llu",
(unsigned long long)EXT4_SB(sb)->s_sbh->b_blocknr);
@@ -1954,6 +1955,26 @@ retry:
}
}
+ /*
+ * Make sure the last group has enough space so that it's
+ * guaranteed to have enough space for all metadata blocks
+ * that it might need to hold. (We might not need to store
+ * the inode table blocks in the last block group, but there
+ * will be cases where this might be needed.)
+ */
+ if ((ext4_group_first_block_no(sb, n_group) +
+ ext4_group_overhead_blocks(sb, n_group) + 2 +
+ sbi->s_itb_per_group + sbi->s_cluster_ratio) >= n_blocks_count) {
+ n_blocks_count = ext4_group_first_block_no(sb, n_group);
+ n_group--;
+ n_blocks_count_retry = 0;
+ if (resize_inode) {
+ iput(resize_inode);
+ resize_inode = NULL;
+ }
+ goto retry;
+ }
+
/* extend the last group */
if (n_group == o_group)
add = n_blocks_count - o_blocks_count;
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 71c9104a7779..959d734806cb 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -4023,11 +4023,13 @@ no_journal:
block = ext4_count_free_clusters(sb);
ext4_free_blocks_count_set(sbi->s_es,
EXT4_C2B(sbi, block));
+ ext4_superblock_csum_set(sb);
err = percpu_counter_init(&sbi->s_freeclusters_counter, block,
GFP_KERNEL);
if (!err) {
unsigned long freei = ext4_count_free_inodes(sb);
sbi->s_es->s_free_inodes_count = cpu_to_le32(freei);
+ ext4_superblock_csum_set(sb);
err = percpu_counter_init(&sbi->s_freeinodes_counter, freei,
GFP_KERNEL);
}