summaryrefslogtreecommitdiffstats
path: root/fs/btrfs/ordered-data.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-02-25 14:53:58 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2017-02-25 14:53:58 -0800
commit9003ed1fed2a3fe2774a6b67dcbe1ab31d7f8ec3 (patch)
treeb388bb693b2c40a9f6fcba8612e45654fca28b49 /fs/btrfs/ordered-data.c
parent94eae8034002401d71ae950106659e16add36e77 (diff)
parent6288d6eabc7505f42dda34a2c2962f91914be3a4 (diff)
downloadlinux-9003ed1fed2a3fe2774a6b67dcbe1ab31d7f8ec3.tar.bz2
Merge branch 'for-linus-4.11' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs
Pull btrfs updates from Chris Mason: "This has a series of fixes and cleanups that Dave Sterba has been collecting. There is a pretty big variety here, cleaning up internal APIs and fixing corner cases" * 'for-linus-4.11' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs: (124 commits) Btrfs: use the correct type when creating cow dio extent Btrfs: fix deadlock between dedup on same file and starting writeback btrfs: use btrfs_debug instead of pr_debug in transaction abort btrfs: btrfs_truncate_free_space_cache always allocates path btrfs: free-space-cache, clean up unnecessary root arguments btrfs: convert btrfs_inc_block_group_ro to accept fs_info btrfs: flush_space always takes fs_info->fs_root btrfs: pass fs_info to (more) routines that are only called with extent_root btrfs: qgroup: Move half of the qgroup accounting time out of commit trans btrfs: remove unused parameter from adjust_slots_upwards btrfs: remove unused parameters from __btrfs_write_out_cache btrfs: remove unused parameter from cleanup_write_cache_enospc btrfs: remove unused parameter from __add_inode_ref btrfs: remove unused parameter from clone_copy_inline_extent btrfs: remove unused parameters from btrfs_cmp_data btrfs: remove unused parameter from __add_inline_refs btrfs: remove unused parameters from scrub_setup_wr_ctx btrfs: remove unused parameter from create_snapshot btrfs: remove unused parameter from init_first_rw_device btrfs: remove unused parameter from __btrfs_alloc_chunk ...
Diffstat (limited to 'fs/btrfs/ordered-data.c')
-rw-r--r--fs/btrfs/ordered-data.c47
1 files changed, 27 insertions, 20 deletions
diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c
index 041c3326d109..bc2aba810629 100644
--- a/fs/btrfs/ordered-data.c
+++ b/fs/btrfs/ordered-data.c
@@ -432,7 +432,7 @@ out:
}
/* Needs to either be called under a log transaction or the log_mutex */
-void btrfs_get_logged_extents(struct inode *inode,
+void btrfs_get_logged_extents(struct btrfs_inode *inode,
struct list_head *logged_list,
const loff_t start,
const loff_t end)
@@ -442,7 +442,7 @@ void btrfs_get_logged_extents(struct inode *inode,
struct rb_node *n;
struct rb_node *prev;
- tree = &BTRFS_I(inode)->ordered_tree;
+ tree = &inode->ordered_tree;
spin_lock_irq(&tree->lock);
n = __tree_search(&tree->tree, end, &prev);
if (!n)
@@ -984,8 +984,18 @@ int btrfs_ordered_update_i_size(struct inode *inode, u64 offset,
}
disk_i_size = BTRFS_I(inode)->disk_i_size;
- /* truncate file */
- if (disk_i_size > i_size) {
+ /*
+ * truncate file.
+ * If ordered is not NULL, then this is called from endio and
+ * disk_i_size will be updated by either truncate itself or any
+ * in-flight IOs which are inside the disk_i_size.
+ *
+ * Because btrfs_setsize() may set i_size with disk_i_size if truncate
+ * fails somehow, we need to make sure we have a precise disk_i_size by
+ * updating it as usual.
+ *
+ */
+ if (!ordered && disk_i_size > i_size) {
BTRFS_I(inode)->disk_i_size = orig_offset;
ret = 0;
goto out;
@@ -1032,25 +1042,22 @@ int btrfs_ordered_update_i_size(struct inode *inode, u64 offset,
/* We treat this entry as if it doesn't exist */
if (test_bit(BTRFS_ORDERED_UPDATED_ISIZE, &test->flags))
continue;
- if (test->file_offset + test->len <= disk_i_size)
+
+ if (entry_end(test) <= disk_i_size)
break;
if (test->file_offset >= i_size)
break;
- if (entry_end(test) > disk_i_size) {
- /*
- * we don't update disk_i_size now, so record this
- * undealt i_size. Or we will not know the real
- * i_size.
- */
- if (test->outstanding_isize < offset)
- test->outstanding_isize = offset;
- if (ordered &&
- ordered->outstanding_isize >
- test->outstanding_isize)
- test->outstanding_isize =
- ordered->outstanding_isize;
- goto out;
- }
+
+ /*
+ * We don't update disk_i_size now, so record this undealt
+ * i_size. Or we will not know the real i_size.
+ */
+ if (test->outstanding_isize < offset)
+ test->outstanding_isize = offset;
+ if (ordered &&
+ ordered->outstanding_isize > test->outstanding_isize)
+ test->outstanding_isize = ordered->outstanding_isize;
+ goto out;
}
new_i_size = min_t(u64, offset, i_size);