]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - fs/btrfs/delayed-ref.c
btrfs: free delayed node outside of root->inode_lock
[karo-tx-linux.git] / fs / btrfs / delayed-ref.c
index 31299646024d65340b4a8c401a41bdb594402d57..6d16bea94e1cd1cac5c102efa8b50290c2b4e218 100644 (file)
@@ -106,6 +106,10 @@ static int comp_entry(struct btrfs_delayed_ref_node *ref2,
                return -1;
        if (ref1->type > ref2->type)
                return 1;
+       if (ref1->no_quota > ref2->no_quota)
+               return 1;
+       if (ref1->no_quota < ref2->no_quota)
+               return -1;
        /* merging of sequenced refs is not allowed */
        if (compare_seq) {
                if (ref1->seq < ref2->seq)
@@ -635,7 +639,7 @@ add_delayed_tree_ref(struct btrfs_fs_info *fs_info,
                     struct btrfs_delayed_ref_head *head_ref,
                     struct btrfs_delayed_ref_node *ref, u64 bytenr,
                     u64 num_bytes, u64 parent, u64 ref_root, int level,
-                    int action, int for_cow)
+                    int action, int no_quota)
 {
        struct btrfs_delayed_ref_node *existing;
        struct btrfs_delayed_tree_ref *full_ref;
@@ -645,6 +649,8 @@ add_delayed_tree_ref(struct btrfs_fs_info *fs_info,
        if (action == BTRFS_ADD_DELAYED_EXTENT)
                action = BTRFS_ADD_DELAYED_REF;
 
+       if (is_fstree(ref_root))
+               seq = atomic64_read(&fs_info->tree_mod_seq);
        delayed_refs = &trans->transaction->delayed_refs;
 
        /* first set the basic ref node struct up */
@@ -655,9 +661,7 @@ add_delayed_tree_ref(struct btrfs_fs_info *fs_info,
        ref->action = action;
        ref->is_head = 0;
        ref->in_tree = 1;
-
-       if (need_ref_seq(for_cow, ref_root))
-               seq = btrfs_get_tree_mod_seq(fs_info, &trans->delayed_ref_elem);
+       ref->no_quota = no_quota;
        ref->seq = seq;
 
        full_ref = btrfs_delayed_node_to_tree_ref(ref);
@@ -697,7 +701,7 @@ add_delayed_data_ref(struct btrfs_fs_info *fs_info,
                     struct btrfs_delayed_ref_head *head_ref,
                     struct btrfs_delayed_ref_node *ref, u64 bytenr,
                     u64 num_bytes, u64 parent, u64 ref_root, u64 owner,
-                    u64 offset, int action, int for_cow)
+                    u64 offset, int action, int no_quota)
 {
        struct btrfs_delayed_ref_node *existing;
        struct btrfs_delayed_data_ref *full_ref;
@@ -709,6 +713,9 @@ add_delayed_data_ref(struct btrfs_fs_info *fs_info,
 
        delayed_refs = &trans->transaction->delayed_refs;
 
+       if (is_fstree(ref_root))
+               seq = atomic64_read(&fs_info->tree_mod_seq);
+
        /* first set the basic ref node struct up */
        atomic_set(&ref->refs, 1);
        ref->bytenr = bytenr;
@@ -717,9 +724,7 @@ add_delayed_data_ref(struct btrfs_fs_info *fs_info,
        ref->action = action;
        ref->is_head = 0;
        ref->in_tree = 1;
-
-       if (need_ref_seq(for_cow, ref_root))
-               seq = btrfs_get_tree_mod_seq(fs_info, &trans->delayed_ref_elem);
+       ref->no_quota = no_quota;
        ref->seq = seq;
 
        full_ref = btrfs_delayed_node_to_data_ref(ref);
@@ -762,12 +767,15 @@ int btrfs_add_delayed_tree_ref(struct btrfs_fs_info *fs_info,
                               u64 bytenr, u64 num_bytes, u64 parent,
                               u64 ref_root,  int level, int action,
                               struct btrfs_delayed_extent_op *extent_op,
-                              int for_cow)
+                              int no_quota)
 {
        struct btrfs_delayed_tree_ref *ref;
        struct btrfs_delayed_ref_head *head_ref;
        struct btrfs_delayed_ref_root *delayed_refs;
 
+       if (!is_fstree(ref_root) || !fs_info->quota_enabled)
+               no_quota = 0;
+
        BUG_ON(extent_op && extent_op->is_data);
        ref = kmem_cache_alloc(btrfs_delayed_tree_ref_cachep, GFP_NOFS);
        if (!ref)
@@ -793,10 +801,8 @@ int btrfs_add_delayed_tree_ref(struct btrfs_fs_info *fs_info,
 
        add_delayed_tree_ref(fs_info, trans, head_ref, &ref->node, bytenr,
                                   num_bytes, parent, ref_root, level, action,
-                                  for_cow);
+                                  no_quota);
        spin_unlock(&delayed_refs->lock);
-       if (need_ref_seq(for_cow, ref_root))
-               btrfs_qgroup_record_ref(trans, &ref->node, extent_op);
 
        return 0;
 }
@@ -810,12 +816,15 @@ int btrfs_add_delayed_data_ref(struct btrfs_fs_info *fs_info,
                               u64 parent, u64 ref_root,
                               u64 owner, u64 offset, int action,
                               struct btrfs_delayed_extent_op *extent_op,
-                              int for_cow)
+                              int no_quota)
 {
        struct btrfs_delayed_data_ref *ref;
        struct btrfs_delayed_ref_head *head_ref;
        struct btrfs_delayed_ref_root *delayed_refs;
 
+       if (!is_fstree(ref_root) || !fs_info->quota_enabled)
+               no_quota = 0;
+
        BUG_ON(extent_op && !extent_op->is_data);
        ref = kmem_cache_alloc(btrfs_delayed_data_ref_cachep, GFP_NOFS);
        if (!ref)
@@ -841,10 +850,8 @@ int btrfs_add_delayed_data_ref(struct btrfs_fs_info *fs_info,
 
        add_delayed_data_ref(fs_info, trans, head_ref, &ref->node, bytenr,
                                   num_bytes, parent, ref_root, owner, offset,
-                                  action, for_cow);
+                                  action, no_quota);
        spin_unlock(&delayed_refs->lock);
-       if (need_ref_seq(for_cow, ref_root))
-               btrfs_qgroup_record_ref(trans, &ref->node, extent_op);
 
        return 0;
 }