mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	btrfs: use bio iterators for the decompression handlers
Pass the full bio to the decompression routines and use bio iterators to iterate over the data in the bio. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
		
							parent
							
								
									0c476a5d7f
								
							
						
					
					
						commit
						974b1adc3b
					
				
					 4 changed files with 56 additions and 113 deletions
				
			
		| 
						 | 
					@ -81,9 +81,9 @@ struct compressed_bio {
 | 
				
			||||||
	u32 sums;
 | 
						u32 sums;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int btrfs_decompress_biovec(int type, struct page **pages_in,
 | 
					static int btrfs_decompress_bio(int type, struct page **pages_in,
 | 
				
			||||||
				   u64 disk_start, struct bio_vec *bvec,
 | 
									   u64 disk_start, struct bio *orig_bio,
 | 
				
			||||||
				   int vcnt, size_t srclen);
 | 
									   size_t srclen);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline int compressed_bio_size(struct btrfs_root *root,
 | 
					static inline int compressed_bio_size(struct btrfs_root *root,
 | 
				
			||||||
				      unsigned long disk_size)
 | 
									      unsigned long disk_size)
 | 
				
			||||||
| 
						 | 
					@ -175,11 +175,10 @@ static void end_compressed_bio_read(struct bio *bio)
 | 
				
			||||||
	/* ok, we're the last bio for this extent, lets start
 | 
						/* ok, we're the last bio for this extent, lets start
 | 
				
			||||||
	 * the decompression.
 | 
						 * the decompression.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	ret = btrfs_decompress_biovec(cb->compress_type,
 | 
						ret = btrfs_decompress_bio(cb->compress_type,
 | 
				
			||||||
				      cb->compressed_pages,
 | 
									      cb->compressed_pages,
 | 
				
			||||||
				      cb->start,
 | 
									      cb->start,
 | 
				
			||||||
				      cb->orig_bio->bi_io_vec,
 | 
									      cb->orig_bio,
 | 
				
			||||||
				      cb->orig_bio->bi_vcnt,
 | 
					 | 
				
			||||||
				      cb->compressed_len);
 | 
									      cb->compressed_len);
 | 
				
			||||||
csum_failed:
 | 
					csum_failed:
 | 
				
			||||||
	if (ret)
 | 
						if (ret)
 | 
				
			||||||
| 
						 | 
					@ -959,9 +958,7 @@ int btrfs_compress_pages(int type, struct address_space *mapping,
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * disk_start is the starting logical offset of this array in the file
 | 
					 * disk_start is the starting logical offset of this array in the file
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * bvec is a bio_vec of pages from the file that we want to decompress into
 | 
					 * orig_bio contains the pages from the file that we want to decompress into
 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * vcnt is the count of pages in the biovec
 | 
					 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * srclen is the number of bytes in pages_in
 | 
					 * srclen is the number of bytes in pages_in
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
| 
						 | 
					@ -970,18 +967,18 @@ int btrfs_compress_pages(int type, struct address_space *mapping,
 | 
				
			||||||
 * be contiguous.  They all correspond to the range of bytes covered by
 | 
					 * be contiguous.  They all correspond to the range of bytes covered by
 | 
				
			||||||
 * the compressed extent.
 | 
					 * the compressed extent.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static int btrfs_decompress_biovec(int type, struct page **pages_in,
 | 
					static int btrfs_decompress_bio(int type, struct page **pages_in,
 | 
				
			||||||
				   u64 disk_start, struct bio_vec *bvec,
 | 
									   u64 disk_start, struct bio *orig_bio,
 | 
				
			||||||
				   int vcnt, size_t srclen)
 | 
									   size_t srclen)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct list_head *workspace;
 | 
						struct list_head *workspace;
 | 
				
			||||||
	int ret;
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	workspace = find_workspace(type);
 | 
						workspace = find_workspace(type);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ret = btrfs_compress_op[type-1]->decompress_biovec(workspace, pages_in,
 | 
						ret = btrfs_compress_op[type-1]->decompress_bio(workspace, pages_in,
 | 
				
			||||||
							 disk_start,
 | 
												 disk_start, orig_bio,
 | 
				
			||||||
							 bvec, vcnt, srclen);
 | 
												 srclen);
 | 
				
			||||||
	free_workspace(type, workspace);
 | 
						free_workspace(type, workspace);
 | 
				
			||||||
	return ret;
 | 
						return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1021,9 +1018,7 @@ void btrfs_exit_compress(void)
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
int btrfs_decompress_buf2page(char *buf, unsigned long buf_start,
 | 
					int btrfs_decompress_buf2page(char *buf, unsigned long buf_start,
 | 
				
			||||||
			      unsigned long total_out, u64 disk_start,
 | 
								      unsigned long total_out, u64 disk_start,
 | 
				
			||||||
			      struct bio_vec *bvec, int vcnt,
 | 
								      struct bio *bio)
 | 
				
			||||||
			      unsigned long *pg_index,
 | 
					 | 
				
			||||||
			      unsigned long *pg_offset)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	unsigned long buf_offset;
 | 
						unsigned long buf_offset;
 | 
				
			||||||
	unsigned long current_buf_start;
 | 
						unsigned long current_buf_start;
 | 
				
			||||||
| 
						 | 
					@ -1031,13 +1026,13 @@ int btrfs_decompress_buf2page(char *buf, unsigned long buf_start,
 | 
				
			||||||
	unsigned long working_bytes = total_out - buf_start;
 | 
						unsigned long working_bytes = total_out - buf_start;
 | 
				
			||||||
	unsigned long bytes;
 | 
						unsigned long bytes;
 | 
				
			||||||
	char *kaddr;
 | 
						char *kaddr;
 | 
				
			||||||
	struct page *page_out = bvec[*pg_index].bv_page;
 | 
						struct bio_vec bvec = bio_iter_iovec(bio, bio->bi_iter);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * start byte is the first byte of the page we're currently
 | 
						 * start byte is the first byte of the page we're currently
 | 
				
			||||||
	 * copying into relative to the start of the compressed data.
 | 
						 * copying into relative to the start of the compressed data.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	start_byte = page_offset(page_out) - disk_start;
 | 
						start_byte = page_offset(bvec.bv_page) - disk_start;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* we haven't yet hit data corresponding to this page */
 | 
						/* we haven't yet hit data corresponding to this page */
 | 
				
			||||||
	if (total_out <= start_byte)
 | 
						if (total_out <= start_byte)
 | 
				
			||||||
| 
						 | 
					@ -1057,80 +1052,46 @@ int btrfs_decompress_buf2page(char *buf, unsigned long buf_start,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* copy bytes from the working buffer into the pages */
 | 
						/* copy bytes from the working buffer into the pages */
 | 
				
			||||||
	while (working_bytes > 0) {
 | 
						while (working_bytes > 0) {
 | 
				
			||||||
		bytes = min(PAGE_SIZE - *pg_offset,
 | 
							bytes = min_t(unsigned long, bvec.bv_len,
 | 
				
			||||||
			    PAGE_SIZE - buf_offset);
 | 
									PAGE_SIZE - buf_offset);
 | 
				
			||||||
		bytes = min(bytes, working_bytes);
 | 
							bytes = min(bytes, working_bytes);
 | 
				
			||||||
		kaddr = kmap_atomic(page_out);
 | 
					 | 
				
			||||||
		memcpy(kaddr + *pg_offset, buf + buf_offset, bytes);
 | 
					 | 
				
			||||||
		kunmap_atomic(kaddr);
 | 
					 | 
				
			||||||
		flush_dcache_page(page_out);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		*pg_offset += bytes;
 | 
							kaddr = kmap_atomic(bvec.bv_page);
 | 
				
			||||||
 | 
							memcpy(kaddr + bvec.bv_offset, buf + buf_offset, bytes);
 | 
				
			||||||
 | 
							kunmap_atomic(kaddr);
 | 
				
			||||||
 | 
							flush_dcache_page(bvec.bv_page);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		buf_offset += bytes;
 | 
							buf_offset += bytes;
 | 
				
			||||||
		working_bytes -= bytes;
 | 
							working_bytes -= bytes;
 | 
				
			||||||
		current_buf_start += bytes;
 | 
							current_buf_start += bytes;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* check if we need to pick another page */
 | 
							/* check if we need to pick another page */
 | 
				
			||||||
		if (*pg_offset == PAGE_SIZE) {
 | 
							bio_advance(bio, bytes);
 | 
				
			||||||
			(*pg_index)++;
 | 
							if (!bio->bi_iter.bi_size)
 | 
				
			||||||
			if (*pg_index >= vcnt)
 | 
								return 0;
 | 
				
			||||||
				return 0;
 | 
							bvec = bio_iter_iovec(bio, bio->bi_iter);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			page_out = bvec[*pg_index].bv_page;
 | 
							start_byte = page_offset(bvec.bv_page) - disk_start;
 | 
				
			||||||
			*pg_offset = 0;
 | 
					 | 
				
			||||||
			start_byte = page_offset(page_out) - disk_start;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
			/*
 | 
							/*
 | 
				
			||||||
			 * make sure our new page is covered by this
 | 
							 * make sure our new page is covered by this
 | 
				
			||||||
			 * working buffer
 | 
							 * working buffer
 | 
				
			||||||
			 */
 | 
							 */
 | 
				
			||||||
			if (total_out <= start_byte)
 | 
							if (total_out <= start_byte)
 | 
				
			||||||
				return 1;
 | 
								return 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			/*
 | 
							/*
 | 
				
			||||||
			 * the next page in the biovec might not be adjacent
 | 
							 * the next page in the biovec might not be adjacent
 | 
				
			||||||
			 * to the last page, but it might still be found
 | 
							 * to the last page, but it might still be found
 | 
				
			||||||
			 * inside this working buffer. bump our offset pointer
 | 
							 * inside this working buffer. bump our offset pointer
 | 
				
			||||||
			 */
 | 
							 */
 | 
				
			||||||
			if (total_out > start_byte &&
 | 
							if (total_out > start_byte &&
 | 
				
			||||||
			    current_buf_start < start_byte) {
 | 
							    current_buf_start < start_byte) {
 | 
				
			||||||
				buf_offset = start_byte - buf_start;
 | 
								buf_offset = start_byte - buf_start;
 | 
				
			||||||
				working_bytes = total_out - start_byte;
 | 
								working_bytes = total_out - start_byte;
 | 
				
			||||||
				current_buf_start = buf_start + buf_offset;
 | 
								current_buf_start = buf_start + buf_offset;
 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 1;
 | 
						return 1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * When uncompressing data, we need to make sure and zero any parts of
 | 
					 | 
				
			||||||
 * the biovec that were not filled in by the decompression code.  pg_index
 | 
					 | 
				
			||||||
 * and pg_offset indicate the last page and the last offset of that page
 | 
					 | 
				
			||||||
 * that have been filled in.  This will zero everything remaining in the
 | 
					 | 
				
			||||||
 * biovec.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
void btrfs_clear_biovec_end(struct bio_vec *bvec, int vcnt,
 | 
					 | 
				
			||||||
				   unsigned long pg_index,
 | 
					 | 
				
			||||||
				   unsigned long pg_offset)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	while (pg_index < vcnt) {
 | 
					 | 
				
			||||||
		struct page *page = bvec[pg_index].bv_page;
 | 
					 | 
				
			||||||
		unsigned long off = bvec[pg_index].bv_offset;
 | 
					 | 
				
			||||||
		unsigned long len = bvec[pg_index].bv_len;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (pg_offset < off)
 | 
					 | 
				
			||||||
			pg_offset = off;
 | 
					 | 
				
			||||||
		if (pg_offset < off + len) {
 | 
					 | 
				
			||||||
			unsigned long bytes = off + len - pg_offset;
 | 
					 | 
				
			||||||
			char *kaddr;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			kaddr = kmap_atomic(page);
 | 
					 | 
				
			||||||
			memset(kaddr + pg_offset, 0, bytes);
 | 
					 | 
				
			||||||
			kunmap_atomic(kaddr);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		pg_index++;
 | 
					 | 
				
			||||||
		pg_offset = 0;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -34,9 +34,7 @@ int btrfs_decompress(int type, unsigned char *data_in, struct page *dest_page,
 | 
				
			||||||
		     unsigned long start_byte, size_t srclen, size_t destlen);
 | 
							     unsigned long start_byte, size_t srclen, size_t destlen);
 | 
				
			||||||
int btrfs_decompress_buf2page(char *buf, unsigned long buf_start,
 | 
					int btrfs_decompress_buf2page(char *buf, unsigned long buf_start,
 | 
				
			||||||
			      unsigned long total_out, u64 disk_start,
 | 
								      unsigned long total_out, u64 disk_start,
 | 
				
			||||||
			      struct bio_vec *bvec, int vcnt,
 | 
								      struct bio *bio);
 | 
				
			||||||
			      unsigned long *pg_index,
 | 
					 | 
				
			||||||
			      unsigned long *pg_offset);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
int btrfs_submit_compressed_write(struct inode *inode, u64 start,
 | 
					int btrfs_submit_compressed_write(struct inode *inode, u64 start,
 | 
				
			||||||
				  unsigned long len, u64 disk_start,
 | 
									  unsigned long len, u64 disk_start,
 | 
				
			||||||
| 
						 | 
					@ -45,9 +43,6 @@ int btrfs_submit_compressed_write(struct inode *inode, u64 start,
 | 
				
			||||||
				  unsigned long nr_pages);
 | 
									  unsigned long nr_pages);
 | 
				
			||||||
int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio,
 | 
					int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio,
 | 
				
			||||||
				 int mirror_num, unsigned long bio_flags);
 | 
									 int mirror_num, unsigned long bio_flags);
 | 
				
			||||||
void btrfs_clear_biovec_end(struct bio_vec *bvec, int vcnt,
 | 
					 | 
				
			||||||
				   unsigned long pg_index,
 | 
					 | 
				
			||||||
				   unsigned long pg_offset);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum btrfs_compression_type {
 | 
					enum btrfs_compression_type {
 | 
				
			||||||
	BTRFS_COMPRESS_NONE  = 0,
 | 
						BTRFS_COMPRESS_NONE  = 0,
 | 
				
			||||||
| 
						 | 
					@ -72,11 +67,10 @@ struct btrfs_compress_op {
 | 
				
			||||||
			      unsigned long *total_out,
 | 
								      unsigned long *total_out,
 | 
				
			||||||
			      unsigned long max_out);
 | 
								      unsigned long max_out);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	int (*decompress_biovec)(struct list_head *workspace,
 | 
						int (*decompress_bio)(struct list_head *workspace,
 | 
				
			||||||
				 struct page **pages_in,
 | 
									 struct page **pages_in,
 | 
				
			||||||
				 u64 disk_start,
 | 
									 u64 disk_start,
 | 
				
			||||||
				 struct bio_vec *bvec,
 | 
									 struct bio *orig_bio,
 | 
				
			||||||
				 int vcnt,
 | 
					 | 
				
			||||||
				 size_t srclen);
 | 
									 size_t srclen);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	int (*decompress)(struct list_head *workspace,
 | 
						int (*decompress)(struct list_head *workspace,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -254,25 +254,21 @@ static int lzo_compress_pages(struct list_head *ws,
 | 
				
			||||||
	return ret;
 | 
						return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int lzo_decompress_biovec(struct list_head *ws,
 | 
					static int lzo_decompress_bio(struct list_head *ws,
 | 
				
			||||||
				 struct page **pages_in,
 | 
									 struct page **pages_in,
 | 
				
			||||||
				 u64 disk_start,
 | 
									 u64 disk_start,
 | 
				
			||||||
				 struct bio_vec *bvec,
 | 
									 struct bio *orig_bio,
 | 
				
			||||||
				 int vcnt,
 | 
					 | 
				
			||||||
				 size_t srclen)
 | 
									 size_t srclen)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct workspace *workspace = list_entry(ws, struct workspace, list);
 | 
						struct workspace *workspace = list_entry(ws, struct workspace, list);
 | 
				
			||||||
	int ret = 0, ret2;
 | 
						int ret = 0, ret2;
 | 
				
			||||||
	char *data_in;
 | 
						char *data_in;
 | 
				
			||||||
	unsigned long page_in_index = 0;
 | 
						unsigned long page_in_index = 0;
 | 
				
			||||||
	unsigned long page_out_index = 0;
 | 
					 | 
				
			||||||
	unsigned long total_pages_in = DIV_ROUND_UP(srclen, PAGE_SIZE);
 | 
						unsigned long total_pages_in = DIV_ROUND_UP(srclen, PAGE_SIZE);
 | 
				
			||||||
	unsigned long buf_start;
 | 
						unsigned long buf_start;
 | 
				
			||||||
	unsigned long buf_offset = 0;
 | 
						unsigned long buf_offset = 0;
 | 
				
			||||||
	unsigned long bytes;
 | 
						unsigned long bytes;
 | 
				
			||||||
	unsigned long working_bytes;
 | 
						unsigned long working_bytes;
 | 
				
			||||||
	unsigned long pg_offset;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	size_t in_len;
 | 
						size_t in_len;
 | 
				
			||||||
	size_t out_len;
 | 
						size_t out_len;
 | 
				
			||||||
	unsigned long in_offset;
 | 
						unsigned long in_offset;
 | 
				
			||||||
| 
						 | 
					@ -292,7 +288,6 @@ static int lzo_decompress_biovec(struct list_head *ws,
 | 
				
			||||||
	in_page_bytes_left = PAGE_SIZE - LZO_LEN;
 | 
						in_page_bytes_left = PAGE_SIZE - LZO_LEN;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	tot_out = 0;
 | 
						tot_out = 0;
 | 
				
			||||||
	pg_offset = 0;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	while (tot_in < tot_len) {
 | 
						while (tot_in < tot_len) {
 | 
				
			||||||
		in_len = read_compress_length(data_in + in_offset);
 | 
							in_len = read_compress_length(data_in + in_offset);
 | 
				
			||||||
| 
						 | 
					@ -365,16 +360,14 @@ static int lzo_decompress_biovec(struct list_head *ws,
 | 
				
			||||||
		tot_out += out_len;
 | 
							tot_out += out_len;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		ret2 = btrfs_decompress_buf2page(workspace->buf, buf_start,
 | 
							ret2 = btrfs_decompress_buf2page(workspace->buf, buf_start,
 | 
				
			||||||
						 tot_out, disk_start,
 | 
											 tot_out, disk_start, orig_bio);
 | 
				
			||||||
						 bvec, vcnt,
 | 
					 | 
				
			||||||
						 &page_out_index, &pg_offset);
 | 
					 | 
				
			||||||
		if (ret2 == 0)
 | 
							if (ret2 == 0)
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
done:
 | 
					done:
 | 
				
			||||||
	kunmap(pages_in[page_in_index]);
 | 
						kunmap(pages_in[page_in_index]);
 | 
				
			||||||
	if (!ret)
 | 
						if (!ret)
 | 
				
			||||||
		btrfs_clear_biovec_end(bvec, vcnt, page_out_index, pg_offset);
 | 
							zero_fill_bio(orig_bio);
 | 
				
			||||||
	return ret;
 | 
						return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -438,6 +431,6 @@ const struct btrfs_compress_op btrfs_lzo_compress = {
 | 
				
			||||||
	.alloc_workspace	= lzo_alloc_workspace,
 | 
						.alloc_workspace	= lzo_alloc_workspace,
 | 
				
			||||||
	.free_workspace		= lzo_free_workspace,
 | 
						.free_workspace		= lzo_free_workspace,
 | 
				
			||||||
	.compress_pages		= lzo_compress_pages,
 | 
						.compress_pages		= lzo_compress_pages,
 | 
				
			||||||
	.decompress_biovec	= lzo_decompress_biovec,
 | 
						.decompress_bio		= lzo_decompress_bio,
 | 
				
			||||||
	.decompress		= lzo_decompress,
 | 
						.decompress		= lzo_decompress,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -210,10 +210,9 @@ static int zlib_compress_pages(struct list_head *ws,
 | 
				
			||||||
	return ret;
 | 
						return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int zlib_decompress_biovec(struct list_head *ws, struct page **pages_in,
 | 
					static int zlib_decompress_bio(struct list_head *ws, struct page **pages_in,
 | 
				
			||||||
				  u64 disk_start,
 | 
									  u64 disk_start,
 | 
				
			||||||
				  struct bio_vec *bvec,
 | 
									  struct bio *orig_bio,
 | 
				
			||||||
				  int vcnt,
 | 
					 | 
				
			||||||
				  size_t srclen)
 | 
									  size_t srclen)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct workspace *workspace = list_entry(ws, struct workspace, list);
 | 
						struct workspace *workspace = list_entry(ws, struct workspace, list);
 | 
				
			||||||
| 
						 | 
					@ -222,10 +221,8 @@ static int zlib_decompress_biovec(struct list_head *ws, struct page **pages_in,
 | 
				
			||||||
	char *data_in;
 | 
						char *data_in;
 | 
				
			||||||
	size_t total_out = 0;
 | 
						size_t total_out = 0;
 | 
				
			||||||
	unsigned long page_in_index = 0;
 | 
						unsigned long page_in_index = 0;
 | 
				
			||||||
	unsigned long page_out_index = 0;
 | 
					 | 
				
			||||||
	unsigned long total_pages_in = DIV_ROUND_UP(srclen, PAGE_SIZE);
 | 
						unsigned long total_pages_in = DIV_ROUND_UP(srclen, PAGE_SIZE);
 | 
				
			||||||
	unsigned long buf_start;
 | 
						unsigned long buf_start;
 | 
				
			||||||
	unsigned long pg_offset;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	data_in = kmap(pages_in[page_in_index]);
 | 
						data_in = kmap(pages_in[page_in_index]);
 | 
				
			||||||
	workspace->strm.next_in = data_in;
 | 
						workspace->strm.next_in = data_in;
 | 
				
			||||||
| 
						 | 
					@ -235,7 +232,6 @@ static int zlib_decompress_biovec(struct list_head *ws, struct page **pages_in,
 | 
				
			||||||
	workspace->strm.total_out = 0;
 | 
						workspace->strm.total_out = 0;
 | 
				
			||||||
	workspace->strm.next_out = workspace->buf;
 | 
						workspace->strm.next_out = workspace->buf;
 | 
				
			||||||
	workspace->strm.avail_out = PAGE_SIZE;
 | 
						workspace->strm.avail_out = PAGE_SIZE;
 | 
				
			||||||
	pg_offset = 0;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* If it's deflate, and it's got no preset dictionary, then
 | 
						/* If it's deflate, and it's got no preset dictionary, then
 | 
				
			||||||
	   we can tell zlib to skip the adler32 check. */
 | 
						   we can tell zlib to skip the adler32 check. */
 | 
				
			||||||
| 
						 | 
					@ -267,8 +263,7 @@ static int zlib_decompress_biovec(struct list_head *ws, struct page **pages_in,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		ret2 = btrfs_decompress_buf2page(workspace->buf, buf_start,
 | 
							ret2 = btrfs_decompress_buf2page(workspace->buf, buf_start,
 | 
				
			||||||
						 total_out, disk_start,
 | 
											 total_out, disk_start,
 | 
				
			||||||
						 bvec, vcnt,
 | 
											 orig_bio);
 | 
				
			||||||
						 &page_out_index, &pg_offset);
 | 
					 | 
				
			||||||
		if (ret2 == 0) {
 | 
							if (ret2 == 0) {
 | 
				
			||||||
			ret = 0;
 | 
								ret = 0;
 | 
				
			||||||
			goto done;
 | 
								goto done;
 | 
				
			||||||
| 
						 | 
					@ -301,7 +296,7 @@ static int zlib_decompress_biovec(struct list_head *ws, struct page **pages_in,
 | 
				
			||||||
	if (data_in)
 | 
						if (data_in)
 | 
				
			||||||
		kunmap(pages_in[page_in_index]);
 | 
							kunmap(pages_in[page_in_index]);
 | 
				
			||||||
	if (!ret)
 | 
						if (!ret)
 | 
				
			||||||
		btrfs_clear_biovec_end(bvec, vcnt, page_out_index, pg_offset);
 | 
							zero_fill_bio(orig_bio);
 | 
				
			||||||
	return ret;
 | 
						return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -408,6 +403,6 @@ const struct btrfs_compress_op btrfs_zlib_compress = {
 | 
				
			||||||
	.alloc_workspace	= zlib_alloc_workspace,
 | 
						.alloc_workspace	= zlib_alloc_workspace,
 | 
				
			||||||
	.free_workspace		= zlib_free_workspace,
 | 
						.free_workspace		= zlib_free_workspace,
 | 
				
			||||||
	.compress_pages		= zlib_compress_pages,
 | 
						.compress_pages		= zlib_compress_pages,
 | 
				
			||||||
	.decompress_biovec	= zlib_decompress_biovec,
 | 
						.decompress_bio		= zlib_decompress_bio,
 | 
				
			||||||
	.decompress		= zlib_decompress,
 | 
						.decompress		= zlib_decompress,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue