OSDN Git Service

x86/cpufeature: Replace the old static_cpu_has() with safe variant
[sagit-ice-cold/kernel_xiaomi_msm8998.git] / fs / btrfs / ctree.c
index 5b8e235..38ee086 100644 (file)
@@ -1551,6 +1551,7 @@ noinline int btrfs_cow_block(struct btrfs_trans_handle *trans,
                       trans->transid, root->fs_info->generation);
 
        if (!should_cow_block(trans, root, buf)) {
+               trans->dirty = true;
                *cow_ret = buf;
                return 0;
        }
@@ -2496,10 +2497,8 @@ read_block_for_search(struct btrfs_trans_handle *trans,
        if (p->reada)
                reada_for_search(root, p, level, slot, key->objectid);
 
-       btrfs_release_path(p);
-
        ret = -EAGAIN;
-       tmp = read_tree_block(root, blocknr, 0);
+       tmp = read_tree_block(root, blocknr, gen);
        if (!IS_ERR(tmp)) {
                /*
                 * If the read above didn't mark this buffer up to date,
@@ -2511,6 +2510,8 @@ read_block_for_search(struct btrfs_trans_handle *trans,
                        ret = -EIO;
                free_extent_buffer(tmp);
        }
+
+       btrfs_release_path(p);
        return ret;
 }
 
@@ -2768,13 +2769,17 @@ again:
                 * contention with the cow code
                 */
                if (cow) {
+                       bool last_level = (level == (BTRFS_MAX_LEVEL - 1));
+
                        /*
                         * if we don't really need to cow this block
                         * then we don't want to set the path blocking,
                         * so we test it here
                         */
-                       if (!should_cow_block(trans, root, b))
+                       if (!should_cow_block(trans, root, b)) {
+                               trans->dirty = true;
                                goto cow_done;
+                       }
 
                        /*
                         * must have write locks on this node and the
@@ -2790,9 +2795,13 @@ again:
                        }
 
                        btrfs_set_path_blocking(p);
-                       err = btrfs_cow_block(trans, root, b,
-                                             p->nodes[level + 1],
-                                             p->slots[level + 1], &b);
+                       if (last_level)
+                               err = btrfs_cow_block(trans, root, b, NULL, 0,
+                                                     &b);
+                       else
+                               err = btrfs_cow_block(trans, root, b,
+                                                     p->nodes[level + 1],
+                                                     p->slots[level + 1], &b);
                        if (err) {
                                ret = err;
                                goto done;