Pull btrfs fixes from Chris Mason: "These are bug fixes, including a really old fsync bug, and a few trace points to help us track down problems in the quota code" * 'for-linus-4.6' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs: Btrfs: fix file/data loss caused by fsync after rename and new inode btrfs: Reset IO error counters before start of device replacing btrfs: Add qgroup tracing Btrfs: don't use src fd for printk btrfs: fallback to vmalloc in btrfs_compare_tree btrfs: handle non-fatal errors in btrfs_qgroup_inherit() btrfs: Output more info for enospc_debug mount option Btrfs: fix invalid reference in replace_path Btrfs: Improve FL_KEEP_SIZE handling in fallocate
Unified · Split
| @@ -19,6 +19,7 @@ · 18 unmodified lines | |||
| 19 | #include <linux/sched.h> | 19 | #include <linux/sched.h> |
| 20 | #include <linux/slab.h> | 20 | #include <linux/slab.h> |
| 21 | #include <linux/rbtree.h> | 21 | #include <linux/rbtree.h> |
| 22 | #include <linux/vmalloc.h> | ||
| 22 | #include "ctree.h" | 23 | #include "ctree.h" |
| 23 | #include "disk-io.h" | 24 | #include "disk-io.h" |
| 24 | #include "transaction.h" | 25 | #include "transaction.h" |
| @@ -5361,10 +5362,13 @@ int btrfs_compare_trees(struct btrfs_root *left_root, · 5336 unmodified lines | |||
| 5361 | goto out; | 5362 | goto out; |
| 5362 | } | 5363 | } |
| 5363 | 5364 | ||
| 5364 | tmp_buf = kmalloc(left_root->nodesize, GFP_KERNEL); | 5365 | tmp_buf = kmalloc(left_root->nodesize, GFP_KERNEL | __GFP_NOWARN); |
| 5365 | if (!tmp_buf) { | 5366 | if (!tmp_buf) { |
| 5366 | ret = -ENOMEM; | 5367 | tmp_buf = vmalloc(left_root->nodesize); |
| 5367 | goto out; | 5368 | if (!tmp_buf) { |
| 5369 | ret = -ENOMEM; | ||
| 5370 | goto out; | ||
| 5371 | } | ||
| 5368 | } | 5372 | } |
| 5369 | 5373 | ||
| 5370 | left_path->search_commit_root = 1; | 5374 | left_path->search_commit_root = 1; |
| @@ -5565,7 +5569,7 @@ int btrfs_compare_trees(struct btrfs_root *left_root, · 194 unmodified lines | |||
| 5565 | out: | 5569 | out: |
| 5566 | btrfs_free_path(left_path); | 5570 | btrfs_free_path(left_path); |
| 5567 | btrfs_free_path(right_path); | 5571 | btrfs_free_path(right_path); |
| 5568 | kfree(tmp_buf); | 5572 | kvfree(tmp_buf); |
| 5569 | return ret; | 5573 | return ret; |
| 5570 | } | 5574 | } |
| 5571 | 5575 | ||
| @@ -394,6 +394,8 @@ int btrfs_dev_replace_start(struct btrfs_root *root, · 393 unmodified lines | |||
| 394 | dev_replace->cursor_right = 0; | 394 | dev_replace->cursor_right = 0; |
| 395 | dev_replace->is_valid = 1; | 395 | dev_replace->is_valid = 1; |
| 396 | dev_replace->item_needs_writeback = 1; | 396 | dev_replace->item_needs_writeback = 1; |
| 397 | atomic64_set(&dev_replace->num_write_errors, 0); | ||
| 398 | atomic64_set(&dev_replace->num_uncorrectable_read_errors, 0); | ||
| 397 | args->result = BTRFS_IOCTL_DEV_REPLACE_RESULT_NO_ERROR; | 399 | args->result = BTRFS_IOCTL_DEV_REPLACE_RESULT_NO_ERROR; |
| 398 | btrfs_dev_replace_unlock(dev_replace, 1); | 400 | btrfs_dev_replace_unlock(dev_replace, 1); |
| 399 | 401 | ||
| @@ -9386,15 +9386,23 @@ int btrfs_can_relocate(struct btrfs_root *root, u64 bytenr) · 9385 unmodified lines | |||
| 9386 | u64 dev_min = 1; | 9386 | u64 dev_min = 1; |
| 9387 | u64 dev_nr = 0; | 9387 | u64 dev_nr = 0; |
| 9388 | u64 target; | 9388 | u64 target; |
| 9389 | int debug; | ||
| 9389 | int index; | 9390 | int index; |
| 9390 | int full = 0; | 9391 | int full = 0; |
| 9391 | int ret = 0; | 9392 | int ret = 0; |
| 9392 | 9393 | ||
| 9394 | debug = btrfs_test_opt(root, ENOSPC_DEBUG); | ||
| 9395 | |||
| 9393 | block_group = btrfs_lookup_block_group(root->fs_info, bytenr); | 9396 | block_group = btrfs_lookup_block_group(root->fs_info, bytenr); |
| 9394 | 9397 | ||
| 9395 | /* odd, couldn't find the block group, leave it alone */ | 9398 | /* odd, couldn't find the block group, leave it alone */ |
| 9396 | if (!block_group) | 9399 | if (!block_group) { |
| 9400 | if (debug) | ||
| 9401 | btrfs_warn(root->fs_info, | ||
| 9402 | "can't find block group for bytenr %llu", | ||
| 9403 | bytenr); | ||
| 9397 | return -1; | 9404 | return -1; |
| 9405 | } | ||
| 9398 | 9406 | ||
| 9399 | min_free = btrfs_block_group_used(&block_group->item); | 9407 | min_free = btrfs_block_group_used(&block_group->item); |
| 9400 | 9408 | ||
| @@ -9448,8 +9456,13 @@ int btrfs_can_relocate(struct btrfs_root *root, u64 bytenr) · 47 unmodified lines | |||
| 9448 | * this is just a balance, so if we were marked as full | 9456 | * this is just a balance, so if we were marked as full |
| 9449 | * we know there is no space for a new chunk | 9457 | * we know there is no space for a new chunk |
| 9450 | */ | 9458 | */ |
| 9451 | if (full) | 9459 | if (full) { |
| 9460 | if (debug) | ||
| 9461 | btrfs_warn(root->fs_info, | ||
| 9462 | "no space to alloc new chunk for block group %llu", | ||
| 9463 | block_group->key.objectid); | ||
| 9452 | goto out; | 9464 | goto out; |
| 9465 | } | ||
| 9453 | 9466 | ||
| 9454 | index = get_block_group_index(block_group); | 9467 | index = get_block_group_index(block_group); |
| 9455 | } | 9468 | } |
| @@ -9496,6 +9509,10 @@ int btrfs_can_relocate(struct btrfs_root *root, u64 bytenr) · 40 unmodified lines | |||
| 9496 | ret = -1; | 9509 | ret = -1; |
| 9497 | } | 9510 | } |
| 9498 | } | 9511 | } |
| 9512 | if (debug && ret == -1) | ||
| 9513 | btrfs_warn(root->fs_info, | ||
| 9514 | "no space to allocate a new chunk for block group %llu", | ||
| 9515 | block_group->key.objectid); | ||
| 9499 | mutex_unlock(&root->fs_info->chunk_mutex); | 9516 | mutex_unlock(&root->fs_info->chunk_mutex); |
| 9500 | btrfs_end_transaction(trans, root); | 9517 | btrfs_end_transaction(trans, root); |
| 9501 | out: | 9518 | out: |
| @@ -2682,9 +2682,12 @@ static long btrfs_fallocate(struct file *file, int mode, · 2681 unmodified lines | |||
| 2682 | return ret; | 2682 | return ret; |
| 2683 | 2683 | ||
| 2684 | inode_lock(inode); | 2684 | inode_lock(inode); |
| 2685 | ret = inode_newsize_ok(inode, alloc_end); | 2685 | |
| 2686 | if (ret) | 2686 | if (!(mode & FALLOC_FL_KEEP_SIZE) && offset + len > inode->i_size) { |
| 2687 | goto out; | 2687 | ret = inode_newsize_ok(inode, offset + len); |
| 2688 | if (ret) | ||
| 2689 | goto out; | ||
| 2690 | } | ||
| 2688 | 2691 | ||
| 2689 | /* | 2692 | /* |
| 2690 | * TODO: Move these two operations after we have checked | 2693 | * TODO: Move these two operations after we have checked |
| @@ -1654,7 +1654,7 @@ static noinline int btrfs_ioctl_snap_create_transid(struct file *file, · 1653 unmodified lines | |||
| 1654 | 1654 | ||
| 1655 | src_inode = file_inode(src.file); | 1655 | src_inode = file_inode(src.file); |
| 1656 | if (src_inode->i_sb != file_inode(file)->i_sb) { | 1656 | if (src_inode->i_sb != file_inode(file)->i_sb) { |
| 1657 | btrfs_info(BTRFS_I(src_inode)->root->fs_info, | 1657 | btrfs_info(BTRFS_I(file_inode(file))->root->fs_info, |
| 1658 | "Snapshot src from another FS"); | 1658 | "Snapshot src from another FS"); |
| 1659 | ret = -EXDEV; | 1659 | ret = -EXDEV; |
| 1660 | } else if (!inode_owner_or_capable(src_inode)) { | 1660 | } else if (!inode_owner_or_capable(src_inode)) { |
| @@ -1463,6 +1463,7 @@ struct btrfs_qgroup_extent_record · 1462 unmodified lines | |||
| 1463 | u64 bytenr = record->bytenr; | 1463 | u64 bytenr = record->bytenr; |
| 1464 | 1464 | ||
| 1465 | assert_spin_locked(&delayed_refs->lock); | 1465 | assert_spin_locked(&delayed_refs->lock); |
| 1466 | trace_btrfs_qgroup_insert_dirty_extent(record); | ||
| 1466 | 1467 | ||
| 1467 | while (*p) { | 1468 | while (*p) { |
| 1468 | parent_node = *p; | 1469 | parent_node = *p; |
| @@ -1594,6 +1595,9 @@ static int qgroup_update_counters(struct btrfs_fs_info *fs_info, · 125 unmodified lines | |||
| 1594 | cur_old_count = btrfs_qgroup_get_old_refcnt(qg, seq); | 1595 | cur_old_count = btrfs_qgroup_get_old_refcnt(qg, seq); |
| 1595 | cur_new_count = btrfs_qgroup_get_new_refcnt(qg, seq); | 1596 | cur_new_count = btrfs_qgroup_get_new_refcnt(qg, seq); |
| 1596 | 1597 | ||
| 1598 | trace_qgroup_update_counters(qg->qgroupid, cur_old_count, | ||
| 1599 | cur_new_count); | ||
| 1600 | |||
| 1597 | /* Rfer update part */ | 1601 | /* Rfer update part */ |
| 1598 | if (cur_old_count == 0 && cur_new_count > 0) { | 1602 | if (cur_old_count == 0 && cur_new_count > 0) { |
| 1599 | qg->rfer += num_bytes; | 1603 | qg->rfer += num_bytes; |
| @@ -1683,6 +1687,9 @@ btrfs_qgroup_account_extent(struct btrfs_trans_handle *trans, · 83 unmodified lines | |||
| 1683 | goto out_free; | 1687 | goto out_free; |
| 1684 | BUG_ON(!fs_info->quota_root); | 1688 | BUG_ON(!fs_info->quota_root); |
| 1685 | 1689 | ||
| 1690 | trace_btrfs_qgroup_account_extent(bytenr, num_bytes, nr_old_roots, | ||
| 1691 | nr_new_roots); | ||
| 1692 | |||
| 1686 | qgroups = ulist_alloc(GFP_NOFS); | 1693 | qgroups = ulist_alloc(GFP_NOFS); |
| 1687 | if (!qgroups) { | 1694 | if (!qgroups) { |
| 1688 | ret = -ENOMEM; | 1695 | ret = -ENOMEM; |
| @@ -1752,6 +1759,8 @@ int btrfs_qgroup_account_extents(struct btrfs_trans_handle *trans, · 63 unmodified lines | |||
| 1752 | record = rb_entry(node, struct btrfs_qgroup_extent_record, | 1759 | record = rb_entry(node, struct btrfs_qgroup_extent_record, |
| 1753 | node); | 1760 | node); |
| 1754 | 1761 | ||
| 1762 | trace_btrfs_qgroup_account_extents(record); | ||
| 1763 | |||
| 1755 | if (!ret) { | 1764 | if (!ret) { |
| 1756 | /* | 1765 | /* |
| 1757 | * Use (u64)-1 as time_seq to do special search, which | 1766 | * Use (u64)-1 as time_seq to do special search, which |
| @@ -1842,8 +1851,10 @@ out: · 84 unmodified lines | |||
| 1842 | } | 1851 | } |
| 1843 | 1852 | ||
| 1844 | /* | 1853 | /* |
| 1845 | * copy the acounting information between qgroups. This is necessary when a | 1854 | * Copy the acounting information between qgroups. This is necessary |
| 1846 | * snapshot or a subvolume is created | 1855 | * when a snapshot or a subvolume is created. Throwing an error will |
| 1856 | * cause a transaction abort so we take extra care here to only error | ||
| 1857 | * when a readonly fs is a reasonable outcome. | ||
| 1847 | */ | 1858 | */ |
| 1848 | int btrfs_qgroup_inherit(struct btrfs_trans_handle *trans, | 1859 | int btrfs_qgroup_inherit(struct btrfs_trans_handle *trans, |
| 1849 | struct btrfs_fs_info *fs_info, u64 srcid, u64 objectid, | 1860 | struct btrfs_fs_info *fs_info, u64 srcid, u64 objectid, |
| @@ -1873,15 +1884,15 @@ int btrfs_qgroup_inherit(struct btrfs_trans_handle *trans, · 23 unmodified lines | |||
| 1873 | 2 * inherit->num_excl_copies; | 1884 | 2 * inherit->num_excl_copies; |
| 1874 | for (i = 0; i < nums; ++i) { | 1885 | for (i = 0; i < nums; ++i) { |
| 1875 | srcgroup = find_qgroup_rb(fs_info, *i_qgroups); | 1886 | srcgroup = find_qgroup_rb(fs_info, *i_qgroups); |
| 1876 | if (!srcgroup) { | ||
| 1877 | ret = -EINVAL; | ||
| 1878 | goto out; | ||
| 1879 | } | ||
| 1880 | 1887 | ||
| 1881 | if ((srcgroup->qgroupid >> 48) <= (objectid >> 48)) { | 1888 | /* |
| 1882 | ret = -EINVAL; | 1889 | * Zero out invalid groups so we can ignore |
| 1883 | goto out; | 1890 | * them later. |
| 1884 | } | 1891 | */ |
| 1892 | if (!srcgroup || | ||
| 1893 | ((srcgroup->qgroupid >> 48) <= (objectid >> 48))) | ||
| 1894 | *i_qgroups = 0ULL; | ||
| 1895 | |||
| 1885 | ++i_qgroups; | 1896 | ++i_qgroups; |
| 1886 | } | 1897 | } |
| 1887 | } | 1898 | } |
| @@ -1916,17 +1927,19 @@ int btrfs_qgroup_inherit(struct btrfs_trans_handle *trans, · 28 unmodified lines | |||
| 1916 | */ | 1927 | */ |
| 1917 | if (inherit) { | 1928 | if (inherit) { |
| 1918 | i_qgroups = (u64 *)(inherit + 1); | 1929 | i_qgroups = (u64 *)(inherit + 1); |
| 1919 | for (i = 0; i < inherit->num_qgroups; ++i) { | 1930 | for (i = 0; i < inherit->num_qgroups; ++i, ++i_qgroups) { |
| 1931 | if (*i_qgroups == 0) | ||
| 1932 | continue; | ||
| 1920 | ret = add_qgroup_relation_item(trans, quota_root, | 1933 | ret = add_qgroup_relation_item(trans, quota_root, |
| 1921 | objectid, *i_qgroups); | 1934 | objectid, *i_qgroups); |
| 1922 | if (ret) | 1935 | if (ret && ret != -EEXIST) |
| 1923 | goto out; | 1936 | goto out; |
| 1924 | ret = add_qgroup_relation_item(trans, quota_root, | 1937 | ret = add_qgroup_relation_item(trans, quota_root, |
| 1925 | *i_qgroups, objectid); | 1938 | *i_qgroups, objectid); |
| 1926 | if (ret) | 1939 | if (ret && ret != -EEXIST) |
| 1927 | goto out; | 1940 | goto out; |
| 1928 | ++i_qgroups; | ||
| 1929 | } | 1941 | } |
| 1942 | ret = 0; | ||
| 1930 | } | 1943 | } |
| 1931 | 1944 | ||
| 1932 | 1945 | ||
| @@ -1987,17 +2000,22 @@ int btrfs_qgroup_inherit(struct btrfs_trans_handle *trans, · 54 unmodified lines | |||
| 1987 | 2000 | ||
| 1988 | i_qgroups = (u64 *)(inherit + 1); | 2001 | i_qgroups = (u64 *)(inherit + 1); |
| 1989 | for (i = 0; i < inherit->num_qgroups; ++i) { | 2002 | for (i = 0; i < inherit->num_qgroups; ++i) { |
| 1990 | ret = add_relation_rb(quota_root->fs_info, objectid, | 2003 | if (*i_qgroups) { |
| 1991 | *i_qgroups); | 2004 | ret = add_relation_rb(quota_root->fs_info, objectid, |
| 1992 | if (ret) | 2005 | *i_qgroups); |
| 1993 | goto unlock; | 2006 | if (ret) |
| 2007 | goto unlock; | ||
| 2008 | } | ||
| 1994 | ++i_qgroups; | 2009 | ++i_qgroups; |
| 1995 | } | 2010 | } |
| 1996 | 2011 | ||
| 1997 | for (i = 0; i < inherit->num_ref_copies; ++i) { | 2012 | for (i = 0; i < inherit->num_ref_copies; ++i, i_qgroups += 2) { |
| 1998 | struct btrfs_qgroup *src; | 2013 | struct btrfs_qgroup *src; |
| 1999 | struct btrfs_qgroup *dst; | 2014 | struct btrfs_qgroup *dst; |
| 2000 | 2015 | ||
| 2016 | if (!i_qgroups[0] || !i_qgroups[1]) | ||
| 2017 | continue; | ||
| 2018 | |||
| 2001 | src = find_qgroup_rb(fs_info, i_qgroups[0]); | 2019 | src = find_qgroup_rb(fs_info, i_qgroups[0]); |
| 2002 | dst = find_qgroup_rb(fs_info, i_qgroups[1]); | 2020 | dst = find_qgroup_rb(fs_info, i_qgroups[1]); |
| 2003 | 2021 | ||
| @@ -2008,12 +2026,14 @@ int btrfs_qgroup_inherit(struct btrfs_trans_handle *trans, · 4 unmodified lines | |||
| 2008 | 2026 | ||
| 2009 | dst->rfer = src->rfer - level_size; | 2027 | dst->rfer = src->rfer - level_size; |
| 2010 | dst->rfer_cmpr = src->rfer_cmpr - level_size; | 2028 | dst->rfer_cmpr = src->rfer_cmpr - level_size; |
| 2011 | i_qgroups += 2; | ||
| 2012 | } | 2029 | } |
| 2013 | for (i = 0; i < inherit->num_excl_copies; ++i) { | 2030 | for (i = 0; i < inherit->num_excl_copies; ++i, i_qgroups += 2) { |
| 2014 | struct btrfs_qgroup *src; | 2031 | struct btrfs_qgroup *src; |
| 2015 | struct btrfs_qgroup *dst; | 2032 | struct btrfs_qgroup *dst; |
| 2016 | 2033 | ||
| 2034 | if (!i_qgroups[0] || !i_qgroups[1]) | ||
| 2035 | continue; | ||
| 2036 | |||
| 2017 | src = find_qgroup_rb(fs_info, i_qgroups[0]); | 2037 | src = find_qgroup_rb(fs_info, i_qgroups[0]); |
| 2018 | dst = find_qgroup_rb(fs_info, i_qgroups[1]); | 2038 | dst = find_qgroup_rb(fs_info, i_qgroups[1]); |
| 2019 | 2039 | ||
| @@ -2024,7 +2044,6 @@ int btrfs_qgroup_inherit(struct btrfs_trans_handle *trans, · 4 unmodified lines | |||
| 2024 | 2044 | ||
| 2025 | dst->excl = src->excl + level_size; | 2045 | dst->excl = src->excl + level_size; |
| 2026 | dst->excl_cmpr = src->excl_cmpr + level_size; | 2046 | dst->excl_cmpr = src->excl_cmpr + level_size; |
| 2027 | i_qgroups += 2; | ||
| 2028 | } | 2047 | } |
| 2029 | 2048 | ||
| 2030 | unlock: | 2049 | unlock: |
| @@ -1850,6 +1850,7 @@ again: · 1849 unmodified lines | |||
| 1850 | eb = read_tree_block(dest, old_bytenr, old_ptr_gen); | 1850 | eb = read_tree_block(dest, old_bytenr, old_ptr_gen); |
| 1851 | if (IS_ERR(eb)) { | 1851 | if (IS_ERR(eb)) { |
| 1852 | ret = PTR_ERR(eb); | 1852 | ret = PTR_ERR(eb); |
| 1853 | break; | ||
| 1853 | } else if (!extent_buffer_uptodate(eb)) { | 1854 | } else if (!extent_buffer_uptodate(eb)) { |
| 1854 | ret = -EIO; | 1855 | ret = -EIO; |
| 1855 | free_extent_buffer(eb); | 1856 | free_extent_buffer(eb); |
| @@ -4415,6 +4415,127 @@ static int btrfs_log_trailing_hole(struct btrfs_trans_handle *trans, · 4414 unmodified lines | |||
| 4415 | return ret; | 4415 | return ret; |
| 4416 | } | 4416 | } |
| 4417 | 4417 | ||
| 4418 | /* | ||
| 4419 | * When we are logging a new inode X, check if it doesn't have a reference that | ||
| 4420 | * matches the reference from some other inode Y created in a past transaction | ||
| 4421 | * and that was renamed in the current transaction. If we don't do this, then at | ||
| 4422 | * log replay time we can lose inode Y (and all its files if it's a directory): | ||
| 4423 | * | ||
| 4424 | * mkdir /mnt/x | ||
| 4425 | * echo "hello world" > /mnt/x/foobar | ||
| 4426 | * sync | ||
| 4427 | * mv /mnt/x /mnt/y | ||
| 4428 | * mkdir /mnt/x # or touch /mnt/x | ||
| 4429 | * xfs_io -c fsync /mnt/x | ||
| 4430 | * <power fail> | ||
| 4431 | * mount fs, trigger log replay | ||
| 4432 | * | ||
| 4433 | * After the log replay procedure, we would lose the first directory and all its | ||
| 4434 | * files (file foobar). | ||
| 4435 | * For the case where inode Y is not a directory we simply end up losing it: | ||
| 4436 | * | ||
| 4437 | * echo "123" > /mnt/foo | ||
| 4438 | * sync | ||
| 4439 | * mv /mnt/foo /mnt/bar | ||
| 4440 | * echo "abc" > /mnt/foo | ||
| 4441 | * xfs_io -c fsync /mnt/foo | ||
| 4442 | * <power fail> | ||
| 4443 | * | ||
| 4444 | * We also need this for cases where a snapshot entry is replaced by some other | ||
| 4445 | * entry (file or directory) otherwise we end up with an unreplayable log due to | ||
| 4446 | * attempts to delete the snapshot entry (entry of type BTRFS_ROOT_ITEM_KEY) as | ||
| 4447 | * if it were a regular entry: | ||
| 4448 | * | ||
| 4449 | * mkdir /mnt/x | ||
| 4450 | * btrfs subvolume snapshot /mnt /mnt/x/snap | ||
| 4451 | * btrfs subvolume delete /mnt/x/snap | ||
| 4452 | * rmdir /mnt/x | ||
| 4453 | * mkdir /mnt/x | ||
| 4454 | * fsync /mnt/x or fsync some new file inside it | ||
| 4455 | * <power fail> | ||
| 4456 | * | ||
| 4457 | * The snapshot delete, rmdir of x, mkdir of a new x and the fsync all happen in | ||
| 4458 | * the same transaction. | ||
| 4459 | */ | ||
| 4460 | static int btrfs_check_ref_name_override(struct extent_buffer *eb, | ||
| 4461 | const int slot, | ||
| 4462 | const struct btrfs_key *key, | ||
| 4463 | struct inode *inode) | ||
| 4464 | { | ||
| 4465 | int ret; | ||
| 4466 | struct btrfs_path *search_path; | ||
| 4467 | char *name = NULL; | ||
| 4468 | u32 name_len = 0; | ||
| 4469 | u32 item_size = btrfs_item_size_nr(eb, slot); | ||
| 4470 | u32 cur_offset = 0; | ||
| 4471 | unsigned long ptr = btrfs_item_ptr_offset(eb, slot); | ||
| 4472 | |||
| 4473 | search_path = btrfs_alloc_path(); | ||
| 4474 | if (!search_path) | ||
| 4475 | return -ENOMEM; | ||
| 4476 | search_path->search_commit_root = 1; | ||
| 4477 | search_path->skip_locking = 1; | ||
| 4478 | |||
| 4479 | while (cur_offset < item_size) { | ||
| 4480 | u64 parent; | ||
| 4481 | u32 this_name_len; | ||
| 4482 | u32 this_len; | ||
| 4483 | unsigned long name_ptr; | ||
| 4484 | struct btrfs_dir_item *di; | ||
| 4485 | |||
| 4486 | if (key->type == BTRFS_INODE_REF_KEY) { | ||
| 4487 | struct btrfs_inode_ref *iref; | ||
| 4488 | |||
| 4489 | iref = (struct btrfs_inode_ref *)(ptr + cur_offset); | ||
| 4490 | parent = key->offset; | ||
| 4491 | this_name_len = btrfs_inode_ref_name_len(eb, iref); | ||
| 4492 | name_ptr = (unsigned long)(iref + 1); | ||
| 4493 | this_len = sizeof(*iref) + this_name_len; | ||
| 4494 | } else { | ||
| 4495 | struct btrfs_inode_extref *extref; | ||
| 4496 | |||
| 4497 | extref = (struct btrfs_inode_extref *)(ptr + | ||
| 4498 | cur_offset); | ||
| 4499 | parent = btrfs_inode_extref_parent(eb, extref); | ||
| 4500 | this_name_len = btrfs_inode_extref_name_len(eb, extref); | ||
| 4501 | name_ptr = (unsigned long)&extref->name; | ||
| 4502 | this_len = sizeof(*extref) + this_name_len; | ||
| 4503 | } | ||
| 4504 | |||
| 4505 | if (this_name_len > name_len) { | ||
| 4506 | char *new_name; | ||
| 4507 | |||
| 4508 | new_name = krealloc(name, this_name_len, GFP_NOFS); | ||
| 4509 | if (!new_name) { | ||
| 4510 | ret = -ENOMEM; | ||
| 4511 | goto out; | ||
| 4512 | } | ||
| 4513 | name_len = this_name_len; | ||
| 4514 | name = new_name; | ||
| 4515 | } | ||
| 4516 | |||
| 4517 | read_extent_buffer(eb, name, name_ptr, this_name_len); | ||
| 4518 | di = btrfs_lookup_dir_item(NULL, BTRFS_I(inode)->root, | ||
| 4519 | search_path, parent, | ||
| 4520 | name, this_name_len, 0); | ||
| 4521 | if (di && !IS_ERR(di)) { | ||
| 4522 | ret = 1; | ||
| 4523 | goto out; | ||
| 4524 | } else if (IS_ERR(di)) { | ||
| 4525 | ret = PTR_ERR(di); | ||
| 4526 | goto out; | ||
| 4527 | } | ||
| 4528 | btrfs_release_path(search_path); | ||
| 4529 | |||
| 4530 | cur_offset += this_len; | ||
| 4531 | } | ||
| 4532 | ret = 0; | ||
| 4533 | out: | ||
| 4534 | btrfs_free_path(search_path); | ||
| 4535 | kfree(name); | ||
| 4536 | return ret; | ||
| 4537 | } | ||
| 4538 | |||
| 4418 | /* log a single inode in the tree log. | 4539 | /* log a single inode in the tree log. |
| 4419 | * At least one parent directory for this inode must exist in the tree | 4540 | * At least one parent directory for this inode must exist in the tree |
| 4420 | * or be logged already. | 4541 | * or be logged already. |
| @@ -4602,6 +4723,22 @@ again: · 181 unmodified lines | |||
| 4602 | if (min_key.type == BTRFS_INODE_ITEM_KEY) | 4723 | if (min_key.type == BTRFS_INODE_ITEM_KEY) |
| 4603 | need_log_inode_item = false; | 4724 | need_log_inode_item = false; |
| 4604 | 4725 | ||
| 4726 | if ((min_key.type == BTRFS_INODE_REF_KEY || | ||
| 4727 | min_key.type == BTRFS_INODE_EXTREF_KEY) && | ||
| 4728 | BTRFS_I(inode)->generation == trans->transid) { | ||
| 4729 | ret = btrfs_check_ref_name_override(path->nodes[0], | ||
| 4730 | path->slots[0], | ||
| 4731 | &min_key, inode); | ||
| 4732 | if (ret < 0) { | ||
| 4733 | err = ret; | ||
| 4734 | goto out_unlock; | ||
| 4735 | } else if (ret > 0) { | ||
| 4736 | err = 1; | ||
| 4737 | btrfs_set_log_full_commit(root->fs_info, trans); | ||
| 4738 | goto out_unlock; | ||
| 4739 | } | ||
| 4740 | } | ||
| 4741 | |||
| 4605 | /* Skip xattrs, we log them later with btrfs_log_all_xattrs() */ | 4742 | /* Skip xattrs, we log them later with btrfs_log_all_xattrs() */ |
| 4606 | if (min_key.type == BTRFS_XATTR_ITEM_KEY) { | 4743 | if (min_key.type == BTRFS_XATTR_ITEM_KEY) { |
| 4607 | if (ins_nr == 0) | 4744 | if (ins_nr == 0) |
| @@ -23,7 +23,7 @@ struct map_lookup; · 22 unmodified lines | |||
| 23 | struct extent_buffer; | 23 | struct extent_buffer; |
| 24 | struct btrfs_work; | 24 | struct btrfs_work; |
| 25 | struct __btrfs_workqueue; | 25 | struct __btrfs_workqueue; |
| 26 | struct btrfs_qgroup_operation; | 26 | struct btrfs_qgroup_extent_record; |
| 27 | 27 | ||
| 28 | #define show_ref_type(type) \ | 28 | #define show_ref_type(type) \ |
| 29 | __print_symbolic(type, \ | 29 | __print_symbolic(type, \ |
| @@ -1231,6 +1231,93 @@ DEFINE_EVENT(btrfs__qgroup_delayed_ref, btrfs_qgroup_free_delayed_ref, · 1201 unmodified lines | |||
| 1231 | 1231 | ||
| 1232 | TP_ARGS(ref_root, reserved) | 1232 | TP_ARGS(ref_root, reserved) |
| 1233 | ); | 1233 | ); |
| 1234 | |||
| 1235 | DECLARE_EVENT_CLASS(btrfs_qgroup_extent, | ||
| 1236 | TP_PROTO(struct btrfs_qgroup_extent_record *rec), | ||
| 1237 | |||
| 1238 | TP_ARGS(rec), | ||
| 1239 | |||
| 1240 | TP_STRUCT__entry( | ||
| 1241 | __field( u64, bytenr ) | ||
| 1242 | __field( u64, num_bytes ) | ||
| 1243 | ), | ||
| 1244 | |||
| 1245 | TP_fast_assign( | ||
| 1246 | __entry->bytenr = rec->bytenr, | ||
| 1247 | __entry->num_bytes = rec->num_bytes; | ||
| 1248 | ), | ||
| 1249 | |||
| 1250 | TP_printk("bytenr = %llu, num_bytes = %llu", | ||
| 1251 | (unsigned long long)__entry->bytenr, | ||
| 1252 | (unsigned long long)__entry->num_bytes) | ||
| 1253 | ); | ||
| 1254 | |||
| 1255 | DEFINE_EVENT(btrfs_qgroup_extent, btrfs_qgroup_account_extents, | ||
| 1256 | |||
| 1257 | TP_PROTO(struct btrfs_qgroup_extent_record *rec), | ||
| 1258 | |||
| 1259 | TP_ARGS(rec) | ||
| 1260 | ); | ||
| 1261 | |||
| 1262 | DEFINE_EVENT(btrfs_qgroup_extent, btrfs_qgroup_insert_dirty_extent, | ||
| 1263 | |||
| 1264 | TP_PROTO(struct btrfs_qgroup_extent_record *rec), | ||
| 1265 | |||
| 1266 | TP_ARGS(rec) | ||
| 1267 | ); | ||
| 1268 | |||
| 1269 | TRACE_EVENT(btrfs_qgroup_account_extent, | ||
| 1270 | |||
| 1271 | TP_PROTO(u64 bytenr, u64 num_bytes, u64 nr_old_roots, u64 nr_new_roots), | ||
| 1272 | |||
| 1273 | TP_ARGS(bytenr, num_bytes, nr_old_roots, nr_new_roots), | ||
| 1274 | |||
| 1275 | TP_STRUCT__entry( | ||
| 1276 | __field( u64, bytenr ) | ||
| 1277 | __field( u64, num_bytes ) | ||
| 1278 | __field( u64, nr_old_roots ) | ||
| 1279 | __field( u64, nr_new_roots ) | ||
| 1280 | ), | ||
| 1281 | |||
| 1282 | TP_fast_assign( | ||
| 1283 | __entry->bytenr = bytenr; | ||
| 1284 | __entry->num_bytes = num_bytes; | ||
| 1285 | __entry->nr_old_roots = nr_old_roots; | ||
| 1286 | __entry->nr_new_roots = nr_new_roots; | ||
| 1287 | ), | ||
| 1288 | |||
| 1289 | TP_printk("bytenr = %llu, num_bytes = %llu, nr_old_roots = %llu, " | ||
| 1290 | "nr_new_roots = %llu", | ||
| 1291 | __entry->bytenr, | ||
| 1292 | __entry->num_bytes, | ||
| 1293 | __entry->nr_old_roots, | ||
| 1294 | __entry->nr_new_roots) | ||
| 1295 | ); | ||
| 1296 | |||
| 1297 | TRACE_EVENT(qgroup_update_counters, | ||
| 1298 | |||
| 1299 | TP_PROTO(u64 qgid, u64 cur_old_count, u64 cur_new_count), | ||
| 1300 | |||
| 1301 | TP_ARGS(qgid, cur_old_count, cur_new_count), | ||
| 1302 | |||
| 1303 | TP_STRUCT__entry( | ||
| 1304 | __field( u64, qgid ) | ||
| 1305 | __field( u64, cur_old_count ) | ||
| 1306 | __field( u64, cur_new_count ) | ||
| 1307 | ), | ||
| 1308 | |||
| 1309 | TP_fast_assign( | ||
| 1310 | __entry->qgid = qgid; | ||
| 1311 | __entry->cur_old_count = cur_old_count; | ||
| 1312 | __entry->cur_new_count = cur_new_count; | ||
| 1313 | ), | ||
| 1314 | |||
| 1315 | TP_printk("qgid = %llu, cur_old_count = %llu, cur_new_count = %llu", | ||
| 1316 | __entry->qgid, | ||
| 1317 | __entry->cur_old_count, | ||
| 1318 | __entry->cur_new_count) | ||
| 1319 | ); | ||
| 1320 | |||
| 1234 | #endif /* _TRACE_BTRFS_H */ | 1321 | #endif /* _TRACE_BTRFS_H */ |
| 1235 | 1322 | ||
| 1236 | /* This part must be outside protection */ | 1323 | /* This part must be outside protection */ |