aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/btrfs/ioctl.c23
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]);
2915process_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 }
3138next:
3139 btrfs_release_path(path); 3144 btrfs_release_path(path);
3140 key.offset++; 3145 key.offset++;
3141 } 3146 }