diff options
Diffstat (limited to 'fs/btrfs/extent-tree.c')
-rw-r--r-- | fs/btrfs/extent-tree.c | 13 |
1 files changed, 13 insertions, 0 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 1c2bd1723e40..171312d51799 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -2296,9 +2296,22 @@ static int run_one_delayed_ref(struct btrfs_trans_handle *trans, | |||
2296 | static inline struct btrfs_delayed_ref_node * | 2296 | static inline struct btrfs_delayed_ref_node * |
2297 | select_delayed_ref(struct btrfs_delayed_ref_head *head) | 2297 | select_delayed_ref(struct btrfs_delayed_ref_head *head) |
2298 | { | 2298 | { |
2299 | struct btrfs_delayed_ref_node *ref; | ||
2300 | |||
2299 | if (list_empty(&head->ref_list)) | 2301 | if (list_empty(&head->ref_list)) |
2300 | return NULL; | 2302 | return NULL; |
2301 | 2303 | ||
2304 | /* | ||
2305 | * Select a delayed ref of type BTRFS_ADD_DELAYED_REF first. | ||
2306 | * This is to prevent a ref count from going down to zero, which deletes | ||
2307 | * the extent item from the extent tree, when there still are references | ||
2308 | * to add, which would fail because they would not find the extent item. | ||
2309 | */ | ||
2310 | list_for_each_entry(ref, &head->ref_list, list) { | ||
2311 | if (ref->action == BTRFS_ADD_DELAYED_REF) | ||
2312 | return ref; | ||
2313 | } | ||
2314 | |||
2302 | return list_entry(head->ref_list.next, struct btrfs_delayed_ref_node, | 2315 | return list_entry(head->ref_list.next, struct btrfs_delayed_ref_node, |
2303 | list); | 2316 | list); |
2304 | } | 2317 | } |