aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/ordered-data.c
diff options
context:
space:
mode:
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 1ddb7bceea99..c2b4a9c4ddb6 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,
324void btrfs_wait_ordered_range(struct inode *inode, u64 start, u64 len) 324void btrfs_wait_ordered_range(struct inode *inode, u64 start, u64 len)
325{ 325{
326 u64 end; 326 u64 end;
327 u64 orig_end;
328 u64 wait_end;
327 struct btrfs_ordered_extent *ordered; 329 struct btrfs_ordered_extent *ordered;
328 int found; 330 u64 mask = BTRFS_I(inode)->root->sectorsize - 1;
329 int should_wait = 0; 331
330 332 if (start + len < start) {
331again: 333 wait_end = (inode->i_size + mask) & ~mask;
332 if (start + len < start) 334 orig_end = (u64)-1;
333 end = (u64)-1; 335 } else {
334 else 336 orig_end = start + len - 1;
335 end = start + len - 1; 337 wait_end = orig_end;
336 found = 0; 338 }
339
340 /* start IO across the range first to instantiate any delalloc
341 * extents
342 */
343#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22)
344 do_sync_file_range(file, start, wait_end, SYNC_FILE_RANGE_WRITE);
345#else
346 do_sync_mapping_range(inode->i_mapping, start, wait_end,
347 SYNC_FILE_RANGE_WRITE);
348#endif
349 end = orig_end;
350 wait_on_extent_writeback(&BTRFS_I(inode)->io_tree, start, orig_end);
351
337 while(1) { 352 while(1) {
338 ordered = btrfs_lookup_first_ordered_extent(inode, end); 353 ordered = btrfs_lookup_first_ordered_extent(inode, end);
339 if (!ordered) { 354 if (!ordered) {
340 break; 355 break;
341 } 356 }
342 if (ordered->file_offset >= start + len) { 357 if (ordered->file_offset > orig_end) {
343 btrfs_put_ordered_extent(ordered); 358 btrfs_put_ordered_extent(ordered);
344 break; 359 break;
345 } 360 }
@@ -347,21 +362,15 @@ again:
347 btrfs_put_ordered_extent(ordered); 362 btrfs_put_ordered_extent(ordered);
348 break; 363 break;
349 } 364 }
350 btrfs_start_ordered_extent(inode, ordered, should_wait); 365 btrfs_start_ordered_extent(inode, ordered, 1);
351 found++;
352 end = ordered->file_offset; 366 end = ordered->file_offset;
353 btrfs_put_ordered_extent(ordered); 367 btrfs_put_ordered_extent(ordered);
354 if (end == 0) 368 if (end == 0 || end == start)
355 break; 369 break;
356 end--; 370 end--;
357 } 371 }
358 if (should_wait && found) {
359 should_wait = 0;
360 goto again;
361 }
362} 372}
363 373
364
365/* 374/*
366 * find an ordered extent corresponding to file_offset. return NULL if 375 * find an ordered extent corresponding to file_offset. return NULL if
367 * nothing is found, otherwise take a reference on the extent and return it 376 * nothing is found, otherwise take a reference on the extent and return it