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

Commit 17403fa2 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:
 "Miscellaneous ext4 bug fixes for 5.1"

* tag 'ext4_for_linus_stable' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4:
  ext4: prohibit fstrim in norecovery mode
  ext4: cleanup bh release code in ext4_ind_remove_space()
  ext4: brelse all indirect buffer in ext4_ind_remove_space()
  ext4: report real fs size after failed resize
  ext4: add missing brelse() in add_new_gdb_meta_bg()
  ext4: remove useless ext4_pin_inode()
  ext4: avoid panic during forced reboot
  ext4: fix data corruption caused by unaligned direct AIO
  ext4: fix NULL pointer dereference while journal is aborted
parents 231c807a 18915b58
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -384,7 +384,7 @@ static inline void ext4_update_inode_fsync_trans(handle_t *handle,
{
	struct ext4_inode_info *ei = EXT4_I(inode);

	if (ext4_handle_valid(handle)) {
	if (ext4_handle_valid(handle) && !is_handle_aborted(handle)) {
		ei->i_sync_tid = handle->h_transaction->t_tid;
		if (datasync)
			ei->i_datasync_tid = handle->h_transaction->t_tid;
+1 −1
Original line number Diff line number Diff line
@@ -125,7 +125,7 @@ ext4_unaligned_aio(struct inode *inode, struct iov_iter *from, loff_t pos)
	struct super_block *sb = inode->i_sb;
	int blockmask = sb->s_blocksize - 1;

	if (pos >= i_size_read(inode))
	if (pos >= ALIGN(i_size_read(inode), sb->s_blocksize))
		return 0;

	if ((pos | iov_iter_alignment(from)) & blockmask)
+22 −21
Original line number Diff line number Diff line
@@ -1222,6 +1222,7 @@ int ext4_ind_remove_space(handle_t *handle, struct inode *inode,
	ext4_lblk_t offsets[4], offsets2[4];
	Indirect chain[4], chain2[4];
	Indirect *partial, *partial2;
	Indirect *p = NULL, *p2 = NULL;
	ext4_lblk_t max_block;
	__le32 nr = 0, nr2 = 0;
	int n = 0, n2 = 0;
@@ -1263,7 +1264,7 @@ int ext4_ind_remove_space(handle_t *handle, struct inode *inode,
		}


		partial = ext4_find_shared(inode, n, offsets, chain, &nr);
		partial = p = ext4_find_shared(inode, n, offsets, chain, &nr);
		if (nr) {
			if (partial == chain) {
				/* Shared branch grows from the inode */
@@ -1288,13 +1289,11 @@ int ext4_ind_remove_space(handle_t *handle, struct inode *inode,
				partial->p + 1,
				(__le32 *)partial->bh->b_data+addr_per_block,
				(chain+n-1) - partial);
			BUFFER_TRACE(partial->bh, "call brelse");
			brelse(partial->bh);
			partial--;
		}

end_range:
		partial2 = ext4_find_shared(inode, n2, offsets2, chain2, &nr2);
		partial2 = p2 = ext4_find_shared(inode, n2, offsets2, chain2, &nr2);
		if (nr2) {
			if (partial2 == chain2) {
				/*
@@ -1324,16 +1323,14 @@ int ext4_ind_remove_space(handle_t *handle, struct inode *inode,
					   (__le32 *)partial2->bh->b_data,
					   partial2->p,
					   (chain2+n2-1) - partial2);
			BUFFER_TRACE(partial2->bh, "call brelse");
			brelse(partial2->bh);
			partial2--;
		}
		goto do_indirects;
	}

	/* Punch happened within the same level (n == n2) */
	partial = ext4_find_shared(inode, n, offsets, chain, &nr);
	partial2 = ext4_find_shared(inode, n2, offsets2, chain2, &nr2);
	partial = p = ext4_find_shared(inode, n, offsets, chain, &nr);
	partial2 = p2 = ext4_find_shared(inode, n2, offsets2, chain2, &nr2);

	/* Free top, but only if partial2 isn't its subtree. */
	if (nr) {
@@ -1390,11 +1387,7 @@ int ext4_ind_remove_space(handle_t *handle, struct inode *inode,
					   partial->p + 1,
					   partial2->p,
					   (chain+n-1) - partial);
			BUFFER_TRACE(partial->bh, "call brelse");
			brelse(partial->bh);
			BUFFER_TRACE(partial2->bh, "call brelse");
			brelse(partial2->bh);
			return 0;
			goto cleanup;
		}

		/*
@@ -1409,8 +1402,6 @@ int ext4_ind_remove_space(handle_t *handle, struct inode *inode,
					   partial->p + 1,
					   (__le32 *)partial->bh->b_data+addr_per_block,
					   (chain+n-1) - partial);
			BUFFER_TRACE(partial->bh, "call brelse");
			brelse(partial->bh);
			partial--;
		}
		if (partial2 > chain2 && depth2 <= depth) {
@@ -1418,11 +1409,21 @@ int ext4_ind_remove_space(handle_t *handle, struct inode *inode,
					   (__le32 *)partial2->bh->b_data,
					   partial2->p,
					   (chain2+n2-1) - partial2);
			BUFFER_TRACE(partial2->bh, "call brelse");
			brelse(partial2->bh);
			partial2--;
		}
	}

cleanup:
	while (p && p > chain) {
		BUFFER_TRACE(p->bh, "call brelse");
		brelse(p->bh);
		p--;
	}
	while (p2 && p2 > chain2) {
		BUFFER_TRACE(p2->bh, "call brelse");
		brelse(p2->bh);
		p2--;
	}
	return 0;

do_indirects:
@@ -1430,7 +1431,7 @@ int ext4_ind_remove_space(handle_t *handle, struct inode *inode,
	switch (offsets[0]) {
	default:
		if (++n >= n2)
			return 0;
			break;
		nr = i_data[EXT4_IND_BLOCK];
		if (nr) {
			ext4_free_branches(handle, inode, NULL, &nr, &nr+1, 1);
@@ -1439,7 +1440,7 @@ int ext4_ind_remove_space(handle_t *handle, struct inode *inode,
		/* fall through */
	case EXT4_IND_BLOCK:
		if (++n >= n2)
			return 0;
			break;
		nr = i_data[EXT4_DIND_BLOCK];
		if (nr) {
			ext4_free_branches(handle, inode, NULL, &nr, &nr+1, 2);
@@ -1448,7 +1449,7 @@ int ext4_ind_remove_space(handle_t *handle, struct inode *inode,
		/* fall through */
	case EXT4_DIND_BLOCK:
		if (++n >= n2)
			return 0;
			break;
		nr = i_data[EXT4_TIND_BLOCK];
		if (nr) {
			ext4_free_branches(handle, inode, NULL, &nr, &nr+1, 3);
@@ -1458,5 +1459,5 @@ int ext4_ind_remove_space(handle_t *handle, struct inode *inode,
	case EXT4_TIND_BLOCK:
		;
	}
	return 0;
	goto cleanup;
}
+0 −30
Original line number Diff line number Diff line
@@ -6080,36 +6080,6 @@ void ext4_dirty_inode(struct inode *inode, int flags)
	return;
}

#if 0
/*
 * Bind an inode's backing buffer_head into this transaction, to prevent
 * it from being flushed to disk early.  Unlike
 * ext4_reserve_inode_write, this leaves behind no bh reference and
 * returns no iloc structure, so the caller needs to repeat the iloc
 * lookup to mark the inode dirty later.
 */
static int ext4_pin_inode(handle_t *handle, struct inode *inode)
{
	struct ext4_iloc iloc;

	int err = 0;
	if (handle) {
		err = ext4_get_inode_loc(inode, &iloc);
		if (!err) {
			BUFFER_TRACE(iloc.bh, "get_write_access");
			err = jbd2_journal_get_write_access(handle, iloc.bh);
			if (!err)
				err = ext4_handle_dirty_metadata(handle,
								 NULL,
								 iloc.bh);
			brelse(iloc.bh);
		}
	}
	ext4_std_error(inode->i_sb, err);
	return err;
}
#endif

int ext4_change_inode_journal_flag(struct inode *inode, int val)
{
	journal_t *journal;
+7 −0
Original line number Diff line number Diff line
@@ -1000,6 +1000,13 @@ long ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
		if (!blk_queue_discard(q))
			return -EOPNOTSUPP;

		/*
		 * We haven't replayed the journal, so we cannot use our
		 * block-bitmap-guided storage zapping commands.
		 */
		if (test_opt(sb, NOLOAD) && ext4_has_feature_journal(sb))
			return -EROFS;

		if (copy_from_user(&range, (struct fstrim_range __user *)arg,
		    sizeof(range)))
			return -EFAULT;
Loading