Now on-disk backend can delete hash now. Signed-off-by: Wang Xiaoguang <wangxg.f...@cn.fujitsu.com> Signed-off-by: Qu Wenruo <quwen...@cn.fujitsu.com> --- fs/btrfs/dedup.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+)
diff --git a/fs/btrfs/dedup.c b/fs/btrfs/dedup.c index 82e21a6..704c3c7 100644 --- a/fs/btrfs/dedup.c +++ b/fs/btrfs/dedup.c @@ -468,6 +468,58 @@ static int inmem_del(struct btrfs_dedup_info *dedup_info, u64 bytenr) return 0; } +static int ondisk_del(struct btrfs_trans_handle *trans, + struct btrfs_dedup_info *dedup_info, u64 bytenr) +{ + struct btrfs_root *dedup_root = dedup_info->dedup_root; + struct btrfs_path *path; + struct btrfs_key key; + int ret; + + path = btrfs_alloc_path(); + if (!path) + return -ENOMEM; + + key.objectid = bytenr; + key.type = BTRFS_DEDUP_BYTENR_ITEM_KEY; + key.offset = 0; + + mutex_lock(&dedup_info->ondisk_lock); + + ret = btrfs_search_slot(trans, dedup_root, &key, path, -1, 1); + if (ret < 0) + goto out; + + /* There should be at most one item with same objectid and type */ + btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]); + if (key.objectid != bytenr || key.type != BTRFS_DEDUP_BYTENR_ITEM_KEY) { + ret = 0; + goto out; + } + + btrfs_del_item(trans, dedup_root, path); + btrfs_release_path(path); + + /* Search for hash item and delete it */ + key.objectid = key.offset; + key.type = BTRFS_DEDUP_HASH_ITEM_KEY; + key.offset = bytenr; + + ret = btrfs_search_slot(trans, dedup_root, &key, path, -1, 1); + if (WARN_ON(ret > 0)) { + ret = -ENOENT; + goto out; + } + if (ret < 0) + goto out; + btrfs_del_item(trans, dedup_root, path); + +out: + btrfs_free_path(path); + mutex_unlock(&dedup_info->ondisk_lock); + return ret; +} + /* Remove a dedup hash from dedup tree */ int btrfs_dedup_del(struct btrfs_trans_handle *trans, struct btrfs_root *root, u64 bytenr) @@ -480,6 +532,8 @@ int btrfs_dedup_del(struct btrfs_trans_handle *trans, struct btrfs_root *root, if (dedup_info->backend == BTRFS_DEDUP_BACKEND_INMEMORY) return inmem_del(dedup_info, bytenr); + if (dedup_info->backend == BTRFS_DEDUP_BACKEND_ONDISK) + return ondisk_del(trans, dedup_info, bytenr); return -EINVAL; } -- 2.6.4 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html