aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/btrfs/extent-tree.c8
-rw-r--r--fs/btrfs/inode.c26
2 files changed, 31 insertions, 3 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index ab36769c356c..280ac1aa9b6d 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -1151,6 +1151,14 @@ int btrfs_cache_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root,
1151 } 1151 }
1152 1152
1153 ret = btrfs_add_leaf_ref(root, ref, shared); 1153 ret = btrfs_add_leaf_ref(root, ref, shared);
1154 if (ret == -EEXIST && shared) {
1155 struct btrfs_leaf_ref *old;
1156 old = btrfs_lookup_leaf_ref(root, ref->bytenr);
1157 BUG_ON(!old);
1158 btrfs_remove_leaf_ref(root, old);
1159 btrfs_free_leaf_ref(root, old);
1160 ret = btrfs_add_leaf_ref(root, ref, shared);
1161 }
1154 WARN_ON(ret); 1162 WARN_ON(ret);
1155 btrfs_free_leaf_ref(root, ref); 1163 btrfs_free_leaf_ref(root, ref);
1156 } 1164 }
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 3ab147dc3c05..11bfe131fde6 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -48,6 +48,7 @@
48#include "xattr.h" 48#include "xattr.h"
49#include "compat.h" 49#include "compat.h"
50#include "tree-log.h" 50#include "tree-log.h"
51#include "ref-cache.h"
51 52
52struct btrfs_iget_args { 53struct btrfs_iget_args {
53 u64 ino; 54 u64 ino;
@@ -1416,6 +1417,9 @@ static noinline int drop_csum_leaves(struct btrfs_trans_handle *trans,
1416 int nritems; 1417 int nritems;
1417 struct btrfs_key found_key; 1418 struct btrfs_key found_key;
1418 struct btrfs_key other_key; 1419 struct btrfs_key other_key;
1420 struct btrfs_leaf_ref *ref;
1421 u64 leaf_gen;
1422 u64 leaf_start;
1419 1423
1420 path->lowest_level = 1; 1424 path->lowest_level = 1;
1421 key.objectid = inode->i_ino; 1425 key.objectid = inode->i_ino;
@@ -1509,15 +1513,31 @@ next_node:
1509 if (other_key.objectid != inode->i_ino || other_key.type != key.type) 1513 if (other_key.objectid != inode->i_ino || other_key.type != key.type)
1510 goto out; 1514 goto out;
1511 1515
1516 leaf_start = btrfs_node_blockptr(path->nodes[1], path->slots[1]);
1517 leaf_gen = btrfs_node_ptr_generation(path->nodes[1], path->slots[1]);
1512 /* 1518 /*
1513 * it is safe to delete this leaf, it contains only 1519 * it is safe to delete this leaf, it contains only
1514 * csum items from this inode at an offset >= new_size 1520 * csum items from this inode at an offset >= new_size
1515 */ 1521 */
1516 ret = btrfs_del_leaf(trans, root, path, 1522 ret = btrfs_del_leaf(trans, root, path, leaf_start);
1517 btrfs_node_blockptr(path->nodes[1],
1518 path->slots[1]));
1519 BUG_ON(ret); 1523 BUG_ON(ret);
1520 1524
1525 if (root->ref_cows && leaf_gen < trans->transid) {
1526 ref = btrfs_alloc_leaf_ref(root, 0);
1527 if (ref) {
1528 ref->root_gen = root->root_key.offset;
1529 ref->bytenr = leaf_start;
1530 ref->owner = 0;
1531 ref->generation = leaf_gen;
1532 ref->nritems = 0;
1533
1534 ret = btrfs_add_leaf_ref(root, ref, 0);
1535 WARN_ON(ret);
1536 btrfs_free_leaf_ref(root, ref);
1537 } else {
1538 WARN_ON(1);
1539 }
1540 }
1521next_key: 1541next_key:
1522 btrfs_release_path(root, path); 1542 btrfs_release_path(root, path);
1523 1543