+
+ if (btrfs_key_type(&key) == BTRFS_CSUM_ITEM_KEY) {
+ u32 size;
+ struct btrfs_key new_key;
+ u64 coverslen;
+ int coff, clen;
+
+ size = btrfs_item_size_nr(leaf, slot);
+ coverslen = (size / BTRFS_CRC32_SIZE) <<
+ root->fs_info->sb->s_blocksize_bits;
+ printk("csums for %llu~%llu\n",
+ key.offset, coverslen);
+ if (key.offset + coverslen < off ||
+ key.offset >= off+len)
+ goto next;
+
+ read_extent_buffer(leaf, buf,
+ btrfs_item_ptr_offset(leaf, slot),
+ size);
+ btrfs_release_path(root, path);
+
+ coff = 0;
+ if (off > key.offset)
+ coff = ((off - key.offset) >>
+ root->fs_info->sb->s_blocksize_bits) *
+ BTRFS_CRC32_SIZE;
+ clen = size - coff;
+ if (key.offset + coverslen > off+len)
+ clen -= ((key.offset+coverslen-off-len) >>
+ root->fs_info->sb->s_blocksize_bits) *
+ BTRFS_CRC32_SIZE;
+ printk(" will dup %d~%d of %d\n",
+ coff, clen, size);
+
+ memcpy(&new_key, &key, sizeof(new_key));
+ new_key.objectid = inode->i_ino;
+ new_key.offset = key.offset + destoff - off;
+
+ ret = btrfs_insert_empty_item(trans, root, path,
+ &new_key, clen);
+ if (ret)
+ goto out;
+
+ leaf = path->nodes[0];
+ slot = path->slots[0];
+ write_extent_buffer(leaf, buf + coff,
+ btrfs_item_ptr_offset(leaf, slot),
+ clen);
+ btrfs_mark_buffer_dirty(leaf);
+ }
+
+ next: