diff options
Diffstat (limited to 'fs/btrfs/extent_io.c')
-rw-r--r-- | fs/btrfs/extent_io.c | 39 |
1 files changed, 38 insertions, 1 deletions
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index f25a9092b946..a389820d158b 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c | |||
@@ -2354,7 +2354,7 @@ int end_extent_writepage(struct page *page, int err, u64 start, u64 end) | |||
2354 | { | 2354 | { |
2355 | int uptodate = (err == 0); | 2355 | int uptodate = (err == 0); |
2356 | struct extent_io_tree *tree; | 2356 | struct extent_io_tree *tree; |
2357 | int ret; | 2357 | int ret = 0; |
2358 | 2358 | ||
2359 | tree = &BTRFS_I(page->mapping->host)->io_tree; | 2359 | tree = &BTRFS_I(page->mapping->host)->io_tree; |
2360 | 2360 | ||
@@ -5068,6 +5068,43 @@ void read_extent_buffer(struct extent_buffer *eb, void *dstv, | |||
5068 | } | 5068 | } |
5069 | } | 5069 | } |
5070 | 5070 | ||
5071 | int read_extent_buffer_to_user(struct extent_buffer *eb, void __user *dstv, | ||
5072 | unsigned long start, | ||
5073 | unsigned long len) | ||
5074 | { | ||
5075 | size_t cur; | ||
5076 | size_t offset; | ||
5077 | struct page *page; | ||
5078 | char *kaddr; | ||
5079 | char __user *dst = (char __user *)dstv; | ||
5080 | size_t start_offset = eb->start & ((u64)PAGE_CACHE_SIZE - 1); | ||
5081 | unsigned long i = (start_offset + start) >> PAGE_CACHE_SHIFT; | ||
5082 | int ret = 0; | ||
5083 | |||
5084 | WARN_ON(start > eb->len); | ||
5085 | WARN_ON(start + len > eb->start + eb->len); | ||
5086 | |||
5087 | offset = (start_offset + start) & (PAGE_CACHE_SIZE - 1); | ||
5088 | |||
5089 | while (len > 0) { | ||
5090 | page = extent_buffer_page(eb, i); | ||
5091 | |||
5092 | cur = min(len, (PAGE_CACHE_SIZE - offset)); | ||
5093 | kaddr = page_address(page); | ||
5094 | if (copy_to_user(dst, kaddr + offset, cur)) { | ||
5095 | ret = -EFAULT; | ||
5096 | break; | ||
5097 | } | ||
5098 | |||
5099 | dst += cur; | ||
5100 | len -= cur; | ||
5101 | offset = 0; | ||
5102 | i++; | ||
5103 | } | ||
5104 | |||
5105 | return ret; | ||
5106 | } | ||
5107 | |||
5071 | int map_private_extent_buffer(struct extent_buffer *eb, unsigned long start, | 5108 | int map_private_extent_buffer(struct extent_buffer *eb, unsigned long start, |
5072 | unsigned long min_len, char **map, | 5109 | unsigned long min_len, char **map, |
5073 | unsigned long *map_start, | 5110 | unsigned long *map_start, |