diff options
Diffstat (limited to 'fs/btrfs/extent-tree.c')
-rw-r--r-- | fs/btrfs/extent-tree.c | 206 |
1 files changed, 130 insertions, 76 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index aff579df5f47..343eb10230a1 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include "free-space-cache.h" | 35 | #include "free-space-cache.h" |
36 | #include "math.h" | 36 | #include "math.h" |
37 | #include "sysfs.h" | 37 | #include "sysfs.h" |
38 | #include "qgroup.h" | ||
38 | 39 | ||
39 | #undef SCRAMBLE_DELAYED_REFS | 40 | #undef SCRAMBLE_DELAYED_REFS |
40 | 41 | ||
@@ -80,7 +81,8 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans, | |||
80 | u64 bytenr, u64 num_bytes, u64 parent, | 81 | u64 bytenr, u64 num_bytes, u64 parent, |
81 | u64 root_objectid, u64 owner_objectid, | 82 | u64 root_objectid, u64 owner_objectid, |
82 | u64 owner_offset, int refs_to_drop, | 83 | u64 owner_offset, int refs_to_drop, |
83 | struct btrfs_delayed_extent_op *extra_op); | 84 | struct btrfs_delayed_extent_op *extra_op, |
85 | int no_quota); | ||
84 | static void __run_delayed_extent_op(struct btrfs_delayed_extent_op *extent_op, | 86 | static void __run_delayed_extent_op(struct btrfs_delayed_extent_op *extent_op, |
85 | struct extent_buffer *leaf, | 87 | struct extent_buffer *leaf, |
86 | struct btrfs_extent_item *ei); | 88 | struct btrfs_extent_item *ei); |
@@ -93,7 +95,8 @@ static int alloc_reserved_tree_block(struct btrfs_trans_handle *trans, | |||
93 | struct btrfs_root *root, | 95 | struct btrfs_root *root, |
94 | u64 parent, u64 root_objectid, | 96 | u64 parent, u64 root_objectid, |
95 | u64 flags, struct btrfs_disk_key *key, | 97 | u64 flags, struct btrfs_disk_key *key, |
96 | int level, struct btrfs_key *ins); | 98 | int level, struct btrfs_key *ins, |
99 | int no_quota); | ||
97 | static int do_chunk_alloc(struct btrfs_trans_handle *trans, | 100 | static int do_chunk_alloc(struct btrfs_trans_handle *trans, |
98 | struct btrfs_root *extent_root, u64 flags, | 101 | struct btrfs_root *extent_root, u64 flags, |
99 | int force); | 102 | int force); |
@@ -1270,7 +1273,7 @@ fail: | |||
1270 | static noinline int remove_extent_data_ref(struct btrfs_trans_handle *trans, | 1273 | static noinline int remove_extent_data_ref(struct btrfs_trans_handle *trans, |
1271 | struct btrfs_root *root, | 1274 | struct btrfs_root *root, |
1272 | struct btrfs_path *path, | 1275 | struct btrfs_path *path, |
1273 | int refs_to_drop) | 1276 | int refs_to_drop, int *last_ref) |
1274 | { | 1277 | { |
1275 | struct btrfs_key key; | 1278 | struct btrfs_key key; |
1276 | struct btrfs_extent_data_ref *ref1 = NULL; | 1279 | struct btrfs_extent_data_ref *ref1 = NULL; |
@@ -1306,6 +1309,7 @@ static noinline int remove_extent_data_ref(struct btrfs_trans_handle *trans, | |||
1306 | 1309 | ||
1307 | if (num_refs == 0) { | 1310 | if (num_refs == 0) { |
1308 | ret = btrfs_del_item(trans, root, path); | 1311 | ret = btrfs_del_item(trans, root, path); |
1312 | *last_ref = 1; | ||
1309 | } else { | 1313 | } else { |
1310 | if (key.type == BTRFS_EXTENT_DATA_REF_KEY) | 1314 | if (key.type == BTRFS_EXTENT_DATA_REF_KEY) |
1311 | btrfs_set_extent_data_ref_count(leaf, ref1, num_refs); | 1315 | btrfs_set_extent_data_ref_count(leaf, ref1, num_refs); |
@@ -1763,7 +1767,8 @@ void update_inline_extent_backref(struct btrfs_root *root, | |||
1763 | struct btrfs_path *path, | 1767 | struct btrfs_path *path, |
1764 | struct btrfs_extent_inline_ref *iref, | 1768 | struct btrfs_extent_inline_ref *iref, |
1765 | int refs_to_mod, | 1769 | int refs_to_mod, |
1766 | struct btrfs_delayed_extent_op *extent_op) | 1770 | struct btrfs_delayed_extent_op *extent_op, |
1771 | int *last_ref) | ||
1767 | { | 1772 | { |
1768 | struct extent_buffer *leaf; | 1773 | struct extent_buffer *leaf; |
1769 | struct btrfs_extent_item *ei; | 1774 | struct btrfs_extent_item *ei; |
@@ -1807,6 +1812,7 @@ void update_inline_extent_backref(struct btrfs_root *root, | |||
1807 | else | 1812 | else |
1808 | btrfs_set_shared_data_ref_count(leaf, sref, refs); | 1813 | btrfs_set_shared_data_ref_count(leaf, sref, refs); |
1809 | } else { | 1814 | } else { |
1815 | *last_ref = 1; | ||
1810 | size = btrfs_extent_inline_ref_size(type); | 1816 | size = btrfs_extent_inline_ref_size(type); |
1811 | item_size = btrfs_item_size_nr(leaf, path->slots[0]); | 1817 | item_size = btrfs_item_size_nr(leaf, path->slots[0]); |
1812 | ptr = (unsigned long)iref; | 1818 | ptr = (unsigned long)iref; |
@@ -1838,7 +1844,7 @@ int insert_inline_extent_backref(struct btrfs_trans_handle *trans, | |||
1838 | if (ret == 0) { | 1844 | if (ret == 0) { |
1839 | BUG_ON(owner < BTRFS_FIRST_FREE_OBJECTID); | 1845 | BUG_ON(owner < BTRFS_FIRST_FREE_OBJECTID); |
1840 | update_inline_extent_backref(root, path, iref, | 1846 | update_inline_extent_backref(root, path, iref, |
1841 | refs_to_add, extent_op); | 1847 | refs_to_add, extent_op, NULL); |
1842 | } else if (ret == -ENOENT) { | 1848 | } else if (ret == -ENOENT) { |
1843 | setup_inline_extent_backref(root, path, iref, parent, | 1849 | setup_inline_extent_backref(root, path, iref, parent, |
1844 | root_objectid, owner, offset, | 1850 | root_objectid, owner, offset, |
@@ -1871,17 +1877,19 @@ static int remove_extent_backref(struct btrfs_trans_handle *trans, | |||
1871 | struct btrfs_root *root, | 1877 | struct btrfs_root *root, |
1872 | struct btrfs_path *path, | 1878 | struct btrfs_path *path, |
1873 | struct btrfs_extent_inline_ref *iref, | 1879 | struct btrfs_extent_inline_ref *iref, |
1874 | int refs_to_drop, int is_data) | 1880 | int refs_to_drop, int is_data, int *last_ref) |
1875 | { | 1881 | { |
1876 | int ret = 0; | 1882 | int ret = 0; |
1877 | 1883 | ||
1878 | BUG_ON(!is_data && refs_to_drop != 1); | 1884 | BUG_ON(!is_data && refs_to_drop != 1); |
1879 | if (iref) { | 1885 | if (iref) { |
1880 | update_inline_extent_backref(root, path, iref, | 1886 | update_inline_extent_backref(root, path, iref, |
1881 | -refs_to_drop, NULL); | 1887 | -refs_to_drop, NULL, last_ref); |
1882 | } else if (is_data) { | 1888 | } else if (is_data) { |
1883 | ret = remove_extent_data_ref(trans, root, path, refs_to_drop); | 1889 | ret = remove_extent_data_ref(trans, root, path, refs_to_drop, |
1890 | last_ref); | ||
1884 | } else { | 1891 | } else { |
1892 | *last_ref = 1; | ||
1885 | ret = btrfs_del_item(trans, root, path); | 1893 | ret = btrfs_del_item(trans, root, path); |
1886 | } | 1894 | } |
1887 | return ret; | 1895 | return ret; |
@@ -1945,7 +1953,8 @@ static int btrfs_discard_extent(struct btrfs_root *root, u64 bytenr, | |||
1945 | int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, | 1953 | int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, |
1946 | struct btrfs_root *root, | 1954 | struct btrfs_root *root, |
1947 | u64 bytenr, u64 num_bytes, u64 parent, | 1955 | u64 bytenr, u64 num_bytes, u64 parent, |
1948 | u64 root_objectid, u64 owner, u64 offset, int for_cow) | 1956 | u64 root_objectid, u64 owner, u64 offset, |
1957 | int no_quota) | ||
1949 | { | 1958 | { |
1950 | int ret; | 1959 | int ret; |
1951 | struct btrfs_fs_info *fs_info = root->fs_info; | 1960 | struct btrfs_fs_info *fs_info = root->fs_info; |
@@ -1957,12 +1966,12 @@ int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, | |||
1957 | ret = btrfs_add_delayed_tree_ref(fs_info, trans, bytenr, | 1966 | ret = btrfs_add_delayed_tree_ref(fs_info, trans, bytenr, |
1958 | num_bytes, | 1967 | num_bytes, |
1959 | parent, root_objectid, (int)owner, | 1968 | parent, root_objectid, (int)owner, |
1960 | BTRFS_ADD_DELAYED_REF, NULL, for_cow); | 1969 | BTRFS_ADD_DELAYED_REF, NULL, no_quota); |
1961 | } else { | 1970 | } else { |
1962 | ret = btrfs_add_delayed_data_ref(fs_info, trans, bytenr, | 1971 | ret = btrfs_add_delayed_data_ref(fs_info, trans, bytenr, |
1963 | num_bytes, | 1972 | num_bytes, |
1964 | parent, root_objectid, owner, offset, | 1973 | parent, root_objectid, owner, offset, |
1965 | BTRFS_ADD_DELAYED_REF, NULL, for_cow); | 1974 | BTRFS_ADD_DELAYED_REF, NULL, no_quota); |
1966 | } | 1975 | } |
1967 | return ret; | 1976 | return ret; |
1968 | } | 1977 | } |
@@ -1972,31 +1981,64 @@ static int __btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, | |||
1972 | u64 bytenr, u64 num_bytes, | 1981 | u64 bytenr, u64 num_bytes, |
1973 | u64 parent, u64 root_objectid, | 1982 | u64 parent, u64 root_objectid, |
1974 | u64 owner, u64 offset, int refs_to_add, | 1983 | u64 owner, u64 offset, int refs_to_add, |
1984 | int no_quota, | ||
1975 | struct btrfs_delayed_extent_op *extent_op) | 1985 | struct btrfs_delayed_extent_op *extent_op) |
1976 | { | 1986 | { |
1987 | struct btrfs_fs_info *fs_info = root->fs_info; | ||
1977 | struct btrfs_path *path; | 1988 | struct btrfs_path *path; |
1978 | struct extent_buffer *leaf; | 1989 | struct extent_buffer *leaf; |
1979 | struct btrfs_extent_item *item; | 1990 | struct btrfs_extent_item *item; |
1991 | struct btrfs_key key; | ||
1980 | u64 refs; | 1992 | u64 refs; |
1981 | int ret; | 1993 | int ret; |
1994 | enum btrfs_qgroup_operation_type type = BTRFS_QGROUP_OPER_ADD_EXCL; | ||
1982 | 1995 | ||
1983 | path = btrfs_alloc_path(); | 1996 | path = btrfs_alloc_path(); |
1984 | if (!path) | 1997 | if (!path) |
1985 | return -ENOMEM; | 1998 | return -ENOMEM; |
1986 | 1999 | ||
2000 | if (!is_fstree(root_objectid) || !root->fs_info->quota_enabled) | ||
2001 | no_quota = 1; | ||
2002 | |||
1987 | path->reada = 1; | 2003 | path->reada = 1; |
1988 | path->leave_spinning = 1; | 2004 | path->leave_spinning = 1; |
1989 | /* this will setup the path even if it fails to insert the back ref */ | 2005 | /* this will setup the path even if it fails to insert the back ref */ |
1990 | ret = insert_inline_extent_backref(trans, root->fs_info->extent_root, | 2006 | ret = insert_inline_extent_backref(trans, fs_info->extent_root, path, |
1991 | path, bytenr, num_bytes, parent, | 2007 | bytenr, num_bytes, parent, |
1992 | root_objectid, owner, offset, | 2008 | root_objectid, owner, offset, |
1993 | refs_to_add, extent_op); | 2009 | refs_to_add, extent_op); |
1994 | if (ret != -EAGAIN) | 2010 | if ((ret < 0 && ret != -EAGAIN) || (!ret && no_quota)) |
1995 | goto out; | 2011 | goto out; |
2012 | /* | ||
2013 | * Ok we were able to insert an inline extent and it appears to be a new | ||
2014 | * reference, deal with the qgroup accounting. | ||
2015 | */ | ||
2016 | if (!ret && !no_quota) { | ||
2017 | ASSERT(root->fs_info->quota_enabled); | ||
2018 | leaf = path->nodes[0]; | ||
2019 | btrfs_item_key_to_cpu(leaf, &key, path->slots[0]); | ||
2020 | item = btrfs_item_ptr(leaf, path->slots[0], | ||
2021 | struct btrfs_extent_item); | ||
2022 | if (btrfs_extent_refs(leaf, item) > (u64)refs_to_add) | ||
2023 | type = BTRFS_QGROUP_OPER_ADD_SHARED; | ||
2024 | btrfs_release_path(path); | ||
1996 | 2025 | ||
2026 | ret = btrfs_qgroup_record_ref(trans, fs_info, root_objectid, | ||
2027 | bytenr, num_bytes, type, 0); | ||
2028 | goto out; | ||
2029 | } | ||
2030 | |||
2031 | /* | ||
2032 | * Ok we had -EAGAIN which means we didn't have space to insert and | ||
2033 | * inline extent ref, so just update the reference count and add a | ||
2034 | * normal backref. | ||
2035 | */ | ||
1997 | leaf = path->nodes[0]; | 2036 | leaf = path->nodes[0]; |
2037 | btrfs_item_key_to_cpu(leaf, &key, path->slots[0]); | ||
1998 | item = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_extent_item); | 2038 | item = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_extent_item); |
1999 | refs = btrfs_extent_refs(leaf, item); | 2039 | refs = btrfs_extent_refs(leaf, item); |
2040 | if (refs) | ||
2041 | type = BTRFS_QGROUP_OPER_ADD_SHARED; | ||
2000 | btrfs_set_extent_refs(leaf, item, refs + refs_to_add); | 2042 | btrfs_set_extent_refs(leaf, item, refs + refs_to_add); |
2001 | if (extent_op) | 2043 | if (extent_op) |
2002 | __run_delayed_extent_op(extent_op, leaf, item); | 2044 | __run_delayed_extent_op(extent_op, leaf, item); |
@@ -2004,9 +2046,15 @@ static int __btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, | |||
2004 | btrfs_mark_buffer_dirty(leaf); | 2046 | btrfs_mark_buffer_dirty(leaf); |
2005 | btrfs_release_path(path); | 2047 | btrfs_release_path(path); |
2006 | 2048 | ||
2049 | if (!no_quota) { | ||
2050 | ret = btrfs_qgroup_record_ref(trans, fs_info, root_objectid, | ||
2051 | bytenr, num_bytes, type, 0); | ||
2052 | if (ret) | ||
2053 | goto out; | ||
2054 | } | ||
2055 | |||
2007 | path->reada = 1; | 2056 | path->reada = 1; |
2008 | path->leave_spinning = 1; | 2057 | path->leave_spinning = 1; |
2009 | |||
2010 | /* now insert the actual backref */ | 2058 | /* now insert the actual backref */ |
2011 | ret = insert_extent_backref(trans, root->fs_info->extent_root, | 2059 | ret = insert_extent_backref(trans, root->fs_info->extent_root, |
2012 | path, bytenr, parent, root_objectid, | 2060 | path, bytenr, parent, root_objectid, |
@@ -2040,8 +2088,7 @@ static int run_delayed_data_ref(struct btrfs_trans_handle *trans, | |||
2040 | 2088 | ||
2041 | if (node->type == BTRFS_SHARED_DATA_REF_KEY) | 2089 | if (node->type == BTRFS_SHARED_DATA_REF_KEY) |
2042 | parent = ref->parent; | 2090 | parent = ref->parent; |
2043 | else | 2091 | ref_root = ref->root; |
2044 | ref_root = ref->root; | ||
2045 | 2092 | ||
2046 | if (node->action == BTRFS_ADD_DELAYED_REF && insert_reserved) { | 2093 | if (node->action == BTRFS_ADD_DELAYED_REF && insert_reserved) { |
2047 | if (extent_op) | 2094 | if (extent_op) |
@@ -2055,13 +2102,13 @@ static int run_delayed_data_ref(struct btrfs_trans_handle *trans, | |||
2055 | node->num_bytes, parent, | 2102 | node->num_bytes, parent, |
2056 | ref_root, ref->objectid, | 2103 | ref_root, ref->objectid, |
2057 | ref->offset, node->ref_mod, | 2104 | ref->offset, node->ref_mod, |
2058 | extent_op); | 2105 | node->no_quota, extent_op); |
2059 | } else if (node->action == BTRFS_DROP_DELAYED_REF) { | 2106 | } else if (node->action == BTRFS_DROP_DELAYED_REF) { |
2060 | ret = __btrfs_free_extent(trans, root, node->bytenr, | 2107 | ret = __btrfs_free_extent(trans, root, node->bytenr, |
2061 | node->num_bytes, parent, | 2108 | node->num_bytes, parent, |
2062 | ref_root, ref->objectid, | 2109 | ref_root, ref->objectid, |
2063 | ref->offset, node->ref_mod, | 2110 | ref->offset, node->ref_mod, |
2064 | extent_op); | 2111 | extent_op, node->no_quota); |
2065 | } else { | 2112 | } else { |
2066 | BUG(); | 2113 | BUG(); |
2067 | } | 2114 | } |
@@ -2198,8 +2245,7 @@ static int run_delayed_tree_ref(struct btrfs_trans_handle *trans, | |||
2198 | 2245 | ||
2199 | if (node->type == BTRFS_SHARED_BLOCK_REF_KEY) | 2246 | if (node->type == BTRFS_SHARED_BLOCK_REF_KEY) |
2200 | parent = ref->parent; | 2247 | parent = ref->parent; |
2201 | else | 2248 | ref_root = ref->root; |
2202 | ref_root = ref->root; | ||
2203 | 2249 | ||
2204 | ins.objectid = node->bytenr; | 2250 | ins.objectid = node->bytenr; |
2205 | if (skinny_metadata) { | 2251 | if (skinny_metadata) { |
@@ -2217,15 +2263,18 @@ static int run_delayed_tree_ref(struct btrfs_trans_handle *trans, | |||
2217 | parent, ref_root, | 2263 | parent, ref_root, |
2218 | extent_op->flags_to_set, | 2264 | extent_op->flags_to_set, |
2219 | &extent_op->key, | 2265 | &extent_op->key, |
2220 | ref->level, &ins); | 2266 | ref->level, &ins, |
2267 | node->no_quota); | ||
2221 | } else if (node->action == BTRFS_ADD_DELAYED_REF) { | 2268 | } else if (node->action == BTRFS_ADD_DELAYED_REF) { |
2222 | ret = __btrfs_inc_extent_ref(trans, root, node->bytenr, | 2269 | ret = __btrfs_inc_extent_ref(trans, root, node->bytenr, |
2223 | node->num_bytes, parent, ref_root, | 2270 | node->num_bytes, parent, ref_root, |
2224 | ref->level, 0, 1, extent_op); | 2271 | ref->level, 0, 1, node->no_quota, |
2272 | extent_op); | ||
2225 | } else if (node->action == BTRFS_DROP_DELAYED_REF) { | 2273 | } else if (node->action == BTRFS_DROP_DELAYED_REF) { |
2226 | ret = __btrfs_free_extent(trans, root, node->bytenr, | 2274 | ret = __btrfs_free_extent(trans, root, node->bytenr, |
2227 | node->num_bytes, parent, ref_root, | 2275 | node->num_bytes, parent, ref_root, |
2228 | ref->level, 0, 1, extent_op); | 2276 | ref->level, 0, 1, extent_op, |
2277 | node->no_quota); | ||
2229 | } else { | 2278 | } else { |
2230 | BUG(); | 2279 | BUG(); |
2231 | } | 2280 | } |
@@ -2573,42 +2622,6 @@ static u64 find_middle(struct rb_root *root) | |||
2573 | } | 2622 | } |
2574 | #endif | 2623 | #endif |
2575 | 2624 | ||
2576 | int btrfs_delayed_refs_qgroup_accounting(struct btrfs_trans_handle *trans, | ||
2577 | struct btrfs_fs_info *fs_info) | ||
2578 | { | ||
2579 | struct qgroup_update *qgroup_update; | ||
2580 | int ret = 0; | ||
2581 | |||
2582 | if (list_empty(&trans->qgroup_ref_list) != | ||
2583 | !trans->delayed_ref_elem.seq) { | ||
2584 | /* list without seq or seq without list */ | ||
2585 | btrfs_err(fs_info, | ||
2586 | "qgroup accounting update error, list is%s empty, seq is %#x.%x", | ||
2587 | list_empty(&trans->qgroup_ref_list) ? "" : " not", | ||
2588 | (u32)(trans->delayed_ref_elem.seq >> 32), | ||
2589 | (u32)trans->delayed_ref_elem.seq); | ||
2590 | BUG(); | ||
2591 | } | ||
2592 | |||
2593 | if (!trans->delayed_ref_elem.seq) | ||
2594 | return 0; | ||
2595 | |||
2596 | while (!list_empty(&trans->qgroup_ref_list)) { | ||
2597 | qgroup_update = list_first_entry(&trans->qgroup_ref_list, | ||
2598 | struct qgroup_update, list); | ||
2599 | list_del(&qgroup_update->list); | ||
2600 | if (!ret) | ||
2601 | ret = btrfs_qgroup_account_ref( | ||
2602 | trans, fs_info, qgroup_update->node, | ||
2603 | qgroup_update->extent_op); | ||
2604 | kfree(qgroup_update); | ||
2605 | } | ||
2606 | |||
2607 | btrfs_put_tree_mod_seq(fs_info, &trans->delayed_ref_elem); | ||
2608 | |||
2609 | return ret; | ||
2610 | } | ||
2611 | |||
2612 | static inline u64 heads_to_leaves(struct btrfs_root *root, u64 heads) | 2625 | static inline u64 heads_to_leaves(struct btrfs_root *root, u64 heads) |
2613 | { | 2626 | { |
2614 | u64 num_bytes; | 2627 | u64 num_bytes; |
@@ -2697,8 +2710,6 @@ int btrfs_run_delayed_refs(struct btrfs_trans_handle *trans, | |||
2697 | if (root == root->fs_info->extent_root) | 2710 | if (root == root->fs_info->extent_root) |
2698 | root = root->fs_info->tree_root; | 2711 | root = root->fs_info->tree_root; |
2699 | 2712 | ||
2700 | btrfs_delayed_refs_qgroup_accounting(trans, root->fs_info); | ||
2701 | |||
2702 | delayed_refs = &trans->transaction->delayed_refs; | 2713 | delayed_refs = &trans->transaction->delayed_refs; |
2703 | if (count == 0) { | 2714 | if (count == 0) { |
2704 | count = atomic_read(&delayed_refs->num_entries) * 2; | 2715 | count = atomic_read(&delayed_refs->num_entries) * 2; |
@@ -2757,6 +2768,9 @@ again: | |||
2757 | goto again; | 2768 | goto again; |
2758 | } | 2769 | } |
2759 | out: | 2770 | out: |
2771 | ret = btrfs_delayed_qgroup_accounting(trans, root->fs_info); | ||
2772 | if (ret) | ||
2773 | return ret; | ||
2760 | assert_qgroups_uptodate(trans); | 2774 | assert_qgroups_uptodate(trans); |
2761 | return 0; | 2775 | return 0; |
2762 | } | 2776 | } |
@@ -2963,7 +2977,7 @@ out: | |||
2963 | static int __btrfs_mod_ref(struct btrfs_trans_handle *trans, | 2977 | static int __btrfs_mod_ref(struct btrfs_trans_handle *trans, |
2964 | struct btrfs_root *root, | 2978 | struct btrfs_root *root, |
2965 | struct extent_buffer *buf, | 2979 | struct extent_buffer *buf, |
2966 | int full_backref, int inc, int for_cow) | 2980 | int full_backref, int inc, int no_quota) |
2967 | { | 2981 | { |
2968 | u64 bytenr; | 2982 | u64 bytenr; |
2969 | u64 num_bytes; | 2983 | u64 num_bytes; |
@@ -3013,7 +3027,7 @@ static int __btrfs_mod_ref(struct btrfs_trans_handle *trans, | |||
3013 | key.offset -= btrfs_file_extent_offset(buf, fi); | 3027 | key.offset -= btrfs_file_extent_offset(buf, fi); |
3014 | ret = process_func(trans, root, bytenr, num_bytes, | 3028 | ret = process_func(trans, root, bytenr, num_bytes, |
3015 | parent, ref_root, key.objectid, | 3029 | parent, ref_root, key.objectid, |
3016 | key.offset, for_cow); | 3030 | key.offset, no_quota); |
3017 | if (ret) | 3031 | if (ret) |
3018 | goto fail; | 3032 | goto fail; |
3019 | } else { | 3033 | } else { |
@@ -3021,7 +3035,7 @@ static int __btrfs_mod_ref(struct btrfs_trans_handle *trans, | |||
3021 | num_bytes = btrfs_level_size(root, level - 1); | 3035 | num_bytes = btrfs_level_size(root, level - 1); |
3022 | ret = process_func(trans, root, bytenr, num_bytes, | 3036 | ret = process_func(trans, root, bytenr, num_bytes, |
3023 | parent, ref_root, level - 1, 0, | 3037 | parent, ref_root, level - 1, 0, |
3024 | for_cow); | 3038 | no_quota); |
3025 | if (ret) | 3039 | if (ret) |
3026 | goto fail; | 3040 | goto fail; |
3027 | } | 3041 | } |
@@ -3032,15 +3046,15 @@ fail: | |||
3032 | } | 3046 | } |
3033 | 3047 | ||
3034 | int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, | 3048 | int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, |
3035 | struct extent_buffer *buf, int full_backref, int for_cow) | 3049 | struct extent_buffer *buf, int full_backref, int no_quota) |
3036 | { | 3050 | { |
3037 | return __btrfs_mod_ref(trans, root, buf, full_backref, 1, for_cow); | 3051 | return __btrfs_mod_ref(trans, root, buf, full_backref, 1, no_quota); |
3038 | } | 3052 | } |
3039 | 3053 | ||
3040 | int btrfs_dec_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, | 3054 | int btrfs_dec_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, |
3041 | struct extent_buffer *buf, int full_backref, int for_cow) | 3055 | struct extent_buffer *buf, int full_backref, int no_quota) |
3042 | { | 3056 | { |
3043 | return __btrfs_mod_ref(trans, root, buf, full_backref, 0, for_cow); | 3057 | return __btrfs_mod_ref(trans, root, buf, full_backref, 0, no_quota); |
3044 | } | 3058 | } |
3045 | 3059 | ||
3046 | static int write_one_cache_group(struct btrfs_trans_handle *trans, | 3060 | static int write_one_cache_group(struct btrfs_trans_handle *trans, |
@@ -5723,7 +5737,8 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans, | |||
5723 | u64 bytenr, u64 num_bytes, u64 parent, | 5737 | u64 bytenr, u64 num_bytes, u64 parent, |
5724 | u64 root_objectid, u64 owner_objectid, | 5738 | u64 root_objectid, u64 owner_objectid, |
5725 | u64 owner_offset, int refs_to_drop, | 5739 | u64 owner_offset, int refs_to_drop, |
5726 | struct btrfs_delayed_extent_op *extent_op) | 5740 | struct btrfs_delayed_extent_op *extent_op, |
5741 | int no_quota) | ||
5727 | { | 5742 | { |
5728 | struct btrfs_key key; | 5743 | struct btrfs_key key; |
5729 | struct btrfs_path *path; | 5744 | struct btrfs_path *path; |
@@ -5739,9 +5754,14 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans, | |||
5739 | int num_to_del = 1; | 5754 | int num_to_del = 1; |
5740 | u32 item_size; | 5755 | u32 item_size; |
5741 | u64 refs; | 5756 | u64 refs; |
5757 | int last_ref = 0; | ||
5758 | enum btrfs_qgroup_operation_type type = BTRFS_QGROUP_OPER_SUB_EXCL; | ||
5742 | bool skinny_metadata = btrfs_fs_incompat(root->fs_info, | 5759 | bool skinny_metadata = btrfs_fs_incompat(root->fs_info, |
5743 | SKINNY_METADATA); | 5760 | SKINNY_METADATA); |
5744 | 5761 | ||
5762 | if (!info->quota_enabled || !is_fstree(root_objectid)) | ||
5763 | no_quota = 1; | ||
5764 | |||
5745 | path = btrfs_alloc_path(); | 5765 | path = btrfs_alloc_path(); |
5746 | if (!path) | 5766 | if (!path) |
5747 | return -ENOMEM; | 5767 | return -ENOMEM; |
@@ -5789,7 +5809,7 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans, | |||
5789 | BUG_ON(iref); | 5809 | BUG_ON(iref); |
5790 | ret = remove_extent_backref(trans, extent_root, path, | 5810 | ret = remove_extent_backref(trans, extent_root, path, |
5791 | NULL, refs_to_drop, | 5811 | NULL, refs_to_drop, |
5792 | is_data); | 5812 | is_data, &last_ref); |
5793 | if (ret) { | 5813 | if (ret) { |
5794 | btrfs_abort_transaction(trans, extent_root, ret); | 5814 | btrfs_abort_transaction(trans, extent_root, ret); |
5795 | goto out; | 5815 | goto out; |
@@ -5916,6 +5936,7 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans, | |||
5916 | refs -= refs_to_drop; | 5936 | refs -= refs_to_drop; |
5917 | 5937 | ||
5918 | if (refs > 0) { | 5938 | if (refs > 0) { |
5939 | type = BTRFS_QGROUP_OPER_SUB_SHARED; | ||
5919 | if (extent_op) | 5940 | if (extent_op) |
5920 | __run_delayed_extent_op(extent_op, leaf, ei); | 5941 | __run_delayed_extent_op(extent_op, leaf, ei); |
5921 | /* | 5942 | /* |
@@ -5931,7 +5952,7 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans, | |||
5931 | if (found_extent) { | 5952 | if (found_extent) { |
5932 | ret = remove_extent_backref(trans, extent_root, path, | 5953 | ret = remove_extent_backref(trans, extent_root, path, |
5933 | iref, refs_to_drop, | 5954 | iref, refs_to_drop, |
5934 | is_data); | 5955 | is_data, &last_ref); |
5935 | if (ret) { | 5956 | if (ret) { |
5936 | btrfs_abort_transaction(trans, extent_root, ret); | 5957 | btrfs_abort_transaction(trans, extent_root, ret); |
5937 | goto out; | 5958 | goto out; |
@@ -5952,6 +5973,7 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans, | |||
5952 | } | 5973 | } |
5953 | } | 5974 | } |
5954 | 5975 | ||
5976 | last_ref = 1; | ||
5955 | ret = btrfs_del_items(trans, extent_root, path, path->slots[0], | 5977 | ret = btrfs_del_items(trans, extent_root, path, path->slots[0], |
5956 | num_to_del); | 5978 | num_to_del); |
5957 | if (ret) { | 5979 | if (ret) { |
@@ -5974,6 +5996,20 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans, | |||
5974 | goto out; | 5996 | goto out; |
5975 | } | 5997 | } |
5976 | } | 5998 | } |
5999 | btrfs_release_path(path); | ||
6000 | |||
6001 | /* Deal with the quota accounting */ | ||
6002 | if (!ret && last_ref && !no_quota) { | ||
6003 | int mod_seq = 0; | ||
6004 | |||
6005 | if (owner_objectid >= BTRFS_FIRST_FREE_OBJECTID && | ||
6006 | type == BTRFS_QGROUP_OPER_SUB_SHARED) | ||
6007 | mod_seq = 1; | ||
6008 | |||
6009 | ret = btrfs_qgroup_record_ref(trans, info, root_objectid, | ||
6010 | bytenr, num_bytes, type, | ||
6011 | mod_seq); | ||
6012 | } | ||
5977 | out: | 6013 | out: |
5978 | btrfs_free_path(path); | 6014 | btrfs_free_path(path); |
5979 | return ret; | 6015 | return ret; |
@@ -6110,7 +6146,7 @@ out: | |||
6110 | /* Can return -ENOMEM */ | 6146 | /* Can return -ENOMEM */ |
6111 | int btrfs_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root *root, | 6147 | int btrfs_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root *root, |
6112 | u64 bytenr, u64 num_bytes, u64 parent, u64 root_objectid, | 6148 | u64 bytenr, u64 num_bytes, u64 parent, u64 root_objectid, |
6113 | u64 owner, u64 offset, int for_cow) | 6149 | u64 owner, u64 offset, int no_quota) |
6114 | { | 6150 | { |
6115 | int ret; | 6151 | int ret; |
6116 | struct btrfs_fs_info *fs_info = root->fs_info; | 6152 | struct btrfs_fs_info *fs_info = root->fs_info; |
@@ -6130,13 +6166,13 @@ int btrfs_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root *root, | |||
6130 | ret = btrfs_add_delayed_tree_ref(fs_info, trans, bytenr, | 6166 | ret = btrfs_add_delayed_tree_ref(fs_info, trans, bytenr, |
6131 | num_bytes, | 6167 | num_bytes, |
6132 | parent, root_objectid, (int)owner, | 6168 | parent, root_objectid, (int)owner, |
6133 | BTRFS_DROP_DELAYED_REF, NULL, for_cow); | 6169 | BTRFS_DROP_DELAYED_REF, NULL, no_quota); |
6134 | } else { | 6170 | } else { |
6135 | ret = btrfs_add_delayed_data_ref(fs_info, trans, bytenr, | 6171 | ret = btrfs_add_delayed_data_ref(fs_info, trans, bytenr, |
6136 | num_bytes, | 6172 | num_bytes, |
6137 | parent, root_objectid, owner, | 6173 | parent, root_objectid, owner, |
6138 | offset, BTRFS_DROP_DELAYED_REF, | 6174 | offset, BTRFS_DROP_DELAYED_REF, |
6139 | NULL, for_cow); | 6175 | NULL, no_quota); |
6140 | } | 6176 | } |
6141 | return ret; | 6177 | return ret; |
6142 | } | 6178 | } |
@@ -6842,6 +6878,13 @@ static int alloc_reserved_file_extent(struct btrfs_trans_handle *trans, | |||
6842 | btrfs_mark_buffer_dirty(path->nodes[0]); | 6878 | btrfs_mark_buffer_dirty(path->nodes[0]); |
6843 | btrfs_free_path(path); | 6879 | btrfs_free_path(path); |
6844 | 6880 | ||
6881 | /* Always set parent to 0 here since its exclusive anyway. */ | ||
6882 | ret = btrfs_qgroup_record_ref(trans, fs_info, root_objectid, | ||
6883 | ins->objectid, ins->offset, | ||
6884 | BTRFS_QGROUP_OPER_ADD_EXCL, 0); | ||
6885 | if (ret) | ||
6886 | return ret; | ||
6887 | |||
6845 | ret = update_block_group(root, ins->objectid, ins->offset, 1); | 6888 | ret = update_block_group(root, ins->objectid, ins->offset, 1); |
6846 | if (ret) { /* -ENOENT, logic error */ | 6889 | if (ret) { /* -ENOENT, logic error */ |
6847 | btrfs_err(fs_info, "update block group failed for %llu %llu", | 6890 | btrfs_err(fs_info, "update block group failed for %llu %llu", |
@@ -6856,7 +6899,8 @@ static int alloc_reserved_tree_block(struct btrfs_trans_handle *trans, | |||
6856 | struct btrfs_root *root, | 6899 | struct btrfs_root *root, |
6857 | u64 parent, u64 root_objectid, | 6900 | u64 parent, u64 root_objectid, |
6858 | u64 flags, struct btrfs_disk_key *key, | 6901 | u64 flags, struct btrfs_disk_key *key, |
6859 | int level, struct btrfs_key *ins) | 6902 | int level, struct btrfs_key *ins, |
6903 | int no_quota) | ||
6860 | { | 6904 | { |
6861 | int ret; | 6905 | int ret; |
6862 | struct btrfs_fs_info *fs_info = root->fs_info; | 6906 | struct btrfs_fs_info *fs_info = root->fs_info; |
@@ -6866,6 +6910,7 @@ static int alloc_reserved_tree_block(struct btrfs_trans_handle *trans, | |||
6866 | struct btrfs_path *path; | 6910 | struct btrfs_path *path; |
6867 | struct extent_buffer *leaf; | 6911 | struct extent_buffer *leaf; |
6868 | u32 size = sizeof(*extent_item) + sizeof(*iref); | 6912 | u32 size = sizeof(*extent_item) + sizeof(*iref); |
6913 | u64 num_bytes = ins->offset; | ||
6869 | bool skinny_metadata = btrfs_fs_incompat(root->fs_info, | 6914 | bool skinny_metadata = btrfs_fs_incompat(root->fs_info, |
6870 | SKINNY_METADATA); | 6915 | SKINNY_METADATA); |
6871 | 6916 | ||
@@ -6899,6 +6944,7 @@ static int alloc_reserved_tree_block(struct btrfs_trans_handle *trans, | |||
6899 | 6944 | ||
6900 | if (skinny_metadata) { | 6945 | if (skinny_metadata) { |
6901 | iref = (struct btrfs_extent_inline_ref *)(extent_item + 1); | 6946 | iref = (struct btrfs_extent_inline_ref *)(extent_item + 1); |
6947 | num_bytes = root->leafsize; | ||
6902 | } else { | 6948 | } else { |
6903 | block_info = (struct btrfs_tree_block_info *)(extent_item + 1); | 6949 | block_info = (struct btrfs_tree_block_info *)(extent_item + 1); |
6904 | btrfs_set_tree_block_key(leaf, block_info, key); | 6950 | btrfs_set_tree_block_key(leaf, block_info, key); |
@@ -6920,6 +6966,14 @@ static int alloc_reserved_tree_block(struct btrfs_trans_handle *trans, | |||
6920 | btrfs_mark_buffer_dirty(leaf); | 6966 | btrfs_mark_buffer_dirty(leaf); |
6921 | btrfs_free_path(path); | 6967 | btrfs_free_path(path); |
6922 | 6968 | ||
6969 | if (!no_quota) { | ||
6970 | ret = btrfs_qgroup_record_ref(trans, fs_info, root_objectid, | ||
6971 | ins->objectid, num_bytes, | ||
6972 | BTRFS_QGROUP_OPER_ADD_EXCL, 0); | ||
6973 | if (ret) | ||
6974 | return ret; | ||
6975 | } | ||
6976 | |||
6923 | ret = update_block_group(root, ins->objectid, root->leafsize, 1); | 6977 | ret = update_block_group(root, ins->objectid, root->leafsize, 1); |
6924 | if (ret) { /* -ENOENT, logic error */ | 6978 | if (ret) { /* -ENOENT, logic error */ |
6925 | btrfs_err(fs_info, "update block group failed for %llu %llu", | 6979 | btrfs_err(fs_info, "update block group failed for %llu %llu", |