Re: [PATCH v6 03/15] btrfs: rework btrfs_decompress_buf2page()
From: David Sterba <hidden>
Date: 2021-07-09 19:28:58
On Mon, Jul 05, 2021 at 10:00:58AM +0800, Qu Wenruo wrote:
+int btrfs_decompress_buf2page(const char *buf, u32 buf_len,
+ struct compressed_bio *cb, u32 decompressed)
{
- unsigned long buf_offset;
- unsigned long current_buf_start;
- unsigned long start_byte;
- unsigned long prev_start_byte;
- unsigned long working_bytes = total_out - buf_start;
- unsigned long bytes;
- struct bio_vec bvec = bio_iter_iovec(bio, bio->bi_iter);
-
- /*
- * start byte is the first byte of the page we're currently
- * copying into relative to the start of the compressed data.
- */
- start_byte = page_offset(bvec.bv_page) - disk_start;
-
- /* we haven't yet hit data corresponding to this page */
- if (total_out <= start_byte)
- return 1;
+ struct bio *orig_bio = cb->orig_bio;
+ u32 cur_offset; /* Offset inside the full decompressed extent */
- /*
- * the start of the data we care about is offset into
- * the middle of our working buffer
- */
- if (total_out > start_byte && buf_start < start_byte) {
- buf_offset = start_byte - buf_start;
- working_bytes -= buf_offset;
- } else {
- buf_offset = 0;
- }
- current_buf_start = buf_start;
+ cur_offset = decompressed;
+ /* The main loop to do the copy */
+ while (cur_offset < decompressed + buf_len) {
+ struct bio_vec bvec = bio_iter_iovec(orig_bio,
+ orig_bio->bi_iter);
+ size_t copy_len;
+ u32 copy_start;
+ u32 bvec_offset; /* Offset inside the full decompressed extent */
- /* copy bytes from the working buffer into the pages */
- while (working_bytes > 0) {
- bytes = min_t(unsigned long, bvec.bv_len,
- PAGE_SIZE - (buf_offset % PAGE_SIZE));
- bytes = min(bytes, working_bytes);
+ bvec = bio_iter_iovec(orig_bio, orig_bio->bi_iter);Looks like a duplicate initialization, the same is in the delcaration, I'll keep the first one as it's a simple struct init.
- memcpy_to_page(bvec.bv_page, bvec.bv_offset, buf + buf_offset, - bytes); - flush_dcache_page(bvec.bv_page); + /* + * cb->start may underflow, but minusing that value can still + * give us correct offset inside the full decompressed extent. + */ + bvec_offset = page_offset(bvec.bv_page) + bvec.bv_offset + - cb->start;