diff options
Diffstat (limited to 'fs/btrfs/disk-io.c')
| -rw-r--r-- | fs/btrfs/disk-io.c | 108 |
1 files changed, 21 insertions, 87 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 087eed85c250..a2eb3a3755db 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
| @@ -29,6 +29,7 @@ | |||
| 29 | #include <linux/crc32c.h> | 29 | #include <linux/crc32c.h> |
| 30 | #include <linux/slab.h> | 30 | #include <linux/slab.h> |
| 31 | #include <linux/migrate.h> | 31 | #include <linux/migrate.h> |
| 32 | #include <linux/ratelimit.h> | ||
| 32 | #include <asm/unaligned.h> | 33 | #include <asm/unaligned.h> |
| 33 | #include "compat.h" | 34 | #include "compat.h" |
| 34 | #include "ctree.h" | 35 | #include "ctree.h" |
| @@ -138,7 +139,7 @@ static const char *btrfs_eb_name[BTRFS_MAX_LEVEL + 1] = { | |||
| 138 | * that covers the entire device | 139 | * that covers the entire device |
| 139 | */ | 140 | */ |
| 140 | static struct extent_map *btree_get_extent(struct inode *inode, | 141 | static struct extent_map *btree_get_extent(struct inode *inode, |
| 141 | struct page *page, size_t page_offset, u64 start, u64 len, | 142 | struct page *page, size_t pg_offset, u64 start, u64 len, |
| 142 | int create) | 143 | int create) |
| 143 | { | 144 | { |
| 144 | struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree; | 145 | struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree; |
| @@ -155,7 +156,7 @@ static struct extent_map *btree_get_extent(struct inode *inode, | |||
| 155 | } | 156 | } |
| 156 | read_unlock(&em_tree->lock); | 157 | read_unlock(&em_tree->lock); |
| 157 | 158 | ||
| 158 | em = alloc_extent_map(GFP_NOFS); | 159 | em = alloc_extent_map(); |
| 159 | if (!em) { | 160 | if (!em) { |
| 160 | em = ERR_PTR(-ENOMEM); | 161 | em = ERR_PTR(-ENOMEM); |
| 161 | goto out; | 162 | goto out; |
| @@ -255,14 +256,12 @@ static int csum_tree_block(struct btrfs_root *root, struct extent_buffer *buf, | |||
| 255 | memcpy(&found, result, csum_size); | 256 | memcpy(&found, result, csum_size); |
| 256 | 257 | ||
| 257 | read_extent_buffer(buf, &val, 0, csum_size); | 258 | read_extent_buffer(buf, &val, 0, csum_size); |
| 258 | if (printk_ratelimit()) { | 259 | printk_ratelimited(KERN_INFO "btrfs: %s checksum verify " |
| 259 | printk(KERN_INFO "btrfs: %s checksum verify " | ||
| 260 | "failed on %llu wanted %X found %X " | 260 | "failed on %llu wanted %X found %X " |
| 261 | "level %d\n", | 261 | "level %d\n", |
| 262 | root->fs_info->sb->s_id, | 262 | root->fs_info->sb->s_id, |
| 263 | (unsigned long long)buf->start, val, found, | 263 | (unsigned long long)buf->start, val, found, |
| 264 | btrfs_header_level(buf)); | 264 | btrfs_header_level(buf)); |
| 265 | } | ||
| 266 | if (result != (char *)&inline_result) | 265 | if (result != (char *)&inline_result) |
| 267 | kfree(result); | 266 | kfree(result); |
| 268 | return 1; | 267 | return 1; |
| @@ -297,13 +296,11 @@ static int verify_parent_transid(struct extent_io_tree *io_tree, | |||
| 297 | ret = 0; | 296 | ret = 0; |
| 298 | goto out; | 297 | goto out; |
| 299 | } | 298 | } |
| 300 | if (printk_ratelimit()) { | 299 | printk_ratelimited("parent transid verify failed on %llu wanted %llu " |
| 301 | printk("parent transid verify failed on %llu wanted %llu " | ||
| 302 | "found %llu\n", | 300 | "found %llu\n", |
| 303 | (unsigned long long)eb->start, | 301 | (unsigned long long)eb->start, |
| 304 | (unsigned long long)parent_transid, | 302 | (unsigned long long)parent_transid, |
| 305 | (unsigned long long)btrfs_header_generation(eb)); | 303 | (unsigned long long)btrfs_header_generation(eb)); |
| 306 | } | ||
| 307 | ret = 1; | 304 | ret = 1; |
| 308 | clear_extent_buffer_uptodate(io_tree, eb, &cached_state); | 305 | clear_extent_buffer_uptodate(io_tree, eb, &cached_state); |
| 309 | out: | 306 | out: |
| @@ -381,7 +378,7 @@ static int csum_dirty_buffer(struct btrfs_root *root, struct page *page) | |||
| 381 | len = page->private >> 2; | 378 | len = page->private >> 2; |
| 382 | WARN_ON(len == 0); | 379 | WARN_ON(len == 0); |
| 383 | 380 | ||
| 384 | eb = alloc_extent_buffer(tree, start, len, page, GFP_NOFS); | 381 | eb = alloc_extent_buffer(tree, start, len, page); |
| 385 | if (eb == NULL) { | 382 | if (eb == NULL) { |
| 386 | WARN_ON(1); | 383 | WARN_ON(1); |
| 387 | goto out; | 384 | goto out; |
| @@ -526,7 +523,7 @@ static int btree_readpage_end_io_hook(struct page *page, u64 start, u64 end, | |||
| 526 | len = page->private >> 2; | 523 | len = page->private >> 2; |
| 527 | WARN_ON(len == 0); | 524 | WARN_ON(len == 0); |
| 528 | 525 | ||
| 529 | eb = alloc_extent_buffer(tree, start, len, page, GFP_NOFS); | 526 | eb = alloc_extent_buffer(tree, start, len, page); |
| 530 | if (eb == NULL) { | 527 | if (eb == NULL) { |
| 531 | ret = -EIO; | 528 | ret = -EIO; |
| 532 | goto out; | 529 | goto out; |
| @@ -534,12 +531,10 @@ static int btree_readpage_end_io_hook(struct page *page, u64 start, u64 end, | |||
| 534 | 531 | ||
| 535 | found_start = btrfs_header_bytenr(eb); | 532 | found_start = btrfs_header_bytenr(eb); |
| 536 | if (found_start != start) { | 533 | if (found_start != start) { |
| 537 | if (printk_ratelimit()) { | 534 | printk_ratelimited(KERN_INFO "btrfs bad tree block start " |
| 538 | printk(KERN_INFO "btrfs bad tree block start " | ||
| 539 | "%llu %llu\n", | 535 | "%llu %llu\n", |
| 540 | (unsigned long long)found_start, | 536 | (unsigned long long)found_start, |
| 541 | (unsigned long long)eb->start); | 537 | (unsigned long long)eb->start); |
| 542 | } | ||
| 543 | ret = -EIO; | 538 | ret = -EIO; |
| 544 | goto err; | 539 | goto err; |
| 545 | } | 540 | } |
| @@ -551,10 +546,8 @@ static int btree_readpage_end_io_hook(struct page *page, u64 start, u64 end, | |||
| 551 | goto err; | 546 | goto err; |
| 552 | } | 547 | } |
| 553 | if (check_tree_block_fsid(root, eb)) { | 548 | if (check_tree_block_fsid(root, eb)) { |
| 554 | if (printk_ratelimit()) { | 549 | printk_ratelimited(KERN_INFO "btrfs bad fsid on block %llu\n", |
| 555 | printk(KERN_INFO "btrfs bad fsid on block %llu\n", | ||
| 556 | (unsigned long long)eb->start); | 550 | (unsigned long long)eb->start); |
| 557 | } | ||
| 558 | ret = -EIO; | 551 | ret = -EIO; |
| 559 | goto err; | 552 | goto err; |
| 560 | } | 553 | } |
| @@ -651,12 +644,6 @@ unsigned long btrfs_async_submit_limit(struct btrfs_fs_info *info) | |||
| 651 | return 256 * limit; | 644 | return 256 * limit; |
| 652 | } | 645 | } |
| 653 | 646 | ||
| 654 | int btrfs_congested_async(struct btrfs_fs_info *info, int iodone) | ||
| 655 | { | ||
| 656 | return atomic_read(&info->nr_async_bios) > | ||
| 657 | btrfs_async_submit_limit(info); | ||
| 658 | } | ||
| 659 | |||
| 660 | static void run_one_async_start(struct btrfs_work *work) | 647 | static void run_one_async_start(struct btrfs_work *work) |
| 661 | { | 648 | { |
| 662 | struct async_submit_bio *async; | 649 | struct async_submit_bio *async; |
| @@ -964,7 +951,7 @@ struct extent_buffer *btrfs_find_tree_block(struct btrfs_root *root, | |||
| 964 | struct inode *btree_inode = root->fs_info->btree_inode; | 951 | struct inode *btree_inode = root->fs_info->btree_inode; |
| 965 | struct extent_buffer *eb; | 952 | struct extent_buffer *eb; |
| 966 | eb = find_extent_buffer(&BTRFS_I(btree_inode)->io_tree, | 953 | eb = find_extent_buffer(&BTRFS_I(btree_inode)->io_tree, |
| 967 | bytenr, blocksize, GFP_NOFS); | 954 | bytenr, blocksize); |
| 968 | return eb; | 955 | return eb; |
| 969 | } | 956 | } |
| 970 | 957 | ||
| @@ -975,7 +962,7 @@ struct extent_buffer *btrfs_find_create_tree_block(struct btrfs_root *root, | |||
| 975 | struct extent_buffer *eb; | 962 | struct extent_buffer *eb; |
| 976 | 963 | ||
| 977 | eb = alloc_extent_buffer(&BTRFS_I(btree_inode)->io_tree, | 964 | eb = alloc_extent_buffer(&BTRFS_I(btree_inode)->io_tree, |
| 978 | bytenr, blocksize, NULL, GFP_NOFS); | 965 | bytenr, blocksize, NULL); |
| 979 | return eb; | 966 | return eb; |
| 980 | } | 967 | } |
| 981 | 968 | ||
| @@ -1082,7 +1069,7 @@ static int __setup_root(u32 nodesize, u32 leafsize, u32 sectorsize, | |||
| 1082 | root->log_transid = 0; | 1069 | root->log_transid = 0; |
| 1083 | root->last_log_commit = 0; | 1070 | root->last_log_commit = 0; |
| 1084 | extent_io_tree_init(&root->dirty_log_pages, | 1071 | extent_io_tree_init(&root->dirty_log_pages, |
| 1085 | fs_info->btree_inode->i_mapping, GFP_NOFS); | 1072 | fs_info->btree_inode->i_mapping); |
| 1086 | 1073 | ||
| 1087 | memset(&root->root_key, 0, sizeof(root->root_key)); | 1074 | memset(&root->root_key, 0, sizeof(root->root_key)); |
| 1088 | memset(&root->root_item, 0, sizeof(root->root_item)); | 1075 | memset(&root->root_item, 0, sizeof(root->root_item)); |
| @@ -1285,21 +1272,6 @@ out: | |||
| 1285 | return root; | 1272 | return root; |
| 1286 | } | 1273 | } |
| 1287 | 1274 | ||
| 1288 | struct btrfs_root *btrfs_lookup_fs_root(struct btrfs_fs_info *fs_info, | ||
| 1289 | u64 root_objectid) | ||
| 1290 | { | ||
| 1291 | struct btrfs_root *root; | ||
| 1292 | |||
| 1293 | if (root_objectid == BTRFS_ROOT_TREE_OBJECTID) | ||
| 1294 | return fs_info->tree_root; | ||
| 1295 | if (root_objectid == BTRFS_EXTENT_TREE_OBJECTID) | ||
| 1296 | return fs_info->extent_root; | ||
| 1297 | |||
| 1298 | root = radix_tree_lookup(&fs_info->fs_roots_radix, | ||
| 1299 | (unsigned long)root_objectid); | ||
| 1300 | return root; | ||
| 1301 | } | ||
| 1302 | |||
| 1303 | struct btrfs_root *btrfs_read_fs_root_no_name(struct btrfs_fs_info *fs_info, | 1275 | struct btrfs_root *btrfs_read_fs_root_no_name(struct btrfs_fs_info *fs_info, |
| 1304 | struct btrfs_key *location) | 1276 | struct btrfs_key *location) |
| 1305 | { | 1277 | { |
| @@ -1384,41 +1356,6 @@ fail: | |||
| 1384 | return ERR_PTR(ret); | 1356 | return ERR_PTR(ret); |
| 1385 | } | 1357 | } |
| 1386 | 1358 | ||
| 1387 | struct btrfs_root *btrfs_read_fs_root(struct btrfs_fs_info *fs_info, | ||
| 1388 | struct btrfs_key *location, | ||
| 1389 | const char *name, int namelen) | ||
| 1390 | { | ||
| 1391 | return btrfs_read_fs_root_no_name(fs_info, location); | ||
| 1392 | #if 0 | ||
| 1393 | struct btrfs_root *root; | ||
| 1394 | int ret; | ||
| 1395 | |||
| 1396 | root = btrfs_read_fs_root_no_name(fs_info, location); | ||
| 1397 | if (!root) | ||
| 1398 | return NULL; | ||
| 1399 | |||
| 1400 | if (root->in_sysfs) | ||
| 1401 | return root; | ||
| 1402 | |||
| 1403 | ret = btrfs_set_root_name(root, name, namelen); | ||
| 1404 | if (ret) { | ||
| 1405 | free_extent_buffer(root->node); | ||
| 1406 | kfree(root); | ||
| 1407 | return ERR_PTR(ret); | ||
| 1408 | } | ||
| 1409 | |||
| 1410 | ret = btrfs_sysfs_add_root(root); | ||
| 1411 | if (ret) { | ||
| 1412 | free_extent_buffer(root->node); | ||
| 1413 | kfree(root->name); | ||
| 1414 | kfree(root); | ||
| 1415 | return ERR_PTR(ret); | ||
| 1416 | } | ||
| 1417 | root->in_sysfs = 1; | ||
| 1418 | return root; | ||
| 1419 | #endif | ||
| 1420 | } | ||
| 1421 | |||
| 1422 | static int btrfs_congested_fn(void *congested_data, int bdi_bits) | 1359 | static int btrfs_congested_fn(void *congested_data, int bdi_bits) |
| 1423 | { | 1360 | { |
| 1424 | struct btrfs_fs_info *info = (struct btrfs_fs_info *)congested_data; | 1361 | struct btrfs_fs_info *info = (struct btrfs_fs_info *)congested_data; |
| @@ -1626,7 +1563,7 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
| 1626 | struct btrfs_root *csum_root = kzalloc(sizeof(struct btrfs_root), | 1563 | struct btrfs_root *csum_root = kzalloc(sizeof(struct btrfs_root), |
| 1627 | GFP_NOFS); | 1564 | GFP_NOFS); |
| 1628 | struct btrfs_root *tree_root = btrfs_sb(sb); | 1565 | struct btrfs_root *tree_root = btrfs_sb(sb); |
| 1629 | struct btrfs_fs_info *fs_info = tree_root->fs_info; | 1566 | struct btrfs_fs_info *fs_info = NULL; |
| 1630 | struct btrfs_root *chunk_root = kzalloc(sizeof(struct btrfs_root), | 1567 | struct btrfs_root *chunk_root = kzalloc(sizeof(struct btrfs_root), |
| 1631 | GFP_NOFS); | 1568 | GFP_NOFS); |
| 1632 | struct btrfs_root *dev_root = kzalloc(sizeof(struct btrfs_root), | 1569 | struct btrfs_root *dev_root = kzalloc(sizeof(struct btrfs_root), |
| @@ -1638,11 +1575,12 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
| 1638 | 1575 | ||
| 1639 | struct btrfs_super_block *disk_super; | 1576 | struct btrfs_super_block *disk_super; |
| 1640 | 1577 | ||
| 1641 | if (!extent_root || !tree_root || !fs_info || | 1578 | if (!extent_root || !tree_root || !tree_root->fs_info || |
| 1642 | !chunk_root || !dev_root || !csum_root) { | 1579 | !chunk_root || !dev_root || !csum_root) { |
| 1643 | err = -ENOMEM; | 1580 | err = -ENOMEM; |
| 1644 | goto fail; | 1581 | goto fail; |
| 1645 | } | 1582 | } |
| 1583 | fs_info = tree_root->fs_info; | ||
| 1646 | 1584 | ||
| 1647 | ret = init_srcu_struct(&fs_info->subvol_srcu); | 1585 | ret = init_srcu_struct(&fs_info->subvol_srcu); |
| 1648 | if (ret) { | 1586 | if (ret) { |
| @@ -1733,10 +1671,8 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
| 1733 | 1671 | ||
| 1734 | RB_CLEAR_NODE(&BTRFS_I(fs_info->btree_inode)->rb_node); | 1672 | RB_CLEAR_NODE(&BTRFS_I(fs_info->btree_inode)->rb_node); |
| 1735 | extent_io_tree_init(&BTRFS_I(fs_info->btree_inode)->io_tree, | 1673 | extent_io_tree_init(&BTRFS_I(fs_info->btree_inode)->io_tree, |
| 1736 | fs_info->btree_inode->i_mapping, | 1674 | fs_info->btree_inode->i_mapping); |
| 1737 | GFP_NOFS); | 1675 | extent_map_tree_init(&BTRFS_I(fs_info->btree_inode)->extent_tree); |
| 1738 | extent_map_tree_init(&BTRFS_I(fs_info->btree_inode)->extent_tree, | ||
| 1739 | GFP_NOFS); | ||
| 1740 | 1676 | ||
| 1741 | BTRFS_I(fs_info->btree_inode)->io_tree.ops = &btree_extent_io_ops; | 1677 | BTRFS_I(fs_info->btree_inode)->io_tree.ops = &btree_extent_io_ops; |
| 1742 | 1678 | ||
| @@ -1750,9 +1686,9 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
| 1750 | fs_info->block_group_cache_tree = RB_ROOT; | 1686 | fs_info->block_group_cache_tree = RB_ROOT; |
| 1751 | 1687 | ||
| 1752 | extent_io_tree_init(&fs_info->freed_extents[0], | 1688 | extent_io_tree_init(&fs_info->freed_extents[0], |
| 1753 | fs_info->btree_inode->i_mapping, GFP_NOFS); | 1689 | fs_info->btree_inode->i_mapping); |
| 1754 | extent_io_tree_init(&fs_info->freed_extents[1], | 1690 | extent_io_tree_init(&fs_info->freed_extents[1], |
| 1755 | fs_info->btree_inode->i_mapping, GFP_NOFS); | 1691 | fs_info->btree_inode->i_mapping); |
| 1756 | fs_info->pinned_extents = &fs_info->freed_extents[0]; | 1692 | fs_info->pinned_extents = &fs_info->freed_extents[0]; |
| 1757 | fs_info->do_barriers = 1; | 1693 | fs_info->do_barriers = 1; |
| 1758 | 1694 | ||
| @@ -2194,11 +2130,9 @@ static void btrfs_end_buffer_write_sync(struct buffer_head *bh, int uptodate) | |||
| 2194 | if (uptodate) { | 2130 | if (uptodate) { |
| 2195 | set_buffer_uptodate(bh); | 2131 | set_buffer_uptodate(bh); |
| 2196 | } else { | 2132 | } else { |
| 2197 | if (printk_ratelimit()) { | 2133 | printk_ratelimited(KERN_WARNING "lost page write due to " |
| 2198 | printk(KERN_WARNING "lost page write due to " | ||
| 2199 | "I/O error on %s\n", | 2134 | "I/O error on %s\n", |
| 2200 | bdevname(bh->b_bdev, b)); | 2135 | bdevname(bh->b_bdev, b)); |
| 2201 | } | ||
| 2202 | /* note, we dont' set_buffer_write_io_error because we have | 2136 | /* note, we dont' set_buffer_write_io_error because we have |
| 2203 | * our own ways of dealing with the IO errors | 2137 | * our own ways of dealing with the IO errors |
| 2204 | */ | 2138 | */ |
| @@ -2756,7 +2690,7 @@ int btree_lock_page_hook(struct page *page) | |||
| 2756 | goto out; | 2690 | goto out; |
| 2757 | 2691 | ||
| 2758 | len = page->private >> 2; | 2692 | len = page->private >> 2; |
| 2759 | eb = find_extent_buffer(io_tree, bytenr, len, GFP_NOFS); | 2693 | eb = find_extent_buffer(io_tree, bytenr, len); |
| 2760 | if (!eb) | 2694 | if (!eb) |
| 2761 | goto out; | 2695 | goto out; |
| 2762 | 2696 | ||
