Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3cfb6772 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'ext4_for_linus_stable' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4

Pull ext4 fixes from Ted Ts'o:
 "Some miscellaneous ext4 fixes for 4.18; one fix is for a regression
  introduced in 4.18-rc4.

  Sorry for the late-breaking pull. I was originally going to wait for
  the next merge window, but Eric Whitney found a regression introduced
  in 4.18-rc4, so I decided to push out the regression plus the other
  fixes now. (The other commits have been baking in linux-next since
  early July)"

* tag 'ext4_for_linus_stable' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4:
  ext4: fix check to prevent initializing reserved inodes
  ext4: check for allocation block validity with block group locked
  ext4: fix inline data updates with checksums enabled
  ext4: clear mmp sequence number when remounting read-only
  ext4: fix false negatives *and* false positives in ext4_check_descriptors()
parents 01cfb793 50122847
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -368,6 +368,8 @@ static int ext4_validate_block_bitmap(struct super_block *sb,
		return -EFSCORRUPTED;

	ext4_lock_group(sb, block_group);
	if (buffer_verified(bh))
		goto verified;
	if (unlikely(!ext4_block_bitmap_csum_verify(sb, block_group,
			desc, bh))) {
		ext4_unlock_group(sb, block_group);
@@ -386,6 +388,7 @@ static int ext4_validate_block_bitmap(struct super_block *sb,
		return -EFSCORRUPTED;
	}
	set_buffer_verified(bh);
verified:
	ext4_unlock_group(sb, block_group);
	return 0;
}
+7 −1
Original line number Diff line number Diff line
@@ -90,6 +90,8 @@ static int ext4_validate_inode_bitmap(struct super_block *sb,
		return -EFSCORRUPTED;

	ext4_lock_group(sb, block_group);
	if (buffer_verified(bh))
		goto verified;
	blk = ext4_inode_bitmap(sb, desc);
	if (!ext4_inode_bitmap_csum_verify(sb, block_group, desc, bh,
					   EXT4_INODES_PER_GROUP(sb) / 8)) {
@@ -101,6 +103,7 @@ static int ext4_validate_inode_bitmap(struct super_block *sb,
		return -EFSBADCRC;
	}
	set_buffer_verified(bh);
verified:
	ext4_unlock_group(sb, block_group);
	return 0;
}
@@ -1385,7 +1388,10 @@ int ext4_init_inode_table(struct super_block *sb, ext4_group_t group,
			    ext4_itable_unused_count(sb, gdp)),
			    sbi->s_inodes_per_block);

	if ((used_blks < 0) || (used_blks > sbi->s_itb_per_group)) {
	if ((used_blks < 0) || (used_blks > sbi->s_itb_per_group) ||
	    ((group == 0) && ((EXT4_INODES_PER_GROUP(sb) -
			       ext4_itable_unused_count(sb, gdp)) <
			      EXT4_FIRST_INO(sb)))) {
		ext4_error(sb, "Something is wrong with group %u: "
			   "used itable blocks: %d; "
			   "itable unused count: %u",
+11 −8
Original line number Diff line number Diff line
@@ -682,6 +682,10 @@ int ext4_try_to_write_inline_data(struct address_space *mapping,
		goto convert;
	}

	ret = ext4_journal_get_write_access(handle, iloc.bh);
	if (ret)
		goto out;

	flags |= AOP_FLAG_NOFS;

	page = grab_cache_page_write_begin(mapping, 0, flags);
@@ -710,7 +714,7 @@ int ext4_try_to_write_inline_data(struct address_space *mapping,
out_up_read:
	up_read(&EXT4_I(inode)->xattr_sem);
out:
	if (handle)
	if (handle && (ret != 1))
		ext4_journal_stop(handle);
	brelse(iloc.bh);
	return ret;
@@ -752,6 +756,7 @@ int ext4_write_inline_data_end(struct inode *inode, loff_t pos, unsigned len,

	ext4_write_unlock_xattr(inode, &no_expand);
	brelse(iloc.bh);
	mark_inode_dirty(inode);
out:
	return copied;
}
@@ -898,7 +903,6 @@ int ext4_da_write_inline_data_begin(struct address_space *mapping,
		goto out;
	}


	page = grab_cache_page_write_begin(mapping, 0, flags);
	if (!page) {
		ret = -ENOMEM;
@@ -916,6 +920,9 @@ int ext4_da_write_inline_data_begin(struct address_space *mapping,
		if (ret < 0)
			goto out_release_page;
	}
	ret = ext4_journal_get_write_access(handle, iloc.bh);
	if (ret)
		goto out_release_page;

	up_read(&EXT4_I(inode)->xattr_sem);
	*pagep = page;
@@ -936,7 +943,6 @@ int ext4_da_write_inline_data_end(struct inode *inode, loff_t pos,
				  unsigned len, unsigned copied,
				  struct page *page)
{
	int i_size_changed = 0;
	int ret;

	ret = ext4_write_inline_data_end(inode, pos, len, copied, page);
@@ -954,10 +960,8 @@ int ext4_da_write_inline_data_end(struct inode *inode, loff_t pos,
	 * But it's important to update i_size while still holding page lock:
	 * page writeout could otherwise come in and zero beyond i_size.
	 */
	if (pos+copied > inode->i_size) {
	if (pos+copied > inode->i_size)
		i_size_write(inode, pos+copied);
		i_size_changed = 1;
	}
	unlock_page(page);
	put_page(page);

@@ -967,7 +971,6 @@ int ext4_da_write_inline_data_end(struct inode *inode, loff_t pos,
	 * ordering of page lock and transaction start for journaling
	 * filesystems.
	 */
	if (i_size_changed)
	mark_inode_dirty(inode);

	return copied;
+7 −9
Original line number Diff line number Diff line
@@ -1389,9 +1389,10 @@ static int ext4_write_end(struct file *file,
	loff_t old_size = inode->i_size;
	int ret = 0, ret2;
	int i_size_changed = 0;
	int inline_data = ext4_has_inline_data(inode);

	trace_ext4_write_end(inode, pos, len, copied);
	if (ext4_has_inline_data(inode)) {
	if (inline_data) {
		ret = ext4_write_inline_data_end(inode, pos, len,
						 copied, page);
		if (ret < 0) {
@@ -1419,7 +1420,7 @@ static int ext4_write_end(struct file *file,
	 * ordering of page lock and transaction start for journaling
	 * filesystems.
	 */
	if (i_size_changed)
	if (i_size_changed || inline_data)
		ext4_mark_inode_dirty(handle, inode);

	if (pos + len > inode->i_size && ext4_can_truncate(inode))
@@ -1493,6 +1494,7 @@ static int ext4_journalled_write_end(struct file *file,
	int partial = 0;
	unsigned from, to;
	int size_changed = 0;
	int inline_data = ext4_has_inline_data(inode);

	trace_ext4_journalled_write_end(inode, pos, len, copied);
	from = pos & (PAGE_SIZE - 1);
@@ -1500,7 +1502,7 @@ static int ext4_journalled_write_end(struct file *file,

	BUG_ON(!ext4_handle_valid(handle));

	if (ext4_has_inline_data(inode)) {
	if (inline_data) {
		ret = ext4_write_inline_data_end(inode, pos, len,
						 copied, page);
		if (ret < 0) {
@@ -1531,7 +1533,7 @@ static int ext4_journalled_write_end(struct file *file,
	if (old_size < pos)
		pagecache_isize_extended(inode, old_size, pos);

	if (size_changed) {
	if (size_changed || inline_data) {
		ret2 = ext4_mark_inode_dirty(handle, inode);
		if (!ret)
			ret = ret2;
@@ -2028,11 +2030,7 @@ static int __ext4_journalled_writepage(struct page *page,
	}

	if (inline_data) {
		BUFFER_TRACE(inode_bh, "get write access");
		ret = ext4_journal_get_write_access(handle, inode_bh);

		err = ext4_handle_dirty_metadata(handle, inode, inode_bh);

		ret = ext4_mark_inode_dirty(handle, inode);
	} else {
		ret = ext4_walk_page_buffers(handle, page_bufs, 0, len, NULL,
					     do_journal_get_write_access);
+2 −5
Original line number Diff line number Diff line
@@ -186,11 +186,8 @@ static int kmmpd(void *data)
			goto exit_thread;
		}

		if (sb_rdonly(sb)) {
			ext4_warning(sb, "kmmpd being stopped since filesystem "
				     "has been remounted as readonly.");
			goto exit_thread;
		}
		if (sb_rdonly(sb))
			break;

		diff = jiffies - last_update_time;
		if (diff < mmp_update_interval * HZ)
Loading