summaryrefslogtreecommitdiffstats
path: root/fs/btrfs/ordered-data.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2008-07-18 20:42:20 -0400
committerChris Mason <chris.mason@oracle.com>2008-09-25 11:04:05 -0400
commite5a2217ef6ff088d08a27208929a6f9c635d672c (patch)
tree47dfed451e11357a5e066180eebba8db942af2b3 /fs/btrfs/ordered-data.c
parent7f3c74fb831fa19bafe087e817c0a5ff3883f1ea (diff)
Fix btrfs_wait_ordered_extent_range to properly wait
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/ordered-data.c')
-rw-r--r--fs/btrfs/ordered-data.c45
1 files changed, 27 insertions, 18 deletions
diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c
index 1ddb7bceea9..c2b4a9c4ddb 100644
--- a/fs/btrfs/ordered-data.c
+++ b/fs/btrfs/ordered-data.c
@@ -324,22 +324,37 @@ void btrfs_start_ordered_extent(struct inode *inode,
void btrfs_wait_ordered_range(struct inode *inode, u64 start, u64 len)
{
u64 end;
+ u64 orig_end;
+ u64 wait_end;
struct btrfs_ordered_extent *ordered;
- int found;
- int should_wait = 0;
-
-again:
- if (start + len < start)
- end = (u64)-1;
- else
- end = start + len - 1;
- found = 0;
+ u64 mask = BTRFS_I(inode)->root->sectorsize - 1;
+
+ if (start + len < start) {
+ wait_end = (inode->i_size + mask) & ~mask;
+ orig_end = (u64)-1;
+ } else {
+ orig_end = start + len - 1;
+ wait_end = orig_end;
+ }
+
+ /* start IO across the range first to instantiate any delalloc
+ * extents
+ */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22)
+ do_sync_file_range(file, start, wait_end, SYNC_FILE_RANGE_WRITE);
+#else
+ do_sync_mapping_range(inode->i_mapping, start, wait_end,
+ SYNC_FILE_RANGE_WRITE);
+#endif
+ end = orig_end;
+ wait_on_extent_writeback(&BTRFS_I(inode)->io_tree, start, orig_end);
+
while(1) {
ordered = btrfs_lookup_first_ordered_extent(inode, end);
if (!ordered) {
break;
}
- if (ordered->file_offset >= start + len) {
+ if (ordered->file_offset > orig_end) {
btrfs_put_ordered_extent(ordered);
break;
}
@@ -347,21 +362,15 @@ again:
btrfs_put_ordered_extent(ordered);
break;
}
- btrfs_start_ordered_extent(inode, ordered, should_wait);
- found++;
+ btrfs_start_ordered_extent(inode, ordered, 1);
end = ordered->file_offset;
btrfs_put_ordered_extent(ordered);
- if (end == 0)
+ if (end == 0 || end == start)
break;
end--;
}
- if (should_wait && found) {
- should_wait = 0;
- goto again;
- }
}
-
/*
* find an ordered extent corresponding to file_offset. return NULL if
* nothing is found, otherwise take a reference on the extent and return it