diff options
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r-- | fs/btrfs/inode.c | 152 |
1 files changed, 111 insertions, 41 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index ff0dcc016b71..e687bb0dc73a 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -382,7 +382,7 @@ static inline int inode_need_compress(struct inode *inode) | |||
382 | * are written in the same order that the flusher thread sent them | 382 | * are written in the same order that the flusher thread sent them |
383 | * down. | 383 | * down. |
384 | */ | 384 | */ |
385 | static noinline int compress_file_range(struct inode *inode, | 385 | static noinline void compress_file_range(struct inode *inode, |
386 | struct page *locked_page, | 386 | struct page *locked_page, |
387 | u64 start, u64 end, | 387 | u64 start, u64 end, |
388 | struct async_cow *async_cow, | 388 | struct async_cow *async_cow, |
@@ -411,14 +411,6 @@ static noinline int compress_file_range(struct inode *inode, | |||
411 | (start > 0 || end + 1 < BTRFS_I(inode)->disk_i_size)) | 411 | (start > 0 || end + 1 < BTRFS_I(inode)->disk_i_size)) |
412 | btrfs_add_inode_defrag(NULL, inode); | 412 | btrfs_add_inode_defrag(NULL, inode); |
413 | 413 | ||
414 | /* | ||
415 | * skip compression for a small file range(<=blocksize) that | ||
416 | * isn't an inline extent, since it dosen't save disk space at all. | ||
417 | */ | ||
418 | if ((end - start + 1) <= blocksize && | ||
419 | (start > 0 || end + 1 < BTRFS_I(inode)->disk_i_size)) | ||
420 | goto cleanup_and_bail_uncompressed; | ||
421 | |||
422 | actual_end = min_t(u64, isize, end + 1); | 414 | actual_end = min_t(u64, isize, end + 1); |
423 | again: | 415 | again: |
424 | will_compress = 0; | 416 | will_compress = 0; |
@@ -440,6 +432,14 @@ again: | |||
440 | 432 | ||
441 | total_compressed = actual_end - start; | 433 | total_compressed = actual_end - start; |
442 | 434 | ||
435 | /* | ||
436 | * skip compression for a small file range(<=blocksize) that | ||
437 | * isn't an inline extent, since it dosen't save disk space at all. | ||
438 | */ | ||
439 | if (total_compressed <= blocksize && | ||
440 | (start > 0 || end + 1 < BTRFS_I(inode)->disk_i_size)) | ||
441 | goto cleanup_and_bail_uncompressed; | ||
442 | |||
443 | /* we want to make sure that amount of ram required to uncompress | 443 | /* we want to make sure that amount of ram required to uncompress |
444 | * an extent is reasonable, so we limit the total size in ram | 444 | * an extent is reasonable, so we limit the total size in ram |
445 | * of a compressed extent to 128k. This is a crucial number | 445 | * of a compressed extent to 128k. This is a crucial number |
@@ -527,7 +527,10 @@ cont: | |||
527 | if (ret <= 0) { | 527 | if (ret <= 0) { |
528 | unsigned long clear_flags = EXTENT_DELALLOC | | 528 | unsigned long clear_flags = EXTENT_DELALLOC | |
529 | EXTENT_DEFRAG; | 529 | EXTENT_DEFRAG; |
530 | unsigned long page_error_op; | ||
531 | |||
530 | clear_flags |= (ret < 0) ? EXTENT_DO_ACCOUNTING : 0; | 532 | clear_flags |= (ret < 0) ? EXTENT_DO_ACCOUNTING : 0; |
533 | page_error_op = ret < 0 ? PAGE_SET_ERROR : 0; | ||
531 | 534 | ||
532 | /* | 535 | /* |
533 | * inline extent creation worked or returned error, | 536 | * inline extent creation worked or returned error, |
@@ -538,6 +541,7 @@ cont: | |||
538 | clear_flags, PAGE_UNLOCK | | 541 | clear_flags, PAGE_UNLOCK | |
539 | PAGE_CLEAR_DIRTY | | 542 | PAGE_CLEAR_DIRTY | |
540 | PAGE_SET_WRITEBACK | | 543 | PAGE_SET_WRITEBACK | |
544 | page_error_op | | ||
541 | PAGE_END_WRITEBACK); | 545 | PAGE_END_WRITEBACK); |
542 | goto free_pages_out; | 546 | goto free_pages_out; |
543 | } | 547 | } |
@@ -620,8 +624,7 @@ cleanup_and_bail_uncompressed: | |||
620 | *num_added += 1; | 624 | *num_added += 1; |
621 | } | 625 | } |
622 | 626 | ||
623 | out: | 627 | return; |
624 | return ret; | ||
625 | 628 | ||
626 | free_pages_out: | 629 | free_pages_out: |
627 | for (i = 0; i < nr_pages_ret; i++) { | 630 | for (i = 0; i < nr_pages_ret; i++) { |
@@ -629,8 +632,22 @@ free_pages_out: | |||
629 | page_cache_release(pages[i]); | 632 | page_cache_release(pages[i]); |
630 | } | 633 | } |
631 | kfree(pages); | 634 | kfree(pages); |
635 | } | ||
632 | 636 | ||
633 | goto out; | 637 | static void free_async_extent_pages(struct async_extent *async_extent) |
638 | { | ||
639 | int i; | ||
640 | |||
641 | if (!async_extent->pages) | ||
642 | return; | ||
643 | |||
644 | for (i = 0; i < async_extent->nr_pages; i++) { | ||
645 | WARN_ON(async_extent->pages[i]->mapping); | ||
646 | page_cache_release(async_extent->pages[i]); | ||
647 | } | ||
648 | kfree(async_extent->pages); | ||
649 | async_extent->nr_pages = 0; | ||
650 | async_extent->pages = NULL; | ||
634 | } | 651 | } |
635 | 652 | ||
636 | /* | 653 | /* |
@@ -639,7 +656,7 @@ free_pages_out: | |||
639 | * queued. We walk all the async extents created by compress_file_range | 656 | * queued. We walk all the async extents created by compress_file_range |
640 | * and send them down to the disk. | 657 | * and send them down to the disk. |
641 | */ | 658 | */ |
642 | static noinline int submit_compressed_extents(struct inode *inode, | 659 | static noinline void submit_compressed_extents(struct inode *inode, |
643 | struct async_cow *async_cow) | 660 | struct async_cow *async_cow) |
644 | { | 661 | { |
645 | struct async_extent *async_extent; | 662 | struct async_extent *async_extent; |
@@ -651,9 +668,6 @@ static noinline int submit_compressed_extents(struct inode *inode, | |||
651 | struct extent_io_tree *io_tree; | 668 | struct extent_io_tree *io_tree; |
652 | int ret = 0; | 669 | int ret = 0; |
653 | 670 | ||
654 | if (list_empty(&async_cow->extents)) | ||
655 | return 0; | ||
656 | |||
657 | again: | 671 | again: |
658 | while (!list_empty(&async_cow->extents)) { | 672 | while (!list_empty(&async_cow->extents)) { |
659 | async_extent = list_entry(async_cow->extents.next, | 673 | async_extent = list_entry(async_cow->extents.next, |
@@ -709,15 +723,7 @@ retry: | |||
709 | async_extent->compressed_size, | 723 | async_extent->compressed_size, |
710 | 0, alloc_hint, &ins, 1, 1); | 724 | 0, alloc_hint, &ins, 1, 1); |
711 | if (ret) { | 725 | if (ret) { |
712 | int i; | 726 | free_async_extent_pages(async_extent); |
713 | |||
714 | for (i = 0; i < async_extent->nr_pages; i++) { | ||
715 | WARN_ON(async_extent->pages[i]->mapping); | ||
716 | page_cache_release(async_extent->pages[i]); | ||
717 | } | ||
718 | kfree(async_extent->pages); | ||
719 | async_extent->nr_pages = 0; | ||
720 | async_extent->pages = NULL; | ||
721 | 727 | ||
722 | if (ret == -ENOSPC) { | 728 | if (ret == -ENOSPC) { |
723 | unlock_extent(io_tree, async_extent->start, | 729 | unlock_extent(io_tree, async_extent->start, |
@@ -814,15 +820,26 @@ retry: | |||
814 | ins.objectid, | 820 | ins.objectid, |
815 | ins.offset, async_extent->pages, | 821 | ins.offset, async_extent->pages, |
816 | async_extent->nr_pages); | 822 | async_extent->nr_pages); |
823 | if (ret) { | ||
824 | struct extent_io_tree *tree = &BTRFS_I(inode)->io_tree; | ||
825 | struct page *p = async_extent->pages[0]; | ||
826 | const u64 start = async_extent->start; | ||
827 | const u64 end = start + async_extent->ram_size - 1; | ||
828 | |||
829 | p->mapping = inode->i_mapping; | ||
830 | tree->ops->writepage_end_io_hook(p, start, end, | ||
831 | NULL, 0); | ||
832 | p->mapping = NULL; | ||
833 | extent_clear_unlock_delalloc(inode, start, end, NULL, 0, | ||
834 | PAGE_END_WRITEBACK | | ||
835 | PAGE_SET_ERROR); | ||
836 | free_async_extent_pages(async_extent); | ||
837 | } | ||
817 | alloc_hint = ins.objectid + ins.offset; | 838 | alloc_hint = ins.objectid + ins.offset; |
818 | kfree(async_extent); | 839 | kfree(async_extent); |
819 | if (ret) | ||
820 | goto out; | ||
821 | cond_resched(); | 840 | cond_resched(); |
822 | } | 841 | } |
823 | ret = 0; | 842 | return; |
824 | out: | ||
825 | return ret; | ||
826 | out_free_reserve: | 843 | out_free_reserve: |
827 | btrfs_free_reserved_extent(root, ins.objectid, ins.offset, 1); | 844 | btrfs_free_reserved_extent(root, ins.objectid, ins.offset, 1); |
828 | out_free: | 845 | out_free: |
@@ -832,7 +849,9 @@ out_free: | |||
832 | NULL, EXTENT_LOCKED | EXTENT_DELALLOC | | 849 | NULL, EXTENT_LOCKED | EXTENT_DELALLOC | |
833 | EXTENT_DEFRAG | EXTENT_DO_ACCOUNTING, | 850 | EXTENT_DEFRAG | EXTENT_DO_ACCOUNTING, |
834 | PAGE_UNLOCK | PAGE_CLEAR_DIRTY | | 851 | PAGE_UNLOCK | PAGE_CLEAR_DIRTY | |
835 | PAGE_SET_WRITEBACK | PAGE_END_WRITEBACK); | 852 | PAGE_SET_WRITEBACK | PAGE_END_WRITEBACK | |
853 | PAGE_SET_ERROR); | ||
854 | free_async_extent_pages(async_extent); | ||
836 | kfree(async_extent); | 855 | kfree(async_extent); |
837 | goto again; | 856 | goto again; |
838 | } | 857 | } |
@@ -1318,7 +1337,7 @@ next_slot: | |||
1318 | * we fall into common COW way. | 1337 | * we fall into common COW way. |
1319 | */ | 1338 | */ |
1320 | if (!nolock) { | 1339 | if (!nolock) { |
1321 | err = btrfs_start_nocow_write(root); | 1340 | err = btrfs_start_write_no_snapshoting(root); |
1322 | if (!err) | 1341 | if (!err) |
1323 | goto out_check; | 1342 | goto out_check; |
1324 | } | 1343 | } |
@@ -1342,7 +1361,7 @@ out_check: | |||
1342 | if (extent_end <= start) { | 1361 | if (extent_end <= start) { |
1343 | path->slots[0]++; | 1362 | path->slots[0]++; |
1344 | if (!nolock && nocow) | 1363 | if (!nolock && nocow) |
1345 | btrfs_end_nocow_write(root); | 1364 | btrfs_end_write_no_snapshoting(root); |
1346 | goto next_slot; | 1365 | goto next_slot; |
1347 | } | 1366 | } |
1348 | if (!nocow) { | 1367 | if (!nocow) { |
@@ -1362,7 +1381,7 @@ out_check: | |||
1362 | page_started, nr_written, 1); | 1381 | page_started, nr_written, 1); |
1363 | if (ret) { | 1382 | if (ret) { |
1364 | if (!nolock && nocow) | 1383 | if (!nolock && nocow) |
1365 | btrfs_end_nocow_write(root); | 1384 | btrfs_end_write_no_snapshoting(root); |
1366 | goto error; | 1385 | goto error; |
1367 | } | 1386 | } |
1368 | cow_start = (u64)-1; | 1387 | cow_start = (u64)-1; |
@@ -1413,7 +1432,7 @@ out_check: | |||
1413 | num_bytes); | 1432 | num_bytes); |
1414 | if (ret) { | 1433 | if (ret) { |
1415 | if (!nolock && nocow) | 1434 | if (!nolock && nocow) |
1416 | btrfs_end_nocow_write(root); | 1435 | btrfs_end_write_no_snapshoting(root); |
1417 | goto error; | 1436 | goto error; |
1418 | } | 1437 | } |
1419 | } | 1438 | } |
@@ -1424,7 +1443,7 @@ out_check: | |||
1424 | EXTENT_DELALLOC, PAGE_UNLOCK | | 1443 | EXTENT_DELALLOC, PAGE_UNLOCK | |
1425 | PAGE_SET_PRIVATE2); | 1444 | PAGE_SET_PRIVATE2); |
1426 | if (!nolock && nocow) | 1445 | if (!nolock && nocow) |
1427 | btrfs_end_nocow_write(root); | 1446 | btrfs_end_write_no_snapshoting(root); |
1428 | cur_offset = extent_end; | 1447 | cur_offset = extent_end; |
1429 | if (cur_offset > end) | 1448 | if (cur_offset > end) |
1430 | break; | 1449 | break; |
@@ -4580,6 +4599,26 @@ next: | |||
4580 | return err; | 4599 | return err; |
4581 | } | 4600 | } |
4582 | 4601 | ||
4602 | static int wait_snapshoting_atomic_t(atomic_t *a) | ||
4603 | { | ||
4604 | schedule(); | ||
4605 | return 0; | ||
4606 | } | ||
4607 | |||
4608 | static void wait_for_snapshot_creation(struct btrfs_root *root) | ||
4609 | { | ||
4610 | while (true) { | ||
4611 | int ret; | ||
4612 | |||
4613 | ret = btrfs_start_write_no_snapshoting(root); | ||
4614 | if (ret) | ||
4615 | break; | ||
4616 | wait_on_atomic_t(&root->will_be_snapshoted, | ||
4617 | wait_snapshoting_atomic_t, | ||
4618 | TASK_UNINTERRUPTIBLE); | ||
4619 | } | ||
4620 | } | ||
4621 | |||
4583 | static int btrfs_setsize(struct inode *inode, struct iattr *attr) | 4622 | static int btrfs_setsize(struct inode *inode, struct iattr *attr) |
4584 | { | 4623 | { |
4585 | struct btrfs_root *root = BTRFS_I(inode)->root; | 4624 | struct btrfs_root *root = BTRFS_I(inode)->root; |
@@ -4604,17 +4643,30 @@ static int btrfs_setsize(struct inode *inode, struct iattr *attr) | |||
4604 | 4643 | ||
4605 | if (newsize > oldsize) { | 4644 | if (newsize > oldsize) { |
4606 | truncate_pagecache(inode, newsize); | 4645 | truncate_pagecache(inode, newsize); |
4646 | /* | ||
4647 | * Don't do an expanding truncate while snapshoting is ongoing. | ||
4648 | * This is to ensure the snapshot captures a fully consistent | ||
4649 | * state of this file - if the snapshot captures this expanding | ||
4650 | * truncation, it must capture all writes that happened before | ||
4651 | * this truncation. | ||
4652 | */ | ||
4653 | wait_for_snapshot_creation(root); | ||
4607 | ret = btrfs_cont_expand(inode, oldsize, newsize); | 4654 | ret = btrfs_cont_expand(inode, oldsize, newsize); |
4608 | if (ret) | 4655 | if (ret) { |
4656 | btrfs_end_write_no_snapshoting(root); | ||
4609 | return ret; | 4657 | return ret; |
4658 | } | ||
4610 | 4659 | ||
4611 | trans = btrfs_start_transaction(root, 1); | 4660 | trans = btrfs_start_transaction(root, 1); |
4612 | if (IS_ERR(trans)) | 4661 | if (IS_ERR(trans)) { |
4662 | btrfs_end_write_no_snapshoting(root); | ||
4613 | return PTR_ERR(trans); | 4663 | return PTR_ERR(trans); |
4664 | } | ||
4614 | 4665 | ||
4615 | i_size_write(inode, newsize); | 4666 | i_size_write(inode, newsize); |
4616 | btrfs_ordered_update_i_size(inode, i_size_read(inode), NULL); | 4667 | btrfs_ordered_update_i_size(inode, i_size_read(inode), NULL); |
4617 | ret = btrfs_update_inode(trans, root, inode); | 4668 | ret = btrfs_update_inode(trans, root, inode); |
4669 | btrfs_end_write_no_snapshoting(root); | ||
4618 | btrfs_end_transaction(trans, root); | 4670 | btrfs_end_transaction(trans, root); |
4619 | } else { | 4671 | } else { |
4620 | 4672 | ||
@@ -7000,9 +7052,12 @@ static int lock_extent_direct(struct inode *inode, u64 lockstart, u64 lockend, | |||
7000 | btrfs_put_ordered_extent(ordered); | 7052 | btrfs_put_ordered_extent(ordered); |
7001 | } else { | 7053 | } else { |
7002 | /* Screw you mmap */ | 7054 | /* Screw you mmap */ |
7003 | ret = filemap_write_and_wait_range(inode->i_mapping, | 7055 | ret = btrfs_fdatawrite_range(inode, lockstart, lockend); |
7004 | lockstart, | 7056 | if (ret) |
7005 | lockend); | 7057 | break; |
7058 | ret = filemap_fdatawait_range(inode->i_mapping, | ||
7059 | lockstart, | ||
7060 | lockend); | ||
7006 | if (ret) | 7061 | if (ret) |
7007 | break; | 7062 | break; |
7008 | 7063 | ||
@@ -9442,6 +9497,21 @@ out_inode: | |||
9442 | 9497 | ||
9443 | } | 9498 | } |
9444 | 9499 | ||
9500 | /* Inspired by filemap_check_errors() */ | ||
9501 | int btrfs_inode_check_errors(struct inode *inode) | ||
9502 | { | ||
9503 | int ret = 0; | ||
9504 | |||
9505 | if (test_bit(AS_ENOSPC, &inode->i_mapping->flags) && | ||
9506 | test_and_clear_bit(AS_ENOSPC, &inode->i_mapping->flags)) | ||
9507 | ret = -ENOSPC; | ||
9508 | if (test_bit(AS_EIO, &inode->i_mapping->flags) && | ||
9509 | test_and_clear_bit(AS_EIO, &inode->i_mapping->flags)) | ||
9510 | ret = -EIO; | ||
9511 | |||
9512 | return ret; | ||
9513 | } | ||
9514 | |||
9445 | static const struct inode_operations btrfs_dir_inode_operations = { | 9515 | static const struct inode_operations btrfs_dir_inode_operations = { |
9446 | .getattr = btrfs_getattr, | 9516 | .getattr = btrfs_getattr, |
9447 | .lookup = btrfs_lookup, | 9517 | .lookup = btrfs_lookup, |