diff options
author | Liu Bo <bo.li.liu@oracle.com> | 2015-06-17 16:59:58 +0800 |
---|---|---|
committer | Chris Mason <clm@fb.com> | 2015-07-01 17:17:21 -0700 |
commit | ddba1bfc2369cd0566bcfdab47599834a32d1c19 (patch) | |
tree | 81924f0b14728137202db0732582cfa5f05d6703 /fs/btrfs/inode.c | |
parent | ad9ee2053f3f2babebc09ebc4970daa66c56c7ee (diff) | |
download | op-kernel-dev-ddba1bfc2369cd0566bcfdab47599834a32d1c19.zip op-kernel-dev-ddba1bfc2369cd0566bcfdab47599834a32d1c19.tar.gz |
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: 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>
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r-- | fs/btrfs/inode.c | 16 |
1 files changed, 13 insertions, 3 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 0b9fb81..b33c0cf 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -7547,6 +7547,7 @@ unlock: 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) - 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); } |