summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Sterba <dsterba@suse.com>2016-11-08 18:30:31 +0100
committerDavid Sterba <dsterba@suse.com>2016-11-30 13:45:17 +0100
commit58e8012cc12b3cdebea118981c4fd7136d52f2c7 (patch)
tree5cda8d4a202fc99ee64be2de43c251b4982c993e
parentb159fa2808b1b53d784807a48ad95fa809be10b0 (diff)
downloadlinux-58e8012cc12b3cdebea118981c4fd7136d52f2c7.tar.gz
linux-58e8012cc12b3cdebea118981c4fd7136d52f2c7.tar.bz2
linux-58e8012cc12b3cdebea118981c4fd7136d52f2c7.zip
btrfs: add optimized version of eb to eb copy
Using copy_extent_buffer is suitable for copying betwenn buffers from an arbitrary offset and deals with page boundaries. This is not necessary when doing a full extent_buffer-to-extent_buffer copy. We can utilize the copy_page helper as well. Signed-off-by: David Sterba <dsterba@suse.com>
-rw-r--r--fs/btrfs/ctree.c4
-rw-r--r--fs/btrfs/extent_io.c14
-rw-r--r--fs/btrfs/extent_io.h2
3 files changed, 18 insertions, 2 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index be362b776138..25286a5912fc 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -260,7 +260,7 @@ int btrfs_copy_root(struct btrfs_trans_handle *trans,
if (IS_ERR(cow))
return PTR_ERR(cow);
- copy_extent_buffer(cow, buf, 0, 0, cow->len);
+ copy_extent_buffer_full(cow, buf);
btrfs_set_header_bytenr(cow, cow->start);
btrfs_set_header_generation(cow, trans->transid);
btrfs_set_header_backref_rev(cow, BTRFS_MIXED_BACKREF_REV);
@@ -1129,7 +1129,7 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans,
/* cow is set to blocking by btrfs_init_new_buffer */
- copy_extent_buffer(cow, buf, 0, 0, cow->len);
+ copy_extent_buffer_full(cow, buf);
btrfs_set_header_bytenr(cow, cow->start);
btrfs_set_header_generation(cow, trans->transid);
btrfs_set_header_backref_rev(cow, BTRFS_MIXED_BACKREF_REV);
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index 9f8a1a331c61..d24af9dc76c7 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -5546,6 +5546,20 @@ void memzero_extent_buffer(struct extent_buffer *eb, unsigned long start,
}
}
+void copy_extent_buffer_full(struct extent_buffer *dst,
+ struct extent_buffer *src)
+{
+ int i;
+ unsigned num_pages;
+
+ ASSERT(dst->len == src->len);
+
+ num_pages = num_extent_pages(dst->start, dst->len);
+ for (i = 0; i < num_pages; i++)
+ copy_page(page_address(dst->pages[i]),
+ page_address(src->pages[i]));
+}
+
void copy_extent_buffer(struct extent_buffer *dst, struct extent_buffer *src,
unsigned long dst_offset, unsigned long src_offset,
unsigned long len)
diff --git a/fs/btrfs/extent_io.h b/fs/btrfs/extent_io.h
index 12fe17523df2..ae64c1917d0a 100644
--- a/fs/btrfs/extent_io.h
+++ b/fs/btrfs/extent_io.h
@@ -410,6 +410,8 @@ void write_extent_buffer_chunk_tree_uuid(struct extent_buffer *eb,
const void *src);
void write_extent_buffer(struct extent_buffer *eb, const void *src,
unsigned long start, unsigned long len);
+void copy_extent_buffer_full(struct extent_buffer *dst,
+ struct extent_buffer *src);
void copy_extent_buffer(struct extent_buffer *dst, struct extent_buffer *src,
unsigned long dst_offset, unsigned long src_offset,
unsigned long len);