diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-11-29 17:26:50 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-11-29 17:26:50 -0500 |
commit | 26cd94744e142dd5d5a21e2c1e31bacc120b2d74 (patch) | |
tree | 011899c07353efd6ff8736332848afa42c66041c | |
parent | 198e0c0c61b604ab919e34989afe3505b80cd0eb (diff) | |
parent | ea37d5998b50a72b9045ba60a132eeb20e1c4230 (diff) |
Merge tag 'for-4.15-rc2-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux
Pull btrfs fixes from David Sterba:
"We've collected some fixes in since the pre-merge window freeze.
There's technically only one regression fix for 4.15, but the rest
seems important and candidates for stable.
- fix missing flush bio puts in error cases (is serious, but rarely
happens)
- fix reporting stat::st_blocks for buffered append writes
- fix space cache invalidation
- fix out of bound memory access when setting zlib level
- fix potential memory corruption when fsync fails in the middle
- fix crash in integrity checker
- incremetnal send fix, path mixup for certain unlink/rename
combination
- pass flags to writeback so compressed writes can be throttled
properly
- error handling fixes"
* tag 'for-4.15-rc2-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux:
Btrfs: incremental send, fix wrong unlink path after renaming file
btrfs: tree-checker: Fix false panic for sanity test
Btrfs: fix list_add corruption and soft lockups in fsync
btrfs: Fix wild memory access in compression level parser
btrfs: fix deadlock when writing out space cache
btrfs: clear space cache inode generation always
Btrfs: fix reported number of inode blocks after buffered append writes
Btrfs: move definition of the function btrfs_find_new_delalloc_bytes
Btrfs: bail out gracefully rather than BUG_ON
btrfs: dev_alloc_list is not protected by RCU, use normal list_del
btrfs: add missing device::flush_bio puts
btrfs: Fix transaction abort during failure in btrfs_rm_dev_item
Btrfs: add write_flags for compression bio
-rw-r--r-- | fs/btrfs/compression.c | 9 | ||||
-rw-r--r-- | fs/btrfs/compression.h | 5 | ||||
-rw-r--r-- | fs/btrfs/ctree.h | 1 | ||||
-rw-r--r-- | fs/btrfs/disk-io.c | 10 | ||||
-rw-r--r-- | fs/btrfs/extent-tree.c | 14 | ||||
-rw-r--r-- | fs/btrfs/extent_io.c | 2 | ||||
-rw-r--r-- | fs/btrfs/extent_io.h | 8 | ||||
-rw-r--r-- | fs/btrfs/file.c | 130 | ||||
-rw-r--r-- | fs/btrfs/free-space-cache.c | 3 | ||||
-rw-r--r-- | fs/btrfs/inode.c | 34 | ||||
-rw-r--r-- | fs/btrfs/relocation.c | 3 | ||||
-rw-r--r-- | fs/btrfs/send.c | 124 | ||||
-rw-r--r-- | fs/btrfs/super.c | 13 | ||||
-rw-r--r-- | fs/btrfs/tests/extent-io-tests.c | 6 | ||||
-rw-r--r-- | fs/btrfs/tests/inode-tests.c | 12 | ||||
-rw-r--r-- | fs/btrfs/tree-checker.c | 27 | ||||
-rw-r--r-- | fs/btrfs/tree-checker.h | 14 | ||||
-rw-r--r-- | fs/btrfs/tree-log.c | 2 | ||||
-rw-r--r-- | fs/btrfs/volumes.c | 32 |
19 files changed, 314 insertions, 135 deletions
diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c index b35ce16b3df3..5982c8a71f02 100644 --- a/fs/btrfs/compression.c +++ b/fs/btrfs/compression.c | |||
@@ -295,7 +295,8 @@ blk_status_t btrfs_submit_compressed_write(struct inode *inode, u64 start, | |||
295 | unsigned long len, u64 disk_start, | 295 | unsigned long len, u64 disk_start, |
296 | unsigned long compressed_len, | 296 | unsigned long compressed_len, |
297 | struct page **compressed_pages, | 297 | struct page **compressed_pages, |
298 | unsigned long nr_pages) | 298 | unsigned long nr_pages, |
299 | unsigned int write_flags) | ||
299 | { | 300 | { |
300 | struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); | 301 | struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); |
301 | struct bio *bio = NULL; | 302 | struct bio *bio = NULL; |
@@ -327,7 +328,7 @@ blk_status_t btrfs_submit_compressed_write(struct inode *inode, u64 start, | |||
327 | bdev = fs_info->fs_devices->latest_bdev; | 328 | bdev = fs_info->fs_devices->latest_bdev; |
328 | 329 | ||
329 | bio = btrfs_bio_alloc(bdev, first_byte); | 330 | bio = btrfs_bio_alloc(bdev, first_byte); |
330 | bio_set_op_attrs(bio, REQ_OP_WRITE, 0); | 331 | bio->bi_opf = REQ_OP_WRITE | write_flags; |
331 | bio->bi_private = cb; | 332 | bio->bi_private = cb; |
332 | bio->bi_end_io = end_compressed_bio_write; | 333 | bio->bi_end_io = end_compressed_bio_write; |
333 | refcount_set(&cb->pending_bios, 1); | 334 | refcount_set(&cb->pending_bios, 1); |
@@ -374,7 +375,7 @@ blk_status_t btrfs_submit_compressed_write(struct inode *inode, u64 start, | |||
374 | bio_put(bio); | 375 | bio_put(bio); |
375 | 376 | ||
376 | bio = btrfs_bio_alloc(bdev, first_byte); | 377 | bio = btrfs_bio_alloc(bdev, first_byte); |
377 | bio_set_op_attrs(bio, REQ_OP_WRITE, 0); | 378 | bio->bi_opf = REQ_OP_WRITE | write_flags; |
378 | bio->bi_private = cb; | 379 | bio->bi_private = cb; |
379 | bio->bi_end_io = end_compressed_bio_write; | 380 | bio->bi_end_io = end_compressed_bio_write; |
380 | bio_add_page(bio, page, PAGE_SIZE, 0); | 381 | bio_add_page(bio, page, PAGE_SIZE, 0); |
@@ -1528,5 +1529,5 @@ unsigned int btrfs_compress_str2level(const char *str) | |||
1528 | if (str[4] == ':' && '1' <= str[5] && str[5] <= '9' && str[6] == 0) | 1529 | if (str[4] == ':' && '1' <= str[5] && str[5] <= '9' && str[6] == 0) |
1529 | return str[5] - '0'; | 1530 | return str[5] - '0'; |
1530 | 1531 | ||
1531 | return 0; | 1532 | return BTRFS_ZLIB_DEFAULT_LEVEL; |
1532 | } | 1533 | } |
diff --git a/fs/btrfs/compression.h b/fs/btrfs/compression.h index da20755ebf21..0868cc554f14 100644 --- a/fs/btrfs/compression.h +++ b/fs/btrfs/compression.h | |||
@@ -34,6 +34,8 @@ | |||
34 | /* Maximum size of data before compression */ | 34 | /* Maximum size of data before compression */ |
35 | #define BTRFS_MAX_UNCOMPRESSED (SZ_128K) | 35 | #define BTRFS_MAX_UNCOMPRESSED (SZ_128K) |
36 | 36 | ||
37 | #define BTRFS_ZLIB_DEFAULT_LEVEL 3 | ||
38 | |||
37 | struct compressed_bio { | 39 | struct compressed_bio { |
38 | /* number of bios pending for this compressed extent */ | 40 | /* number of bios pending for this compressed extent */ |
39 | refcount_t pending_bios; | 41 | refcount_t pending_bios; |
@@ -91,7 +93,8 @@ blk_status_t btrfs_submit_compressed_write(struct inode *inode, u64 start, | |||
91 | unsigned long len, u64 disk_start, | 93 | unsigned long len, u64 disk_start, |
92 | unsigned long compressed_len, | 94 | unsigned long compressed_len, |
93 | struct page **compressed_pages, | 95 | struct page **compressed_pages, |
94 | unsigned long nr_pages); | 96 | unsigned long nr_pages, |
97 | unsigned int write_flags); | ||
95 | blk_status_t btrfs_submit_compressed_read(struct inode *inode, struct bio *bio, | 98 | blk_status_t btrfs_submit_compressed_read(struct inode *inode, struct bio *bio, |
96 | int mirror_num, unsigned long bio_flags); | 99 | int mirror_num, unsigned long bio_flags); |
97 | 100 | ||
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 51477a537c83..13c260b525a1 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
@@ -3180,6 +3180,7 @@ int btrfs_start_delalloc_inodes(struct btrfs_root *root, int delay_iput); | |||
3180 | int btrfs_start_delalloc_roots(struct btrfs_fs_info *fs_info, int delay_iput, | 3180 | int btrfs_start_delalloc_roots(struct btrfs_fs_info *fs_info, int delay_iput, |
3181 | int nr); | 3181 | int nr); |
3182 | int btrfs_set_extent_delalloc(struct inode *inode, u64 start, u64 end, | 3182 | int btrfs_set_extent_delalloc(struct inode *inode, u64 start, u64 end, |
3183 | unsigned int extra_bits, | ||
3183 | struct extent_state **cached_state, int dedupe); | 3184 | struct extent_state **cached_state, int dedupe); |
3184 | int btrfs_create_subvol_root(struct btrfs_trans_handle *trans, | 3185 | int btrfs_create_subvol_root(struct btrfs_trans_handle *trans, |
3185 | struct btrfs_root *new_root, | 3186 | struct btrfs_root *new_root, |
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index efce9a2fa9be..10a2a579cc7f 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
@@ -610,7 +610,7 @@ static int btree_readpage_end_io_hook(struct btrfs_io_bio *io_bio, | |||
610 | * that we don't try and read the other copies of this block, just | 610 | * that we don't try and read the other copies of this block, just |
611 | * return -EIO. | 611 | * return -EIO. |
612 | */ | 612 | */ |
613 | if (found_level == 0 && btrfs_check_leaf(root, eb)) { | 613 | if (found_level == 0 && btrfs_check_leaf_full(root, eb)) { |
614 | set_bit(EXTENT_BUFFER_CORRUPT, &eb->bflags); | 614 | set_bit(EXTENT_BUFFER_CORRUPT, &eb->bflags); |
615 | ret = -EIO; | 615 | ret = -EIO; |
616 | } | 616 | } |
@@ -3848,7 +3848,13 @@ void btrfs_mark_buffer_dirty(struct extent_buffer *buf) | |||
3848 | buf->len, | 3848 | buf->len, |
3849 | fs_info->dirty_metadata_batch); | 3849 | fs_info->dirty_metadata_batch); |
3850 | #ifdef CONFIG_BTRFS_FS_CHECK_INTEGRITY | 3850 | #ifdef CONFIG_BTRFS_FS_CHECK_INTEGRITY |
3851 | if (btrfs_header_level(buf) == 0 && btrfs_check_leaf(root, buf)) { | 3851 | /* |
3852 | * Since btrfs_mark_buffer_dirty() can be called with item pointer set | ||
3853 | * but item data not updated. | ||
3854 | * So here we should only check item pointers, not item data. | ||
3855 | */ | ||
3856 | if (btrfs_header_level(buf) == 0 && | ||
3857 | btrfs_check_leaf_relaxed(root, buf)) { | ||
3852 | btrfs_print_leaf(buf); | 3858 | btrfs_print_leaf(buf); |
3853 | ASSERT(0); | 3859 | ASSERT(0); |
3854 | } | 3860 | } |
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 7208ecef7088..4497f937e8fb 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -3502,13 +3502,6 @@ again: | |||
3502 | goto again; | 3502 | goto again; |
3503 | } | 3503 | } |
3504 | 3504 | ||
3505 | /* We've already setup this transaction, go ahead and exit */ | ||
3506 | if (block_group->cache_generation == trans->transid && | ||
3507 | i_size_read(inode)) { | ||
3508 | dcs = BTRFS_DC_SETUP; | ||
3509 | goto out_put; | ||
3510 | } | ||
3511 | |||
3512 | /* | 3505 | /* |
3513 | * We want to set the generation to 0, that way if anything goes wrong | 3506 | * We want to set the generation to 0, that way if anything goes wrong |
3514 | * from here on out we know not to trust this cache when we load up next | 3507 | * from here on out we know not to trust this cache when we load up next |
@@ -3532,6 +3525,13 @@ again: | |||
3532 | } | 3525 | } |
3533 | WARN_ON(ret); | 3526 | WARN_ON(ret); |
3534 | 3527 | ||
3528 | /* We've already setup this transaction, go ahead and exit */ | ||
3529 | if (block_group->cache_generation == trans->transid && | ||
3530 | i_size_read(inode)) { | ||
3531 | dcs = BTRFS_DC_SETUP; | ||
3532 | goto out_put; | ||
3533 | } | ||
3534 | |||
3535 | if (i_size_read(inode) > 0) { | 3535 | if (i_size_read(inode) > 0) { |
3536 | ret = btrfs_check_trunc_cache_free_space(fs_info, | 3536 | ret = btrfs_check_trunc_cache_free_space(fs_info, |
3537 | &fs_info->global_block_rsv); | 3537 | &fs_info->global_block_rsv); |
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index f9e9f721efe2..012d63870b99 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c | |||
@@ -3253,7 +3253,7 @@ static noinline_for_stack int writepage_delalloc(struct inode *inode, | |||
3253 | delalloc_start, | 3253 | delalloc_start, |
3254 | delalloc_end, | 3254 | delalloc_end, |
3255 | &page_started, | 3255 | &page_started, |
3256 | nr_written); | 3256 | nr_written, wbc); |
3257 | /* File system has been set read-only */ | 3257 | /* File system has been set read-only */ |
3258 | if (ret) { | 3258 | if (ret) { |
3259 | SetPageError(page); | 3259 | SetPageError(page); |
diff --git a/fs/btrfs/extent_io.h b/fs/btrfs/extent_io.h index 4a8861379d3e..93dcae0c3183 100644 --- a/fs/btrfs/extent_io.h +++ b/fs/btrfs/extent_io.h | |||
@@ -116,7 +116,8 @@ struct extent_io_ops { | |||
116 | */ | 116 | */ |
117 | int (*fill_delalloc)(void *private_data, struct page *locked_page, | 117 | int (*fill_delalloc)(void *private_data, struct page *locked_page, |
118 | u64 start, u64 end, int *page_started, | 118 | u64 start, u64 end, int *page_started, |
119 | unsigned long *nr_written); | 119 | unsigned long *nr_written, |
120 | struct writeback_control *wbc); | ||
120 | 121 | ||
121 | int (*writepage_start_hook)(struct page *page, u64 start, u64 end); | 122 | int (*writepage_start_hook)(struct page *page, u64 start, u64 end); |
122 | void (*writepage_end_io_hook)(struct page *page, u64 start, u64 end, | 123 | void (*writepage_end_io_hook)(struct page *page, u64 start, u64 end, |
@@ -365,10 +366,11 @@ int convert_extent_bit(struct extent_io_tree *tree, u64 start, u64 end, | |||
365 | struct extent_state **cached_state); | 366 | struct extent_state **cached_state); |
366 | 367 | ||
367 | static inline int set_extent_delalloc(struct extent_io_tree *tree, u64 start, | 368 | static inline int set_extent_delalloc(struct extent_io_tree *tree, u64 start, |
368 | u64 end, struct extent_state **cached_state) | 369 | u64 end, unsigned int extra_bits, |
370 | struct extent_state **cached_state) | ||
369 | { | 371 | { |
370 | return set_extent_bit(tree, start, end, | 372 | return set_extent_bit(tree, start, end, |
371 | EXTENT_DELALLOC | EXTENT_UPTODATE, | 373 | EXTENT_DELALLOC | EXTENT_UPTODATE | extra_bits, |
372 | NULL, cached_state, GFP_NOFS); | 374 | NULL, cached_state, GFP_NOFS); |
373 | } | 375 | } |
374 | 376 | ||
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index f80254d82f40..eb1bac7c8553 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c | |||
@@ -477,6 +477,47 @@ static void btrfs_drop_pages(struct page **pages, size_t num_pages) | |||
477 | } | 477 | } |
478 | } | 478 | } |
479 | 479 | ||
480 | static int btrfs_find_new_delalloc_bytes(struct btrfs_inode *inode, | ||
481 | const u64 start, | ||
482 | const u64 len, | ||
483 | struct extent_state **cached_state) | ||
484 | { | ||
485 | u64 search_start = start; | ||
486 | const u64 end = start + len - 1; | ||
487 | |||
488 | while (search_start < end) { | ||
489 | const u64 search_len = end - search_start + 1; | ||
490 | struct extent_map *em; | ||
491 | u64 em_len; | ||
492 | int ret = 0; | ||
493 | |||
494 | em = btrfs_get_extent(inode, NULL, 0, search_start, | ||
495 | search_len, 0); | ||
496 | if (IS_ERR(em)) | ||
497 | return PTR_ERR(em); | ||
498 | |||
499 | if (em->block_start != EXTENT_MAP_HOLE) | ||
500 | goto next; | ||
501 | |||
502 | em_len = em->len; | ||
503 | if (em->start < search_start) | ||
504 | em_len -= search_start - em->start; | ||
505 | if (em_len > search_len) | ||
506 | em_len = search_len; | ||
507 | |||
508 | ret = set_extent_bit(&inode->io_tree, search_start, | ||
509 | search_start + em_len - 1, | ||
510 | EXTENT_DELALLOC_NEW, | ||
511 | NULL, cached_state, GFP_NOFS); | ||
512 | next: | ||
513 | search_start = extent_map_end(em); | ||
514 | free_extent_map(em); | ||
515 | if (ret) | ||
516 | return ret; | ||
517 | } | ||
518 | return 0; | ||
519 | } | ||
520 | |||
480 | /* | 521 | /* |
481 | * after copy_from_user, pages need to be dirtied and we need to make | 522 | * after copy_from_user, pages need to be dirtied and we need to make |
482 | * sure holes are created between the current EOF and the start of | 523 | * sure holes are created between the current EOF and the start of |
@@ -497,14 +538,34 @@ int btrfs_dirty_pages(struct inode *inode, struct page **pages, | |||
497 | u64 end_of_last_block; | 538 | u64 end_of_last_block; |
498 | u64 end_pos = pos + write_bytes; | 539 | u64 end_pos = pos + write_bytes; |
499 | loff_t isize = i_size_read(inode); | 540 | loff_t isize = i_size_read(inode); |
541 | unsigned int extra_bits = 0; | ||
500 | 542 | ||
501 | start_pos = pos & ~((u64) fs_info->sectorsize - 1); | 543 | start_pos = pos & ~((u64) fs_info->sectorsize - 1); |
502 | num_bytes = round_up(write_bytes + pos - start_pos, | 544 | num_bytes = round_up(write_bytes + pos - start_pos, |
503 | fs_info->sectorsize); | 545 | fs_info->sectorsize); |
504 | 546 | ||
505 | end_of_last_block = start_pos + num_bytes - 1; | 547 | end_of_last_block = start_pos + num_bytes - 1; |
548 | |||
549 | if (!btrfs_is_free_space_inode(BTRFS_I(inode))) { | ||
550 | if (start_pos >= isize && | ||
551 | !(BTRFS_I(inode)->flags & BTRFS_INODE_PREALLOC)) { | ||
552 | /* | ||
553 | * There can't be any extents following eof in this case | ||
554 | * so just set the delalloc new bit for the range | ||
555 | * directly. | ||
556 | */ | ||
557 | extra_bits |= EXTENT_DELALLOC_NEW; | ||
558 | } else { | ||
559 | err = btrfs_find_new_delalloc_bytes(BTRFS_I(inode), | ||
560 | start_pos, | ||
561 | num_bytes, cached); | ||
562 | if (err) | ||
563 | return err; | ||
564 | } | ||
565 | } | ||
566 | |||
506 | err = btrfs_set_extent_delalloc(inode, start_pos, end_of_last_block, | 567 | err = btrfs_set_extent_delalloc(inode, start_pos, end_of_last_block, |
507 | cached, 0); | 568 | extra_bits, cached, 0); |
508 | if (err) | 569 | if (err) |
509 | return err; | 570 | return err; |
510 | 571 | ||
@@ -1404,47 +1465,6 @@ fail: | |||
1404 | 1465 | ||
1405 | } | 1466 | } |
1406 | 1467 | ||
1407 | static int btrfs_find_new_delalloc_bytes(struct btrfs_inode *inode, | ||
1408 | const u64 start, | ||
1409 | const u64 len, | ||
1410 | struct extent_state **cached_state) | ||
1411 | { | ||
1412 | u64 search_start = start; | ||
1413 | const u64 end = start + len - 1; | ||
1414 | |||
1415 | while (search_start < end) { | ||
1416 | const u64 search_len = end - search_start + 1; | ||
1417 | struct extent_map *em; | ||
1418 | u64 em_len; | ||
1419 | int ret = 0; | ||
1420 | |||
1421 | em = btrfs_get_extent(inode, NULL, 0, search_start, | ||
1422 | search_len, 0); | ||
1423 | if (IS_ERR(em)) | ||
1424 | return PTR_ERR(em); | ||
1425 | |||
1426 | if (em->block_start != EXTENT_MAP_HOLE) | ||
1427 | goto next; | ||
1428 | |||
1429 | em_len = em->len; | ||
1430 | if (em->start < search_start) | ||
1431 | em_len -= search_start - em->start; | ||
1432 | if (em_len > search_len) | ||
1433 | em_len = search_len; | ||
1434 | |||
1435 | ret = set_extent_bit(&inode->io_tree, search_start, | ||
1436 | search_start + em_len - 1, | ||
1437 | EXTENT_DELALLOC_NEW, | ||
1438 | NULL, cached_state, GFP_NOFS); | ||
1439 | next: | ||
1440 | search_start = extent_map_end(em); | ||
1441 | free_extent_map(em); | ||
1442 | if (ret) | ||
1443 | return ret; | ||
1444 | } | ||
1445 | return 0; | ||
1446 | } | ||
1447 | |||
1448 | /* | 1468 | /* |
1449 | * This function locks the extent and properly waits for data=ordered extents | 1469 | * This function locks the extent and properly waits for data=ordered extents |
1450 | * to finish before allowing the pages to be modified if need. | 1470 | * to finish before allowing the pages to be modified if need. |
@@ -1473,10 +1493,8 @@ lock_and_cleanup_extent_if_need(struct btrfs_inode *inode, struct page **pages, | |||
1473 | + round_up(pos + write_bytes - start_pos, | 1493 | + round_up(pos + write_bytes - start_pos, |
1474 | fs_info->sectorsize) - 1; | 1494 | fs_info->sectorsize) - 1; |
1475 | 1495 | ||
1476 | if (start_pos < inode->vfs_inode.i_size || | 1496 | if (start_pos < inode->vfs_inode.i_size) { |
1477 | (inode->flags & BTRFS_INODE_PREALLOC)) { | ||
1478 | struct btrfs_ordered_extent *ordered; | 1497 | struct btrfs_ordered_extent *ordered; |
1479 | unsigned int clear_bits; | ||
1480 | 1498 | ||
1481 | lock_extent_bits(&inode->io_tree, start_pos, last_pos, | 1499 | lock_extent_bits(&inode->io_tree, start_pos, last_pos, |
1482 | cached_state); | 1500 | cached_state); |
@@ -1498,19 +1516,10 @@ lock_and_cleanup_extent_if_need(struct btrfs_inode *inode, struct page **pages, | |||
1498 | } | 1516 | } |
1499 | if (ordered) | 1517 | if (ordered) |
1500 | btrfs_put_ordered_extent(ordered); | 1518 | btrfs_put_ordered_extent(ordered); |
1501 | ret = btrfs_find_new_delalloc_bytes(inode, start_pos, | 1519 | clear_extent_bit(&inode->io_tree, start_pos, last_pos, |
1502 | last_pos - start_pos + 1, | 1520 | EXTENT_DIRTY | EXTENT_DELALLOC | |
1503 | cached_state); | 1521 | EXTENT_DO_ACCOUNTING | EXTENT_DEFRAG, |
1504 | clear_bits = EXTENT_DIRTY | EXTENT_DELALLOC | | 1522 | 0, 0, cached_state, GFP_NOFS); |
1505 | EXTENT_DO_ACCOUNTING | EXTENT_DEFRAG; | ||
1506 | if (ret) | ||
1507 | clear_bits |= EXTENT_DELALLOC_NEW | EXTENT_LOCKED; | ||
1508 | clear_extent_bit(&inode->io_tree, start_pos, | ||
1509 | last_pos, clear_bits, | ||
1510 | (clear_bits & EXTENT_LOCKED) ? 1 : 0, | ||
1511 | 0, cached_state, GFP_NOFS); | ||
1512 | if (ret) | ||
1513 | return ret; | ||
1514 | *lockstart = start_pos; | 1523 | *lockstart = start_pos; |
1515 | *lockend = last_pos; | 1524 | *lockend = last_pos; |
1516 | ret = 1; | 1525 | ret = 1; |
@@ -2048,6 +2057,8 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync) | |||
2048 | len = (u64)end - (u64)start + 1; | 2057 | len = (u64)end - (u64)start + 1; |
2049 | trace_btrfs_sync_file(file, datasync); | 2058 | trace_btrfs_sync_file(file, datasync); |
2050 | 2059 | ||
2060 | btrfs_init_log_ctx(&ctx, inode); | ||
2061 | |||
2051 | /* | 2062 | /* |
2052 | * We write the dirty pages in the range and wait until they complete | 2063 | * We write the dirty pages in the range and wait until they complete |
2053 | * out of the ->i_mutex. If so, we can flush the dirty pages by | 2064 | * out of the ->i_mutex. If so, we can flush the dirty pages by |
@@ -2194,8 +2205,6 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync) | |||
2194 | } | 2205 | } |
2195 | trans->sync = true; | 2206 | trans->sync = true; |
2196 | 2207 | ||
2197 | btrfs_init_log_ctx(&ctx, inode); | ||
2198 | |||
2199 | ret = btrfs_log_dentry_safe(trans, root, dentry, start, end, &ctx); | 2208 | ret = btrfs_log_dentry_safe(trans, root, dentry, start, end, &ctx); |
2200 | if (ret < 0) { | 2209 | if (ret < 0) { |
2201 | /* Fallthrough and commit/free transaction. */ | 2210 | /* Fallthrough and commit/free transaction. */ |
@@ -2253,6 +2262,7 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync) | |||
2253 | ret = btrfs_end_transaction(trans); | 2262 | ret = btrfs_end_transaction(trans); |
2254 | } | 2263 | } |
2255 | out: | 2264 | out: |
2265 | ASSERT(list_empty(&ctx.list)); | ||
2256 | err = file_check_and_advance_wb_err(file); | 2266 | err = file_check_and_advance_wb_err(file); |
2257 | if (!ret) | 2267 | if (!ret) |
2258 | ret = err; | 2268 | ret = err; |
diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c index cdc9f4015ec3..4426d1c73e50 100644 --- a/fs/btrfs/free-space-cache.c +++ b/fs/btrfs/free-space-cache.c | |||
@@ -1264,7 +1264,7 @@ static int __btrfs_write_out_cache(struct btrfs_root *root, struct inode *inode, | |||
1264 | /* Lock all pages first so we can lock the extent safely. */ | 1264 | /* Lock all pages first so we can lock the extent safely. */ |
1265 | ret = io_ctl_prepare_pages(io_ctl, inode, 0); | 1265 | ret = io_ctl_prepare_pages(io_ctl, inode, 0); |
1266 | if (ret) | 1266 | if (ret) |
1267 | goto out; | 1267 | goto out_unlock; |
1268 | 1268 | ||
1269 | lock_extent_bits(&BTRFS_I(inode)->io_tree, 0, i_size_read(inode) - 1, | 1269 | lock_extent_bits(&BTRFS_I(inode)->io_tree, 0, i_size_read(inode) - 1, |
1270 | &cached_state); | 1270 | &cached_state); |
@@ -1358,6 +1358,7 @@ out_nospc_locked: | |||
1358 | out_nospc: | 1358 | out_nospc: |
1359 | cleanup_write_cache_enospc(inode, io_ctl, &cached_state); | 1359 | cleanup_write_cache_enospc(inode, io_ctl, &cached_state); |
1360 | 1360 | ||
1361 | out_unlock: | ||
1361 | if (block_group && (block_group->flags & BTRFS_BLOCK_GROUP_DATA)) | 1362 | if (block_group && (block_group->flags & BTRFS_BLOCK_GROUP_DATA)) |
1362 | up_write(&block_group->data_rwsem); | 1363 | up_write(&block_group->data_rwsem); |
1363 | 1364 | ||
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index b93fe05a39c7..993061f83067 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -378,6 +378,7 @@ struct async_cow { | |||
378 | struct page *locked_page; | 378 | struct page *locked_page; |
379 | u64 start; | 379 | u64 start; |
380 | u64 end; | 380 | u64 end; |
381 | unsigned int write_flags; | ||
381 | struct list_head extents; | 382 | struct list_head extents; |
382 | struct btrfs_work work; | 383 | struct btrfs_work work; |
383 | }; | 384 | }; |
@@ -857,7 +858,8 @@ retry: | |||
857 | async_extent->ram_size, | 858 | async_extent->ram_size, |
858 | ins.objectid, | 859 | ins.objectid, |
859 | ins.offset, async_extent->pages, | 860 | ins.offset, async_extent->pages, |
860 | async_extent->nr_pages)) { | 861 | async_extent->nr_pages, |
862 | async_cow->write_flags)) { | ||
861 | struct extent_io_tree *tree = &BTRFS_I(inode)->io_tree; | 863 | struct extent_io_tree *tree = &BTRFS_I(inode)->io_tree; |
862 | struct page *p = async_extent->pages[0]; | 864 | struct page *p = async_extent->pages[0]; |
863 | const u64 start = async_extent->start; | 865 | const u64 start = async_extent->start; |
@@ -1191,7 +1193,8 @@ static noinline void async_cow_free(struct btrfs_work *work) | |||
1191 | 1193 | ||
1192 | static int cow_file_range_async(struct inode *inode, struct page *locked_page, | 1194 | static int cow_file_range_async(struct inode *inode, struct page *locked_page, |
1193 | u64 start, u64 end, int *page_started, | 1195 | u64 start, u64 end, int *page_started, |
1194 | unsigned long *nr_written) | 1196 | unsigned long *nr_written, |
1197 | unsigned int write_flags) | ||
1195 | { | 1198 | { |
1196 | struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); | 1199 | struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); |
1197 | struct async_cow *async_cow; | 1200 | struct async_cow *async_cow; |
@@ -1208,6 +1211,7 @@ static int cow_file_range_async(struct inode *inode, struct page *locked_page, | |||
1208 | async_cow->root = root; | 1211 | async_cow->root = root; |
1209 | async_cow->locked_page = locked_page; | 1212 | async_cow->locked_page = locked_page; |
1210 | async_cow->start = start; | 1213 | async_cow->start = start; |
1214 | async_cow->write_flags = write_flags; | ||
1211 | 1215 | ||
1212 | if (BTRFS_I(inode)->flags & BTRFS_INODE_NOCOMPRESS && | 1216 | if (BTRFS_I(inode)->flags & BTRFS_INODE_NOCOMPRESS && |
1213 | !btrfs_test_opt(fs_info, FORCE_COMPRESS)) | 1217 | !btrfs_test_opt(fs_info, FORCE_COMPRESS)) |
@@ -1577,11 +1581,13 @@ static inline int need_force_cow(struct inode *inode, u64 start, u64 end) | |||
1577 | */ | 1581 | */ |
1578 | static int run_delalloc_range(void *private_data, struct page *locked_page, | 1582 | static int run_delalloc_range(void *private_data, struct page *locked_page, |
1579 | u64 start, u64 end, int *page_started, | 1583 | u64 start, u64 end, int *page_started, |
1580 | unsigned long *nr_written) | 1584 | unsigned long *nr_written, |
1585 | struct writeback_control *wbc) | ||
1581 | { | 1586 | { |
1582 | struct inode *inode = private_data; | 1587 | struct inode *inode = private_data; |
1583 | int ret; | 1588 | int ret; |
1584 | int force_cow = need_force_cow(inode, start, end); | 1589 | int force_cow = need_force_cow(inode, start, end); |
1590 | unsigned int write_flags = wbc_to_write_flags(wbc); | ||
1585 | 1591 | ||
1586 | if (BTRFS_I(inode)->flags & BTRFS_INODE_NODATACOW && !force_cow) { | 1592 | if (BTRFS_I(inode)->flags & BTRFS_INODE_NODATACOW && !force_cow) { |
1587 | ret = run_delalloc_nocow(inode, locked_page, start, end, | 1593 | ret = run_delalloc_nocow(inode, locked_page, start, end, |
@@ -1596,7 +1602,8 @@ static int run_delalloc_range(void *private_data, struct page *locked_page, | |||
1596 | set_bit(BTRFS_INODE_HAS_ASYNC_EXTENT, | 1602 | set_bit(BTRFS_INODE_HAS_ASYNC_EXTENT, |
1597 | &BTRFS_I(inode)->runtime_flags); | 1603 | &BTRFS_I(inode)->runtime_flags); |
1598 | ret = cow_file_range_async(inode, locked_page, start, end, | 1604 | ret = cow_file_range_async(inode, locked_page, start, end, |
1599 | page_started, nr_written); | 1605 | page_started, nr_written, |
1606 | write_flags); | ||
1600 | } | 1607 | } |
1601 | if (ret) | 1608 | if (ret) |
1602 | btrfs_cleanup_ordered_extents(inode, start, end - start + 1); | 1609 | btrfs_cleanup_ordered_extents(inode, start, end - start + 1); |
@@ -2025,11 +2032,12 @@ static noinline int add_pending_csums(struct btrfs_trans_handle *trans, | |||
2025 | } | 2032 | } |
2026 | 2033 | ||
2027 | int btrfs_set_extent_delalloc(struct inode *inode, u64 start, u64 end, | 2034 | int btrfs_set_extent_delalloc(struct inode *inode, u64 start, u64 end, |
2035 | unsigned int extra_bits, | ||
2028 | struct extent_state **cached_state, int dedupe) | 2036 | struct extent_state **cached_state, int dedupe) |
2029 | { | 2037 | { |
2030 | WARN_ON((end & (PAGE_SIZE - 1)) == 0); | 2038 | WARN_ON((end & (PAGE_SIZE - 1)) == 0); |
2031 | return set_extent_delalloc(&BTRFS_I(inode)->io_tree, start, end, | 2039 | return set_extent_delalloc(&BTRFS_I(inode)->io_tree, start, end, |
2032 | cached_state); | 2040 | extra_bits, cached_state); |
2033 | } | 2041 | } |
2034 | 2042 | ||
2035 | /* see btrfs_writepage_start_hook for details on why this is required */ | 2043 | /* see btrfs_writepage_start_hook for details on why this is required */ |
@@ -2090,7 +2098,7 @@ again: | |||
2090 | goto out; | 2098 | goto out; |
2091 | } | 2099 | } |
2092 | 2100 | ||
2093 | btrfs_set_extent_delalloc(inode, page_start, page_end, &cached_state, | 2101 | btrfs_set_extent_delalloc(inode, page_start, page_end, 0, &cached_state, |
2094 | 0); | 2102 | 0); |
2095 | ClearPageChecked(page); | 2103 | ClearPageChecked(page); |
2096 | set_page_dirty(page); | 2104 | set_page_dirty(page); |
@@ -4790,7 +4798,7 @@ again: | |||
4790 | EXTENT_DO_ACCOUNTING | EXTENT_DEFRAG, | 4798 | EXTENT_DO_ACCOUNTING | EXTENT_DEFRAG, |
4791 | 0, 0, &cached_state, GFP_NOFS); | 4799 | 0, 0, &cached_state, GFP_NOFS); |
4792 | 4800 | ||
4793 | ret = btrfs_set_extent_delalloc(inode, block_start, block_end, | 4801 | ret = btrfs_set_extent_delalloc(inode, block_start, block_end, 0, |
4794 | &cached_state, 0); | 4802 | &cached_state, 0); |
4795 | if (ret) { | 4803 | if (ret) { |
4796 | unlock_extent_cached(io_tree, block_start, block_end, | 4804 | unlock_extent_cached(io_tree, block_start, block_end, |
@@ -5438,6 +5446,14 @@ static int btrfs_inode_by_name(struct inode *dir, struct dentry *dentry, | |||
5438 | goto out_err; | 5446 | goto out_err; |
5439 | 5447 | ||
5440 | btrfs_dir_item_key_to_cpu(path->nodes[0], di, location); | 5448 | btrfs_dir_item_key_to_cpu(path->nodes[0], di, location); |
5449 | if (location->type != BTRFS_INODE_ITEM_KEY && | ||
5450 | location->type != BTRFS_ROOT_ITEM_KEY) { | ||
5451 | btrfs_warn(root->fs_info, | ||
5452 | "%s gets something invalid in DIR_ITEM (name %s, directory ino %llu, location(%llu %u %llu))", | ||
5453 | __func__, name, btrfs_ino(BTRFS_I(dir)), | ||
5454 | location->objectid, location->type, location->offset); | ||
5455 | goto out_err; | ||
5456 | } | ||
5441 | out: | 5457 | out: |
5442 | btrfs_free_path(path); | 5458 | btrfs_free_path(path); |
5443 | return ret; | 5459 | return ret; |
@@ -5754,8 +5770,6 @@ struct inode *btrfs_lookup_dentry(struct inode *dir, struct dentry *dentry) | |||
5754 | return inode; | 5770 | return inode; |
5755 | } | 5771 | } |
5756 | 5772 | ||
5757 | BUG_ON(location.type != BTRFS_ROOT_ITEM_KEY); | ||
5758 | |||
5759 | index = srcu_read_lock(&fs_info->subvol_srcu); | 5773 | index = srcu_read_lock(&fs_info->subvol_srcu); |
5760 | ret = fixup_tree_root_location(fs_info, dir, dentry, | 5774 | ret = fixup_tree_root_location(fs_info, dir, dentry, |
5761 | &location, &sub_root); | 5775 | &location, &sub_root); |
@@ -9150,7 +9164,7 @@ again: | |||
9150 | EXTENT_DO_ACCOUNTING | EXTENT_DEFRAG, | 9164 | EXTENT_DO_ACCOUNTING | EXTENT_DEFRAG, |
9151 | 0, 0, &cached_state, GFP_NOFS); | 9165 | 0, 0, &cached_state, GFP_NOFS); |
9152 | 9166 | ||
9153 | ret = btrfs_set_extent_delalloc(inode, page_start, end, | 9167 | ret = btrfs_set_extent_delalloc(inode, page_start, end, 0, |
9154 | &cached_state, 0); | 9168 | &cached_state, 0); |
9155 | if (ret) { | 9169 | if (ret) { |
9156 | unlock_extent_cached(io_tree, page_start, page_end, | 9170 | unlock_extent_cached(io_tree, page_start, page_end, |
diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c index 4cf2eb67eba6..f0c3f00e97cb 100644 --- a/fs/btrfs/relocation.c +++ b/fs/btrfs/relocation.c | |||
@@ -3268,7 +3268,8 @@ static int relocate_file_extent_cluster(struct inode *inode, | |||
3268 | nr++; | 3268 | nr++; |
3269 | } | 3269 | } |
3270 | 3270 | ||
3271 | btrfs_set_extent_delalloc(inode, page_start, page_end, NULL, 0); | 3271 | btrfs_set_extent_delalloc(inode, page_start, page_end, 0, NULL, |
3272 | 0); | ||
3272 | set_page_dirty(page); | 3273 | set_page_dirty(page); |
3273 | 3274 | ||
3274 | unlock_extent(&BTRFS_I(inode)->io_tree, | 3275 | unlock_extent(&BTRFS_I(inode)->io_tree, |
diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c index c10e4c70f02d..20d3300bd268 100644 --- a/fs/btrfs/send.c +++ b/fs/btrfs/send.c | |||
@@ -3521,7 +3521,40 @@ out: | |||
3521 | } | 3521 | } |
3522 | 3522 | ||
3523 | /* | 3523 | /* |
3524 | * Check if ino ino1 is an ancestor of inode ino2 in the given root. | 3524 | * Check if inode ino2, or any of its ancestors, is inode ino1. |
3525 | * Return 1 if true, 0 if false and < 0 on error. | ||
3526 | */ | ||
3527 | static int check_ino_in_path(struct btrfs_root *root, | ||
3528 | const u64 ino1, | ||
3529 | const u64 ino1_gen, | ||
3530 | const u64 ino2, | ||
3531 | const u64 ino2_gen, | ||
3532 | struct fs_path *fs_path) | ||
3533 | { | ||
3534 | u64 ino = ino2; | ||
3535 | |||
3536 | if (ino1 == ino2) | ||
3537 | return ino1_gen == ino2_gen; | ||
3538 | |||
3539 | while (ino > BTRFS_FIRST_FREE_OBJECTID) { | ||
3540 | u64 parent; | ||
3541 | u64 parent_gen; | ||
3542 | int ret; | ||
3543 | |||
3544 | fs_path_reset(fs_path); | ||
3545 | ret = get_first_ref(root, ino, &parent, &parent_gen, fs_path); | ||
3546 | if (ret < 0) | ||
3547 | return ret; | ||
3548 | if (parent == ino1) | ||
3549 | return parent_gen == ino1_gen; | ||
3550 | ino = parent; | ||
3551 | } | ||
3552 | return 0; | ||
3553 | } | ||
3554 | |||
3555 | /* | ||
3556 | * Check if ino ino1 is an ancestor of inode ino2 in the given root for any | ||
3557 | * possible path (in case ino2 is not a directory and has multiple hard links). | ||
3525 | * Return 1 if true, 0 if false and < 0 on error. | 3558 | * Return 1 if true, 0 if false and < 0 on error. |
3526 | */ | 3559 | */ |
3527 | static int is_ancestor(struct btrfs_root *root, | 3560 | static int is_ancestor(struct btrfs_root *root, |
@@ -3530,36 +3563,91 @@ static int is_ancestor(struct btrfs_root *root, | |||
3530 | const u64 ino2, | 3563 | const u64 ino2, |
3531 | struct fs_path *fs_path) | 3564 | struct fs_path *fs_path) |
3532 | { | 3565 | { |
3533 | u64 ino = ino2; | 3566 | bool free_fs_path = false; |
3534 | bool free_path = false; | ||
3535 | int ret = 0; | 3567 | int ret = 0; |
3568 | struct btrfs_path *path = NULL; | ||
3569 | struct btrfs_key key; | ||
3536 | 3570 | ||
3537 | if (!fs_path) { | 3571 | if (!fs_path) { |
3538 | fs_path = fs_path_alloc(); | 3572 | fs_path = fs_path_alloc(); |
3539 | if (!fs_path) | 3573 | if (!fs_path) |
3540 | return -ENOMEM; | 3574 | return -ENOMEM; |
3541 | free_path = true; | 3575 | free_fs_path = true; |
3542 | } | 3576 | } |
3543 | 3577 | ||
3544 | while (ino > BTRFS_FIRST_FREE_OBJECTID) { | 3578 | path = alloc_path_for_send(); |
3545 | u64 parent; | 3579 | if (!path) { |
3546 | u64 parent_gen; | 3580 | ret = -ENOMEM; |
3581 | goto out; | ||
3582 | } | ||
3547 | 3583 | ||
3548 | fs_path_reset(fs_path); | 3584 | key.objectid = ino2; |
3549 | ret = get_first_ref(root, ino, &parent, &parent_gen, fs_path); | 3585 | key.type = BTRFS_INODE_REF_KEY; |
3550 | if (ret < 0) { | 3586 | key.offset = 0; |
3551 | if (ret == -ENOENT && ino == ino2) | 3587 | |
3552 | ret = 0; | 3588 | ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); |
3553 | goto out; | 3589 | if (ret < 0) |
3590 | goto out; | ||
3591 | |||
3592 | while (true) { | ||
3593 | struct extent_buffer *leaf = path->nodes[0]; | ||
3594 | int slot = path->slots[0]; | ||
3595 | u32 cur_offset = 0; | ||
3596 | u32 item_size; | ||
3597 | |||
3598 | if (slot >= btrfs_header_nritems(leaf)) { | ||
3599 | ret = btrfs_next_leaf(root, path); | ||
3600 | if (ret < 0) | ||
3601 | goto out; | ||
3602 | if (ret > 0) | ||
3603 | break; | ||
3604 | continue; | ||
3554 | } | 3605 | } |
3555 | if (parent == ino1) { | 3606 | |
3556 | ret = parent_gen == ino1_gen ? 1 : 0; | 3607 | btrfs_item_key_to_cpu(leaf, &key, slot); |
3557 | goto out; | 3608 | if (key.objectid != ino2) |
3609 | break; | ||
3610 | if (key.type != BTRFS_INODE_REF_KEY && | ||
3611 | key.type != BTRFS_INODE_EXTREF_KEY) | ||
3612 | break; | ||
3613 | |||
3614 | item_size = btrfs_item_size_nr(leaf, slot); | ||
3615 | while (cur_offset < item_size) { | ||
3616 | u64 parent; | ||
3617 | u64 parent_gen; | ||
3618 | |||
3619 | if (key.type == BTRFS_INODE_EXTREF_KEY) { | ||
3620 | unsigned long ptr; | ||
3621 | struct btrfs_inode_extref *extref; | ||
3622 | |||
3623 | ptr = btrfs_item_ptr_offset(leaf, slot); | ||
3624 | extref = (struct btrfs_inode_extref *) | ||
3625 | (ptr + cur_offset); | ||
3626 | parent = btrfs_inode_extref_parent(leaf, | ||
3627 | extref); | ||
3628 | cur_offset += sizeof(*extref); | ||
3629 | cur_offset += btrfs_inode_extref_name_len(leaf, | ||
3630 | extref); | ||
3631 | } else { | ||
3632 | parent = key.offset; | ||
3633 | cur_offset = item_size; | ||
3634 | } | ||
3635 | |||
3636 | ret = get_inode_info(root, parent, NULL, &parent_gen, | ||
3637 | NULL, NULL, NULL, NULL); | ||
3638 | if (ret < 0) | ||
3639 | goto out; | ||
3640 | ret = check_ino_in_path(root, ino1, ino1_gen, | ||
3641 | parent, parent_gen, fs_path); | ||
3642 | if (ret) | ||
3643 | goto out; | ||
3558 | } | 3644 | } |
3559 | ino = parent; | 3645 | path->slots[0]++; |
3560 | } | 3646 | } |
3647 | ret = 0; | ||
3561 | out: | 3648 | out: |
3562 | if (free_path) | 3649 | btrfs_free_path(path); |
3650 | if (free_fs_path) | ||
3563 | fs_path_free(fs_path); | 3651 | fs_path_free(fs_path); |
3564 | return ret; | 3652 | return ret; |
3565 | } | 3653 | } |
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 305cae7444a0..3a4dce153645 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c | |||
@@ -507,9 +507,18 @@ int btrfs_parse_options(struct btrfs_fs_info *info, char *options, | |||
507 | token == Opt_compress_force || | 507 | token == Opt_compress_force || |
508 | strncmp(args[0].from, "zlib", 4) == 0) { | 508 | strncmp(args[0].from, "zlib", 4) == 0) { |
509 | compress_type = "zlib"; | 509 | compress_type = "zlib"; |
510 | |||
510 | info->compress_type = BTRFS_COMPRESS_ZLIB; | 511 | info->compress_type = BTRFS_COMPRESS_ZLIB; |
511 | info->compress_level = | 512 | info->compress_level = BTRFS_ZLIB_DEFAULT_LEVEL; |
512 | btrfs_compress_str2level(args[0].from); | 513 | /* |
514 | * args[0] contains uninitialized data since | ||
515 | * for these tokens we don't expect any | ||
516 | * parameter. | ||
517 | */ | ||
518 | if (token != Opt_compress && | ||
519 | token != Opt_compress_force) | ||
520 | info->compress_level = | ||
521 | btrfs_compress_str2level(args[0].from); | ||
513 | btrfs_set_opt(info->mount_opt, COMPRESS); | 522 | btrfs_set_opt(info->mount_opt, COMPRESS); |
514 | btrfs_clear_opt(info->mount_opt, NODATACOW); | 523 | btrfs_clear_opt(info->mount_opt, NODATACOW); |
515 | btrfs_clear_opt(info->mount_opt, NODATASUM); | 524 | btrfs_clear_opt(info->mount_opt, NODATASUM); |
diff --git a/fs/btrfs/tests/extent-io-tests.c b/fs/btrfs/tests/extent-io-tests.c index d06b1c931d05..2e7f64a3b22b 100644 --- a/fs/btrfs/tests/extent-io-tests.c +++ b/fs/btrfs/tests/extent-io-tests.c | |||
@@ -114,7 +114,7 @@ static int test_find_delalloc(u32 sectorsize) | |||
114 | * |--- delalloc ---| | 114 | * |--- delalloc ---| |
115 | * |--- search ---| | 115 | * |--- search ---| |
116 | */ | 116 | */ |
117 | set_extent_delalloc(&tmp, 0, sectorsize - 1, NULL); | 117 | set_extent_delalloc(&tmp, 0, sectorsize - 1, 0, NULL); |
118 | start = 0; | 118 | start = 0; |
119 | end = 0; | 119 | end = 0; |
120 | found = find_lock_delalloc_range(inode, &tmp, locked_page, &start, | 120 | found = find_lock_delalloc_range(inode, &tmp, locked_page, &start, |
@@ -145,7 +145,7 @@ static int test_find_delalloc(u32 sectorsize) | |||
145 | test_msg("Couldn't find the locked page\n"); | 145 | test_msg("Couldn't find the locked page\n"); |
146 | goto out_bits; | 146 | goto out_bits; |
147 | } | 147 | } |
148 | set_extent_delalloc(&tmp, sectorsize, max_bytes - 1, NULL); | 148 | set_extent_delalloc(&tmp, sectorsize, max_bytes - 1, 0, NULL); |
149 | start = test_start; | 149 | start = test_start; |
150 | end = 0; | 150 | end = 0; |
151 | found = find_lock_delalloc_range(inode, &tmp, locked_page, &start, | 151 | found = find_lock_delalloc_range(inode, &tmp, locked_page, &start, |
@@ -200,7 +200,7 @@ static int test_find_delalloc(u32 sectorsize) | |||
200 | * | 200 | * |
201 | * We are re-using our test_start from above since it works out well. | 201 | * We are re-using our test_start from above since it works out well. |
202 | */ | 202 | */ |
203 | set_extent_delalloc(&tmp, max_bytes, total_dirty - 1, NULL); | 203 | set_extent_delalloc(&tmp, max_bytes, total_dirty - 1, 0, NULL); |
204 | start = test_start; | 204 | start = test_start; |
205 | end = 0; | 205 | end = 0; |
206 | found = find_lock_delalloc_range(inode, &tmp, locked_page, &start, | 206 | found = find_lock_delalloc_range(inode, &tmp, locked_page, &start, |
diff --git a/fs/btrfs/tests/inode-tests.c b/fs/btrfs/tests/inode-tests.c index f797642c013d..30affb60da51 100644 --- a/fs/btrfs/tests/inode-tests.c +++ b/fs/btrfs/tests/inode-tests.c | |||
@@ -968,7 +968,7 @@ static int test_extent_accounting(u32 sectorsize, u32 nodesize) | |||
968 | btrfs_test_inode_set_ops(inode); | 968 | btrfs_test_inode_set_ops(inode); |
969 | 969 | ||
970 | /* [BTRFS_MAX_EXTENT_SIZE] */ | 970 | /* [BTRFS_MAX_EXTENT_SIZE] */ |
971 | ret = btrfs_set_extent_delalloc(inode, 0, BTRFS_MAX_EXTENT_SIZE - 1, | 971 | ret = btrfs_set_extent_delalloc(inode, 0, BTRFS_MAX_EXTENT_SIZE - 1, 0, |
972 | NULL, 0); | 972 | NULL, 0); |
973 | if (ret) { | 973 | if (ret) { |
974 | test_msg("btrfs_set_extent_delalloc returned %d\n", ret); | 974 | test_msg("btrfs_set_extent_delalloc returned %d\n", ret); |
@@ -984,7 +984,7 @@ static int test_extent_accounting(u32 sectorsize, u32 nodesize) | |||
984 | /* [BTRFS_MAX_EXTENT_SIZE][sectorsize] */ | 984 | /* [BTRFS_MAX_EXTENT_SIZE][sectorsize] */ |
985 | ret = btrfs_set_extent_delalloc(inode, BTRFS_MAX_EXTENT_SIZE, | 985 | ret = btrfs_set_extent_delalloc(inode, BTRFS_MAX_EXTENT_SIZE, |
986 | BTRFS_MAX_EXTENT_SIZE + sectorsize - 1, | 986 | BTRFS_MAX_EXTENT_SIZE + sectorsize - 1, |
987 | NULL, 0); | 987 | 0, NULL, 0); |
988 | if (ret) { | 988 | if (ret) { |
989 | test_msg("btrfs_set_extent_delalloc returned %d\n", ret); | 989 | test_msg("btrfs_set_extent_delalloc returned %d\n", ret); |
990 | goto out; | 990 | goto out; |
@@ -1018,7 +1018,7 @@ static int test_extent_accounting(u32 sectorsize, u32 nodesize) | |||
1018 | ret = btrfs_set_extent_delalloc(inode, BTRFS_MAX_EXTENT_SIZE >> 1, | 1018 | ret = btrfs_set_extent_delalloc(inode, BTRFS_MAX_EXTENT_SIZE >> 1, |
1019 | (BTRFS_MAX_EXTENT_SIZE >> 1) | 1019 | (BTRFS_MAX_EXTENT_SIZE >> 1) |
1020 | + sectorsize - 1, | 1020 | + sectorsize - 1, |
1021 | NULL, 0); | 1021 | 0, NULL, 0); |
1022 | if (ret) { | 1022 | if (ret) { |
1023 | test_msg("btrfs_set_extent_delalloc returned %d\n", ret); | 1023 | test_msg("btrfs_set_extent_delalloc returned %d\n", ret); |
1024 | goto out; | 1024 | goto out; |
@@ -1036,7 +1036,7 @@ static int test_extent_accounting(u32 sectorsize, u32 nodesize) | |||
1036 | ret = btrfs_set_extent_delalloc(inode, | 1036 | ret = btrfs_set_extent_delalloc(inode, |
1037 | BTRFS_MAX_EXTENT_SIZE + 2 * sectorsize, | 1037 | BTRFS_MAX_EXTENT_SIZE + 2 * sectorsize, |
1038 | (BTRFS_MAX_EXTENT_SIZE << 1) + 3 * sectorsize - 1, | 1038 | (BTRFS_MAX_EXTENT_SIZE << 1) + 3 * sectorsize - 1, |
1039 | NULL, 0); | 1039 | 0, NULL, 0); |
1040 | if (ret) { | 1040 | if (ret) { |
1041 | test_msg("btrfs_set_extent_delalloc returned %d\n", ret); | 1041 | test_msg("btrfs_set_extent_delalloc returned %d\n", ret); |
1042 | goto out; | 1042 | goto out; |
@@ -1053,7 +1053,7 @@ static int test_extent_accounting(u32 sectorsize, u32 nodesize) | |||
1053 | */ | 1053 | */ |
1054 | ret = btrfs_set_extent_delalloc(inode, | 1054 | ret = btrfs_set_extent_delalloc(inode, |
1055 | BTRFS_MAX_EXTENT_SIZE + sectorsize, | 1055 | BTRFS_MAX_EXTENT_SIZE + sectorsize, |
1056 | BTRFS_MAX_EXTENT_SIZE + 2 * sectorsize - 1, NULL, 0); | 1056 | BTRFS_MAX_EXTENT_SIZE + 2 * sectorsize - 1, 0, NULL, 0); |
1057 | if (ret) { | 1057 | if (ret) { |
1058 | test_msg("btrfs_set_extent_delalloc returned %d\n", ret); | 1058 | test_msg("btrfs_set_extent_delalloc returned %d\n", ret); |
1059 | goto out; | 1059 | goto out; |
@@ -1089,7 +1089,7 @@ static int test_extent_accounting(u32 sectorsize, u32 nodesize) | |||
1089 | */ | 1089 | */ |
1090 | ret = btrfs_set_extent_delalloc(inode, | 1090 | ret = btrfs_set_extent_delalloc(inode, |
1091 | BTRFS_MAX_EXTENT_SIZE + sectorsize, | 1091 | BTRFS_MAX_EXTENT_SIZE + sectorsize, |
1092 | BTRFS_MAX_EXTENT_SIZE + 2 * sectorsize - 1, NULL, 0); | 1092 | BTRFS_MAX_EXTENT_SIZE + 2 * sectorsize - 1, 0, NULL, 0); |
1093 | if (ret) { | 1093 | if (ret) { |
1094 | test_msg("btrfs_set_extent_delalloc returned %d\n", ret); | 1094 | test_msg("btrfs_set_extent_delalloc returned %d\n", ret); |
1095 | goto out; | 1095 | goto out; |
diff --git a/fs/btrfs/tree-checker.c b/fs/btrfs/tree-checker.c index 114fc5f0ecc5..ce4ed6ec8f39 100644 --- a/fs/btrfs/tree-checker.c +++ b/fs/btrfs/tree-checker.c | |||
@@ -242,7 +242,8 @@ static int check_leaf_item(struct btrfs_root *root, | |||
242 | return ret; | 242 | return ret; |
243 | } | 243 | } |
244 | 244 | ||
245 | int btrfs_check_leaf(struct btrfs_root *root, struct extent_buffer *leaf) | 245 | static int check_leaf(struct btrfs_root *root, struct extent_buffer *leaf, |
246 | bool check_item_data) | ||
246 | { | 247 | { |
247 | struct btrfs_fs_info *fs_info = root->fs_info; | 248 | struct btrfs_fs_info *fs_info = root->fs_info; |
248 | /* No valid key type is 0, so all key should be larger than this key */ | 249 | /* No valid key type is 0, so all key should be larger than this key */ |
@@ -361,10 +362,15 @@ int btrfs_check_leaf(struct btrfs_root *root, struct extent_buffer *leaf) | |||
361 | return -EUCLEAN; | 362 | return -EUCLEAN; |
362 | } | 363 | } |
363 | 364 | ||
364 | /* Check if the item size and content meet other criteria */ | 365 | if (check_item_data) { |
365 | ret = check_leaf_item(root, leaf, &key, slot); | 366 | /* |
366 | if (ret < 0) | 367 | * Check if the item size and content meet other |
367 | return ret; | 368 | * criteria |
369 | */ | ||
370 | ret = check_leaf_item(root, leaf, &key, slot); | ||
371 | if (ret < 0) | ||
372 | return ret; | ||
373 | } | ||
368 | 374 | ||
369 | prev_key.objectid = key.objectid; | 375 | prev_key.objectid = key.objectid; |
370 | prev_key.type = key.type; | 376 | prev_key.type = key.type; |
@@ -374,6 +380,17 @@ int btrfs_check_leaf(struct btrfs_root *root, struct extent_buffer *leaf) | |||
374 | return 0; | 380 | return 0; |
375 | } | 381 | } |
376 | 382 | ||
383 | int btrfs_check_leaf_full(struct btrfs_root *root, struct extent_buffer *leaf) | ||
384 | { | ||
385 | return check_leaf(root, leaf, true); | ||
386 | } | ||
387 | |||
388 | int btrfs_check_leaf_relaxed(struct btrfs_root *root, | ||
389 | struct extent_buffer *leaf) | ||
390 | { | ||
391 | return check_leaf(root, leaf, false); | ||
392 | } | ||
393 | |||
377 | int btrfs_check_node(struct btrfs_root *root, struct extent_buffer *node) | 394 | int btrfs_check_node(struct btrfs_root *root, struct extent_buffer *node) |
378 | { | 395 | { |
379 | unsigned long nr = btrfs_header_nritems(node); | 396 | unsigned long nr = btrfs_header_nritems(node); |
diff --git a/fs/btrfs/tree-checker.h b/fs/btrfs/tree-checker.h index 96c486e95d70..3d53e8d6fda0 100644 --- a/fs/btrfs/tree-checker.h +++ b/fs/btrfs/tree-checker.h | |||
@@ -20,7 +20,19 @@ | |||
20 | #include "ctree.h" | 20 | #include "ctree.h" |
21 | #include "extent_io.h" | 21 | #include "extent_io.h" |
22 | 22 | ||
23 | int btrfs_check_leaf(struct btrfs_root *root, struct extent_buffer *leaf); | 23 | /* |
24 | * Comprehensive leaf checker. | ||
25 | * Will check not only the item pointers, but also every possible member | ||
26 | * in item data. | ||
27 | */ | ||
28 | int btrfs_check_leaf_full(struct btrfs_root *root, struct extent_buffer *leaf); | ||
29 | |||
30 | /* | ||
31 | * Less strict leaf checker. | ||
32 | * Will only check item pointers, not reading item data. | ||
33 | */ | ||
34 | int btrfs_check_leaf_relaxed(struct btrfs_root *root, | ||
35 | struct extent_buffer *leaf); | ||
24 | int btrfs_check_node(struct btrfs_root *root, struct extent_buffer *node); | 36 | int btrfs_check_node(struct btrfs_root *root, struct extent_buffer *node); |
25 | 37 | ||
26 | #endif | 38 | #endif |
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index aa7c71cff575..7bf9b31561db 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c | |||
@@ -4102,7 +4102,7 @@ static int log_one_extent(struct btrfs_trans_handle *trans, | |||
4102 | 4102 | ||
4103 | if (ordered_io_err) { | 4103 | if (ordered_io_err) { |
4104 | ctx->io_err = -EIO; | 4104 | ctx->io_err = -EIO; |
4105 | return 0; | 4105 | return ctx->io_err; |
4106 | } | 4106 | } |
4107 | 4107 | ||
4108 | btrfs_init_map_token(&token); | 4108 | btrfs_init_map_token(&token); |
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index 925070b9ce03..49810b70afd3 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c | |||
@@ -189,6 +189,7 @@ static void free_fs_devices(struct btrfs_fs_devices *fs_devices) | |||
189 | struct btrfs_device, dev_list); | 189 | struct btrfs_device, dev_list); |
190 | list_del(&device->dev_list); | 190 | list_del(&device->dev_list); |
191 | rcu_string_free(device->name); | 191 | rcu_string_free(device->name); |
192 | bio_put(device->flush_bio); | ||
192 | kfree(device); | 193 | kfree(device); |
193 | } | 194 | } |
194 | kfree(fs_devices); | 195 | kfree(fs_devices); |
@@ -578,6 +579,7 @@ static void btrfs_free_stale_device(struct btrfs_device *cur_dev) | |||
578 | fs_devs->num_devices--; | 579 | fs_devs->num_devices--; |
579 | list_del(&dev->dev_list); | 580 | list_del(&dev->dev_list); |
580 | rcu_string_free(dev->name); | 581 | rcu_string_free(dev->name); |
582 | bio_put(dev->flush_bio); | ||
581 | kfree(dev); | 583 | kfree(dev); |
582 | } | 584 | } |
583 | break; | 585 | break; |
@@ -630,6 +632,7 @@ static noinline int device_list_add(const char *path, | |||
630 | 632 | ||
631 | name = rcu_string_strdup(path, GFP_NOFS); | 633 | name = rcu_string_strdup(path, GFP_NOFS); |
632 | if (!name) { | 634 | if (!name) { |
635 | bio_put(device->flush_bio); | ||
633 | kfree(device); | 636 | kfree(device); |
634 | return -ENOMEM; | 637 | return -ENOMEM; |
635 | } | 638 | } |
@@ -742,6 +745,7 @@ static struct btrfs_fs_devices *clone_fs_devices(struct btrfs_fs_devices *orig) | |||
742 | name = rcu_string_strdup(orig_dev->name->str, | 745 | name = rcu_string_strdup(orig_dev->name->str, |
743 | GFP_KERNEL); | 746 | GFP_KERNEL); |
744 | if (!name) { | 747 | if (!name) { |
748 | bio_put(device->flush_bio); | ||
745 | kfree(device); | 749 | kfree(device); |
746 | goto error; | 750 | goto error; |
747 | } | 751 | } |
@@ -807,6 +811,7 @@ again: | |||
807 | list_del_init(&device->dev_list); | 811 | list_del_init(&device->dev_list); |
808 | fs_devices->num_devices--; | 812 | fs_devices->num_devices--; |
809 | rcu_string_free(device->name); | 813 | rcu_string_free(device->name); |
814 | bio_put(device->flush_bio); | ||
810 | kfree(device); | 815 | kfree(device); |
811 | } | 816 | } |
812 | 817 | ||
@@ -1750,20 +1755,24 @@ static int btrfs_rm_dev_item(struct btrfs_fs_info *fs_info, | |||
1750 | key.offset = device->devid; | 1755 | key.offset = device->devid; |
1751 | 1756 | ||
1752 | ret = btrfs_search_slot(trans, root, &key, path, -1, 1); | 1757 | ret = btrfs_search_slot(trans, root, &key, path, -1, 1); |
1753 | if (ret < 0) | 1758 | if (ret) { |
1754 | goto out; | 1759 | if (ret > 0) |
1755 | 1760 | ret = -ENOENT; | |
1756 | if (ret > 0) { | 1761 | btrfs_abort_transaction(trans, ret); |
1757 | ret = -ENOENT; | 1762 | btrfs_end_transaction(trans); |
1758 | goto out; | 1763 | goto out; |
1759 | } | 1764 | } |
1760 | 1765 | ||
1761 | ret = btrfs_del_item(trans, root, path); | 1766 | ret = btrfs_del_item(trans, root, path); |
1762 | if (ret) | 1767 | if (ret) { |
1763 | goto out; | 1768 | btrfs_abort_transaction(trans, ret); |
1769 | btrfs_end_transaction(trans); | ||
1770 | } | ||
1771 | |||
1764 | out: | 1772 | out: |
1765 | btrfs_free_path(path); | 1773 | btrfs_free_path(path); |
1766 | btrfs_commit_transaction(trans); | 1774 | if (!ret) |
1775 | ret = btrfs_commit_transaction(trans); | ||
1767 | return ret; | 1776 | return ret; |
1768 | } | 1777 | } |
1769 | 1778 | ||
@@ -1993,7 +2002,7 @@ void btrfs_rm_dev_replace_remove_srcdev(struct btrfs_fs_info *fs_info, | |||
1993 | fs_devices = srcdev->fs_devices; | 2002 | fs_devices = srcdev->fs_devices; |
1994 | 2003 | ||
1995 | list_del_rcu(&srcdev->dev_list); | 2004 | list_del_rcu(&srcdev->dev_list); |
1996 | list_del_rcu(&srcdev->dev_alloc_list); | 2005 | list_del(&srcdev->dev_alloc_list); |
1997 | fs_devices->num_devices--; | 2006 | fs_devices->num_devices--; |
1998 | if (srcdev->missing) | 2007 | if (srcdev->missing) |
1999 | fs_devices->missing_devices--; | 2008 | fs_devices->missing_devices--; |
@@ -2349,6 +2358,7 @@ int btrfs_init_new_device(struct btrfs_fs_info *fs_info, const char *device_path | |||
2349 | 2358 | ||
2350 | name = rcu_string_strdup(device_path, GFP_KERNEL); | 2359 | name = rcu_string_strdup(device_path, GFP_KERNEL); |
2351 | if (!name) { | 2360 | if (!name) { |
2361 | bio_put(device->flush_bio); | ||
2352 | kfree(device); | 2362 | kfree(device); |
2353 | ret = -ENOMEM; | 2363 | ret = -ENOMEM; |
2354 | goto error; | 2364 | goto error; |
@@ -2358,6 +2368,7 @@ int btrfs_init_new_device(struct btrfs_fs_info *fs_info, const char *device_path | |||
2358 | trans = btrfs_start_transaction(root, 0); | 2368 | trans = btrfs_start_transaction(root, 0); |
2359 | if (IS_ERR(trans)) { | 2369 | if (IS_ERR(trans)) { |
2360 | rcu_string_free(device->name); | 2370 | rcu_string_free(device->name); |
2371 | bio_put(device->flush_bio); | ||
2361 | kfree(device); | 2372 | kfree(device); |
2362 | ret = PTR_ERR(trans); | 2373 | ret = PTR_ERR(trans); |
2363 | goto error; | 2374 | goto error; |
@@ -2501,6 +2512,7 @@ error_trans: | |||
2501 | if (trans) | 2512 | if (trans) |
2502 | btrfs_end_transaction(trans); | 2513 | btrfs_end_transaction(trans); |
2503 | rcu_string_free(device->name); | 2514 | rcu_string_free(device->name); |
2515 | bio_put(device->flush_bio); | ||
2504 | kfree(device); | 2516 | kfree(device); |
2505 | error: | 2517 | error: |
2506 | blkdev_put(bdev, FMODE_EXCL); | 2518 | blkdev_put(bdev, FMODE_EXCL); |
@@ -2567,6 +2579,7 @@ int btrfs_init_dev_replace_tgtdev(struct btrfs_fs_info *fs_info, | |||
2567 | 2579 | ||
2568 | name = rcu_string_strdup(device_path, GFP_KERNEL); | 2580 | name = rcu_string_strdup(device_path, GFP_KERNEL); |
2569 | if (!name) { | 2581 | if (!name) { |
2582 | bio_put(device->flush_bio); | ||
2570 | kfree(device); | 2583 | kfree(device); |
2571 | ret = -ENOMEM; | 2584 | ret = -ENOMEM; |
2572 | goto error; | 2585 | goto error; |
@@ -6284,6 +6297,7 @@ struct btrfs_device *btrfs_alloc_device(struct btrfs_fs_info *fs_info, | |||
6284 | 6297 | ||
6285 | ret = find_next_devid(fs_info, &tmp); | 6298 | ret = find_next_devid(fs_info, &tmp); |
6286 | if (ret) { | 6299 | if (ret) { |
6300 | bio_put(dev->flush_bio); | ||
6287 | kfree(dev); | 6301 | kfree(dev); |
6288 | return ERR_PTR(ret); | 6302 | return ERR_PTR(ret); |
6289 | } | 6303 | } |