.. | .. |
---|
3589 | 3589 | |
---|
3590 | 3590 | ret = tree_mod_log_eb_copy(split, c, 0, mid, c_nritems - mid); |
---|
3591 | 3591 | if (ret) { |
---|
| 3592 | + btrfs_tree_unlock(split); |
---|
| 3593 | + free_extent_buffer(split); |
---|
3592 | 3594 | btrfs_abort_transaction(trans, ret); |
---|
3593 | 3595 | return ret; |
---|
3594 | 3596 | } |
---|
.. | .. |
---|
3872 | 3874 | |
---|
3873 | 3875 | if (check_sibling_keys(left, right)) { |
---|
3874 | 3876 | ret = -EUCLEAN; |
---|
| 3877 | + btrfs_abort_transaction(trans, ret); |
---|
3875 | 3878 | btrfs_tree_unlock(right); |
---|
3876 | 3879 | free_extent_buffer(right); |
---|
3877 | 3880 | return ret; |
---|
.. | .. |
---|
4116 | 4119 | |
---|
4117 | 4120 | if (check_sibling_keys(left, right)) { |
---|
4118 | 4121 | ret = -EUCLEAN; |
---|
| 4122 | + btrfs_abort_transaction(trans, ret); |
---|
4119 | 4123 | goto out; |
---|
4120 | 4124 | } |
---|
4121 | 4125 | return __push_leaf_left(path, min_data_size, |
---|
.. | .. |
---|
5160 | 5164 | int btrfs_prev_leaf(struct btrfs_root *root, struct btrfs_path *path) |
---|
5161 | 5165 | { |
---|
5162 | 5166 | struct btrfs_key key; |
---|
| 5167 | + struct btrfs_key orig_key; |
---|
5163 | 5168 | struct btrfs_disk_key found_key; |
---|
5164 | 5169 | int ret; |
---|
5165 | 5170 | |
---|
5166 | 5171 | btrfs_item_key_to_cpu(path->nodes[0], &key, 0); |
---|
| 5172 | + orig_key = key; |
---|
5167 | 5173 | |
---|
5168 | 5174 | if (key.offset > 0) { |
---|
5169 | 5175 | key.offset--; |
---|
.. | .. |
---|
5180 | 5186 | |
---|
5181 | 5187 | btrfs_release_path(path); |
---|
5182 | 5188 | ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); |
---|
5183 | | - if (ret < 0) |
---|
| 5189 | + if (ret <= 0) |
---|
5184 | 5190 | return ret; |
---|
| 5191 | + |
---|
| 5192 | + /* |
---|
| 5193 | + * Previous key not found. Even if we were at slot 0 of the leaf we had |
---|
| 5194 | + * before releasing the path and calling btrfs_search_slot(), we now may |
---|
| 5195 | + * be in a slot pointing to the same original key - this can happen if |
---|
| 5196 | + * after we released the path, one of more items were moved from a |
---|
| 5197 | + * sibling leaf into the front of the leaf we had due to an insertion |
---|
| 5198 | + * (see push_leaf_right()). |
---|
| 5199 | + * If we hit this case and our slot is > 0 and just decrement the slot |
---|
| 5200 | + * so that the caller does not process the same key again, which may or |
---|
| 5201 | + * may not break the caller, depending on its logic. |
---|
| 5202 | + */ |
---|
| 5203 | + if (path->slots[0] < btrfs_header_nritems(path->nodes[0])) { |
---|
| 5204 | + btrfs_item_key(path->nodes[0], &found_key, path->slots[0]); |
---|
| 5205 | + ret = comp_keys(&found_key, &orig_key); |
---|
| 5206 | + if (ret == 0) { |
---|
| 5207 | + if (path->slots[0] > 0) { |
---|
| 5208 | + path->slots[0]--; |
---|
| 5209 | + return 0; |
---|
| 5210 | + } |
---|
| 5211 | + /* |
---|
| 5212 | + * At slot 0, same key as before, it means orig_key is |
---|
| 5213 | + * the lowest, leftmost, key in the tree. We're done. |
---|
| 5214 | + */ |
---|
| 5215 | + return 1; |
---|
| 5216 | + } |
---|
| 5217 | + } |
---|
| 5218 | + |
---|
5185 | 5219 | btrfs_item_key(path->nodes[0], &found_key, 0); |
---|
5186 | 5220 | ret = comp_keys(&found_key, &key); |
---|
5187 | 5221 | /* |
---|