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

Commit ddba1bfc authored by Liu Bo's avatar Liu Bo Committed by Chris Mason
Browse files

Btrfs: fix warning of bytes_may_use



While running generic/019, dmesg got several warnings from
btrfs_free_reserved_data_space().

Test generic/019 produces some disk failures so sumbit dio will get errors,
in which case, btrfs_direct_IO() goes to the error handling and free
bytes_may_use, but the problem is that bytes_may_use has been free'd
during get_block().

This adds a runtime flag to show if we've gone through get_block(), if so,
don't do the cleanup work.

Signed-off-by: default avatarLiu Bo <bo.li.liu@oracle.com>
Reviewed-by: default avatarFilipe Manana <fdmanana@suse.com>
Tested-by: default avatarFilipe Manana <fdmanana@suse.com>
Signed-off-by: default avatarChris Mason <clm@fb.com>
parent ad9ee205
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -44,6 +44,8 @@
#define BTRFS_INODE_IN_DELALLOC_LIST		9
#define BTRFS_INODE_READDIO_NEED_LOCK		10
#define BTRFS_INODE_HAS_PROPS		        11
/* DIO is ready to submit */
#define BTRFS_INODE_DIO_READY		        12
/*
 * The following 3 bits are meant only for the btree inode.
 * When any of them is set, it means an error happened while writing an
+13 −3
Original line number Diff line number Diff line
@@ -7547,6 +7547,7 @@ static int btrfs_get_blocks_direct(struct inode *inode, sector_t iblock,

		current->journal_info = outstanding_extents;
		btrfs_free_reserved_data_space(inode, len);
		set_bit(BTRFS_INODE_DIO_READY, &BTRFS_I(inode)->runtime_flags);
	}

	/*
@@ -8357,9 +8358,18 @@ static ssize_t btrfs_direct_IO(struct kiocb *iocb, struct iov_iter *iter,
				   btrfs_submit_direct, flags);
	if (iov_iter_rw(iter) == WRITE) {
		current->journal_info = NULL;
		if (ret < 0 && ret != -EIOCBQUEUED)
		if (ret < 0 && ret != -EIOCBQUEUED) {
			/*
			 * If the error comes from submitting stage,
			 * btrfs_get_blocsk_direct() has free'd data space,
			 * and metadata space will be handled by
			 * finish_ordered_fn, don't do that again to make
			 * sure bytes_may_use is correct.
			 */
			if (!test_and_clear_bit(BTRFS_INODE_DIO_READY,
				     &BTRFS_I(inode)->runtime_flags))
				btrfs_delalloc_release_space(inode, count);
		else if (ret >= 0 && (size_t)ret < count)
		} else if (ret >= 0 && (size_t)ret < count)
			btrfs_delalloc_release_space(inode,
						     count - (size_t)ret);
	}