diff options
-rw-r--r-- | fs/btrfs/ioctl.c | 23 |
1 files changed, 14 insertions, 9 deletions
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 5ed5bd001084..829999dafd93 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c | |||
@@ -2905,12 +2905,14 @@ static int btrfs_clone(struct inode *src, struct inode *inode, | |||
2905 | * note the key will change type as we walk through the | 2905 | * note the key will change type as we walk through the |
2906 | * tree. | 2906 | * tree. |
2907 | */ | 2907 | */ |
2908 | path->leave_spinning = 1; | ||
2908 | ret = btrfs_search_slot(NULL, BTRFS_I(src)->root, &key, path, | 2909 | ret = btrfs_search_slot(NULL, BTRFS_I(src)->root, &key, path, |
2909 | 0, 0); | 2910 | 0, 0); |
2910 | if (ret < 0) | 2911 | if (ret < 0) |
2911 | goto out; | 2912 | goto out; |
2912 | 2913 | ||
2913 | nritems = btrfs_header_nritems(path->nodes[0]); | 2914 | nritems = btrfs_header_nritems(path->nodes[0]); |
2915 | process_slot: | ||
2914 | if (path->slots[0] >= nritems) { | 2916 | if (path->slots[0] >= nritems) { |
2915 | ret = btrfs_next_leaf(BTRFS_I(src)->root, path); | 2917 | ret = btrfs_next_leaf(BTRFS_I(src)->root, path); |
2916 | if (ret < 0) | 2918 | if (ret < 0) |
@@ -2937,11 +2939,6 @@ static int btrfs_clone(struct inode *src, struct inode *inode, | |||
2937 | u8 comp; | 2939 | u8 comp; |
2938 | u64 endoff; | 2940 | u64 endoff; |
2939 | 2941 | ||
2940 | size = btrfs_item_size_nr(leaf, slot); | ||
2941 | read_extent_buffer(leaf, buf, | ||
2942 | btrfs_item_ptr_offset(leaf, slot), | ||
2943 | size); | ||
2944 | |||
2945 | extent = btrfs_item_ptr(leaf, slot, | 2942 | extent = btrfs_item_ptr(leaf, slot, |
2946 | struct btrfs_file_extent_item); | 2943 | struct btrfs_file_extent_item); |
2947 | comp = btrfs_file_extent_compression(leaf, extent); | 2944 | comp = btrfs_file_extent_compression(leaf, extent); |
@@ -2960,11 +2957,20 @@ static int btrfs_clone(struct inode *src, struct inode *inode, | |||
2960 | datal = btrfs_file_extent_ram_bytes(leaf, | 2957 | datal = btrfs_file_extent_ram_bytes(leaf, |
2961 | extent); | 2958 | extent); |
2962 | } | 2959 | } |
2963 | btrfs_release_path(path); | ||
2964 | 2960 | ||
2965 | if (key.offset + datal <= off || | 2961 | if (key.offset + datal <= off || |
2966 | key.offset >= off + len - 1) | 2962 | key.offset >= off + len - 1) { |
2967 | goto next; | 2963 | path->slots[0]++; |
2964 | goto process_slot; | ||
2965 | } | ||
2966 | |||
2967 | size = btrfs_item_size_nr(leaf, slot); | ||
2968 | read_extent_buffer(leaf, buf, | ||
2969 | btrfs_item_ptr_offset(leaf, slot), | ||
2970 | size); | ||
2971 | |||
2972 | btrfs_release_path(path); | ||
2973 | path->leave_spinning = 0; | ||
2968 | 2974 | ||
2969 | memcpy(&new_key, &key, sizeof(new_key)); | 2975 | memcpy(&new_key, &key, sizeof(new_key)); |
2970 | new_key.objectid = btrfs_ino(inode); | 2976 | new_key.objectid = btrfs_ino(inode); |
@@ -3135,7 +3141,6 @@ static int btrfs_clone(struct inode *src, struct inode *inode, | |||
3135 | } | 3141 | } |
3136 | ret = btrfs_end_transaction(trans, root); | 3142 | ret = btrfs_end_transaction(trans, root); |
3137 | } | 3143 | } |
3138 | next: | ||
3139 | btrfs_release_path(path); | 3144 | btrfs_release_path(path); |
3140 | key.offset++; | 3145 | key.offset++; |
3141 | } | 3146 | } |