Skip to content

Commit

Permalink
Btrfs: fix warning of bytes_may_use
Browse files Browse the repository at this point in the history
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: Liu Bo <bo.li.liu@oracle.com>
Reviewed-by: Filipe Manana <fdmanana@suse.com>
Tested-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: Chris Mason <clm@fb.com>
  • Loading branch information
Liu Bo authored and Chris Mason committed Jul 2, 2015
1 parent ad9ee20 commit ddba1bf
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 3 deletions.
2 changes: 2 additions & 0 deletions fs/btrfs/btrfs_inode.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
16 changes: 13 additions & 3 deletions fs/btrfs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

/*
Expand Down Expand Up @@ -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)
btrfs_delalloc_release_space(inode, count);
else if (ret >= 0 && (size_t)ret < count)
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)
btrfs_delalloc_release_space(inode,
count - (size_t)ret);
}
Expand Down

0 comments on commit ddba1bf

Please sign in to comment.