aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/ioctl.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/ioctl.c')
-rw-r--r--fs/btrfs/ioctl.c55
1 files changed, 2 insertions, 53 deletions
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index b4da53d55c82..6228b69c2b93 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -714,8 +714,7 @@ static long btrfs_ioctl_clone(struct file *file, unsigned long srcfd,
714 u64 len = olen; 714 u64 len = olen;
715 u64 bs = root->fs_info->sb->s_blocksize; 715 u64 bs = root->fs_info->sb->s_blocksize;
716 u64 hint_byte; 716 u64 hint_byte;
717 u16 csum_size = 717
718 btrfs_super_csum_size(&root->fs_info->super_copy);
719 /* 718 /*
720 * TODO: 719 * TODO:
721 * - split compressed inline extents. annoying: we need to 720 * - split compressed inline extents. annoying: we need to
@@ -833,7 +832,7 @@ static long btrfs_ioctl_clone(struct file *file, unsigned long srcfd,
833 slot = path->slots[0]; 832 slot = path->slots[0];
834 833
835 btrfs_item_key_to_cpu(leaf, &key, slot); 834 btrfs_item_key_to_cpu(leaf, &key, slot);
836 if (btrfs_key_type(&key) > BTRFS_CSUM_ITEM_KEY || 835 if (btrfs_key_type(&key) > BTRFS_EXTENT_DATA_KEY ||
837 key.objectid != src->i_ino) 836 key.objectid != src->i_ino)
838 break; 837 break;
839 838
@@ -958,56 +957,6 @@ static long btrfs_ioctl_clone(struct file *file, unsigned long srcfd,
958 btrfs_mark_buffer_dirty(leaf); 957 btrfs_mark_buffer_dirty(leaf);
959 } 958 }
960 959
961 if (btrfs_key_type(&key) == BTRFS_CSUM_ITEM_KEY) {
962 u32 size;
963 struct btrfs_key new_key;
964 u64 coverslen;
965 int coff, clen;
966
967 size = btrfs_item_size_nr(leaf, slot);
968 coverslen = (size / csum_size) <<
969 root->fs_info->sb->s_blocksize_bits;
970 printk("csums for %llu~%llu\n",
971 key.offset, coverslen);
972 if (key.offset + coverslen < off ||
973 key.offset >= off+len)
974 goto next;
975
976 read_extent_buffer(leaf, buf,
977 btrfs_item_ptr_offset(leaf, slot),
978 size);
979 btrfs_release_path(root, path);
980
981 coff = 0;
982 if (off > key.offset)
983 coff = ((off - key.offset) >>
984 root->fs_info->sb->s_blocksize_bits) *
985 csum_size;
986 clen = size - coff;
987 if (key.offset + coverslen > off+len)
988 clen -= ((key.offset+coverslen-off-len) >>
989 root->fs_info->sb->s_blocksize_bits) *
990 csum_size;
991 printk(" will dup %d~%d of %d\n",
992 coff, clen, size);
993
994 memcpy(&new_key, &key, sizeof(new_key));
995 new_key.objectid = inode->i_ino;
996 new_key.offset = key.offset + destoff - off;
997
998 ret = btrfs_insert_empty_item(trans, root, path,
999 &new_key, clen);
1000 if (ret)
1001 goto out;
1002
1003 leaf = path->nodes[0];
1004 slot = path->slots[0];
1005 write_extent_buffer(leaf, buf + coff,
1006 btrfs_item_ptr_offset(leaf, slot),
1007 clen);
1008 btrfs_mark_buffer_dirty(leaf);
1009 }
1010
1011 next: 960 next:
1012 btrfs_release_path(root, path); 961 btrfs_release_path(root, path);
1013 key.offset++; 962 key.offset++;