This is used by later dedup patches.
Signed-off-by: Qu Wenruo <quwenruo@xxxxxxxxxxxxxx>
---
fs/btrfs/ctree.h | 4 ++++
fs/btrfs/delayed-ref.c | 25 +++++++++++++++++--------
fs/btrfs/delayed-ref.h | 2 +-
fs/btrfs/extent-tree.c | 24 +++++++++++++++++++++---
4 files changed, 43 insertions(+), 12 deletions(-)
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 2132fa5..671be87 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -3539,6 +3539,10 @@ int btrfs_inc_extent_ref(struct
btrfs_trans_handle *trans,
struct btrfs_root *root,
u64 bytenr, u64 num_bytes, u64 parent,
u64 root_objectid, u64 owner, u64 offset);
+int btrfs_inc_extent_ref_atomic(struct btrfs_trans_handle *trans,
+ struct btrfs_root *root, u64 bytenr,
+ u64 num_bytes, u64 parent,
+ u64 root_objectid, u64 owner, u64
offset);
int btrfs_start_dirty_block_groups(struct btrfs_trans_handle *trans,
struct btrfs_root *root);
diff --git a/fs/btrfs/delayed-ref.c b/fs/btrfs/delayed-ref.c
index 914ac13..e869442 100644
--- a/fs/btrfs/delayed-ref.c
+++ b/fs/btrfs/delayed-ref.c
@@ -812,26 +812,31 @@ int btrfs_add_delayed_data_ref(struct
btrfs_fs_info *fs_info,
u64 bytenr, u64 num_bytes,
u64 parent, u64 ref_root,
u64 owner, u64 offset, u64 reserved,
int action,
- struct btrfs_delayed_extent_op
*extent_op)
+ int atomic)
{
struct btrfs_delayed_data_ref *ref;
struct btrfs_delayed_ref_head *head_ref;
struct btrfs_delayed_ref_root *delayed_refs;
struct btrfs_qgroup_extent_record *record = NULL;
+ gfp_t gfp_flags;
+
+ if (atomic)
+ gfp_flags = GFP_ATOMIC;
+ else
+ gfp_flags = GFP_NOFS;
- BUG_ON(extent_op && !extent_op->is_data);
- ref = kmem_cache_alloc(btrfs_delayed_data_ref_cachep, GFP_NOFS);
+ ref = kmem_cache_alloc(btrfs_delayed_data_ref_cachep,
gfp_flags);
if (!ref)
return -ENOMEM;
- head_ref = kmem_cache_alloc(btrfs_delayed_ref_head_cachep,
GFP_NOFS);
+ head_ref = kmem_cache_alloc(btrfs_delayed_ref_head_cachep,
gfp_flags);
if (!head_ref) {
kmem_cache_free(btrfs_delayed_data_ref_cachep, ref);
return -ENOMEM;
}
if (fs_info->quota_enabled && is_fstree(ref_root)) {
- record = kmalloc(sizeof(*record), GFP_NOFS);
+ record = kmalloc(sizeof(*record), gfp_flags);
if (!record) {
kmem_cache_free(btrfs_delayed_data_ref_cachep, ref);
kmem_cache_free(btrfs_delayed_ref_head_cachep,
@@ -840,10 +845,13 @@ int btrfs_add_delayed_data_ref(struct
btrfs_fs_info *fs_info,
}
}
- head_ref->extent_op = extent_op;
+ head_ref->extent_op = NULL;
delayed_refs = &trans->transaction->delayed_refs;
- spin_lock(&delayed_refs->lock);
+
+ /* For atomic case, caller should already hold the
delayed_refs lock */
+ if (!atomic)
+ spin_lock(&delayed_refs->lock);
/*
* insert both the head node and the new ref without dropping
@@ -856,7 +864,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);
- spin_unlock(&delayed_refs->lock);
+ if (!atomic)
+ spin_unlock(&delayed_refs->lock);
return 0;
}
diff --git a/fs/btrfs/delayed-ref.h b/fs/btrfs/delayed-ref.h
index c24b653..e34f96a 100644
--- a/fs/btrfs/delayed-ref.h
+++ b/fs/btrfs/delayed-ref.h
@@ -249,7 +249,7 @@ int btrfs_add_delayed_data_ref(struct
btrfs_fs_info *fs_info,
u64 bytenr, u64 num_bytes,
u64 parent, u64 ref_root,
u64 owner, u64 offset, u64 reserved,
int action,
- struct btrfs_delayed_extent_op
*extent_op);
+ int atomic);
int btrfs_add_delayed_qgroup_reserve(struct btrfs_fs_info *fs_info,
struct btrfs_trans_handle *trans,
u64 ref_root, u64 bytenr, u64
num_bytes);
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 60cc139..4a01ca9 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -2105,11 +2105,29 @@ int btrfs_inc_extent_ref(struct
btrfs_trans_handle *trans,
ret = btrfs_add_delayed_data_ref(fs_info, trans,
bytenr,
num_bytes, parent,
root_objectid,
owner, offset, 0,
- BTRFS_ADD_DELAYED_REF, NULL);
+ BTRFS_ADD_DELAYED_REF, 0);
}
return ret;
}
+int btrfs_inc_extent_ref_atomic(struct btrfs_trans_handle *trans,
+ struct btrfs_root *root, u64 bytenr,
+ u64 num_bytes, u64 parent,
+ u64 root_objectid, u64 owner, u64
offset)
+{
+ struct btrfs_fs_info *fs_info = root->fs_info;
+
+ BUG_ON(owner < BTRFS_FIRST_FREE_OBJECTID &&
+ root_objectid == BTRFS_TREE_LOG_OBJECTID);
+
+ /* Only used by dedup, so only data is possible */
+ if (WARN_ON(owner < BTRFS_FIRST_FREE_OBJECTID))
+ return -EINVAL;
+ return btrfs_add_delayed_data_ref(fs_info, trans, bytenr,
+ num_bytes, parent, root_objectid,
+ owner, offset, 0, BTRFS_ADD_DELAYED_REF, 1);
+}
+
static int __btrfs_inc_extent_ref(struct btrfs_trans_handle *trans,
struct btrfs_root *root,
struct btrfs_delayed_ref_node *node,
@@ -6893,7 +6911,7 @@ int btrfs_free_extent(struct btrfs_trans_handle
*trans, struct btrfs_root *root,
num_bytes,
parent,
root_objectid, owner,
offset, 0,
-
BTRFS_DROP_DELAYED_REF, NULL);
+
BTRFS_DROP_DELAYED_REF, 0);
}
return ret;
}
@@ -7845,7 +7863,7 @@ int btrfs_alloc_reserved_file_extent(struct
btrfs_trans_handle *trans,
ins->offset, 0,
root_objectid, owner, offset,
ram_bytes,
BTRFS_ADD_DELAYED_EXTENT,
- NULL);
+ 0);
return ret;
}
--
2.7.0
--
To unsubscribe from this list: send the line "unsubscribe
linux-btrfs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html