Loading fs/btrfs/check-integrity.c +12 −20 Original line number Diff line number Diff line Loading @@ -1539,7 +1539,7 @@ static int btrfsic_map_block(struct btrfsic_state *state, u64 bytenr, u32 len, struct btrfs_device *device; length = len; ret = btrfs_map_block(state->root->fs_info, READ, ret = btrfs_map_block(state->root->fs_info, BTRFS_MAP_READ, bytenr, &length, &multi, mirror_num); if (ret) { Loading Loading @@ -2819,10 +2819,11 @@ static void __btrfsic_submit_bio(struct bio *bio) * btrfsic_mount(), this might return NULL */ dev_state = btrfsic_dev_state_lookup(bio->bi_bdev); if (NULL != dev_state && (bio_op(bio) == REQ_OP_WRITE) && NULL != bio->bi_io_vec) { (bio_op(bio) == REQ_OP_WRITE) && bio_has_data(bio)) { unsigned int i; u64 dev_bytenr; u64 cur_bytenr; struct bio_vec *bvec; int bio_is_patched; char **mapped_datav; Loading @@ -2840,32 +2841,23 @@ static void __btrfsic_submit_bio(struct bio *bio) if (!mapped_datav) goto leave; cur_bytenr = dev_bytenr; for (i = 0; i < bio->bi_vcnt; i++) { BUG_ON(bio->bi_io_vec[i].bv_len != PAGE_SIZE); mapped_datav[i] = kmap(bio->bi_io_vec[i].bv_page); if (!mapped_datav[i]) { while (i > 0) { i--; kunmap(bio->bi_io_vec[i].bv_page); } kfree(mapped_datav); goto leave; } bio_for_each_segment_all(bvec, bio, i) { BUG_ON(bvec->bv_len != PAGE_SIZE); mapped_datav[i] = kmap(bvec->bv_page); if (dev_state->state->print_mask & BTRFSIC_PRINT_MASK_SUBMIT_BIO_BH_VERBOSE) pr_info("#%u: bytenr=%llu, len=%u, offset=%u\n", i, cur_bytenr, bio->bi_io_vec[i].bv_len, bio->bi_io_vec[i].bv_offset); cur_bytenr += bio->bi_io_vec[i].bv_len; i, cur_bytenr, bvec->bv_len, bvec->bv_offset); cur_bytenr += bvec->bv_len; } btrfsic_process_written_block(dev_state, dev_bytenr, mapped_datav, bio->bi_vcnt, bio, &bio_is_patched, NULL, bio->bi_opf); while (i > 0) { i--; kunmap(bio->bi_io_vec[i].bv_page); } bio_for_each_segment_all(bvec, bio, i) kunmap(bvec->bv_page); kfree(mapped_datav); } else if (NULL != dev_state && (bio->bi_opf & REQ_PREFLUSH)) { if (dev_state->state->print_mask & Loading fs/btrfs/compression.c +53 −89 Original line number Diff line number Diff line Loading @@ -81,9 +81,9 @@ struct compressed_bio { u32 sums; }; static int btrfs_decompress_biovec(int type, struct page **pages_in, u64 disk_start, struct bio_vec *bvec, int vcnt, size_t srclen); static int btrfs_decompress_bio(int type, struct page **pages_in, u64 disk_start, struct bio *orig_bio, size_t srclen); static inline int compressed_bio_size(struct btrfs_root *root, unsigned long disk_size) Loading Loading @@ -120,7 +120,7 @@ static int check_compressed_csum(struct inode *inode, kaddr = kmap_atomic(page); csum = btrfs_csum_data(kaddr, csum, PAGE_SIZE); btrfs_csum_final(csum, (char *)&csum); btrfs_csum_final(csum, (u8 *)&csum); kunmap_atomic(kaddr); if (csum != *cb_sum) { Loading Loading @@ -175,11 +175,10 @@ static void end_compressed_bio_read(struct bio *bio) /* ok, we're the last bio for this extent, lets start * the decompression. */ ret = btrfs_decompress_biovec(cb->compress_type, ret = btrfs_decompress_bio(cb->compress_type, cb->compressed_pages, cb->start, cb->orig_bio->bi_io_vec, cb->orig_bio->bi_vcnt, cb->orig_bio, cb->compressed_len); csum_failed: if (ret) Loading Loading @@ -446,6 +445,13 @@ int btrfs_submit_compressed_write(struct inode *inode, u64 start, return 0; } static u64 bio_end_offset(struct bio *bio) { struct bio_vec *last = &bio->bi_io_vec[bio->bi_vcnt - 1]; return page_offset(last->bv_page) + last->bv_len + last->bv_offset; } static noinline int add_ra_bio_pages(struct inode *inode, u64 compressed_end, struct compressed_bio *cb) Loading @@ -464,8 +470,7 @@ static noinline int add_ra_bio_pages(struct inode *inode, u64 end; int misses = 0; page = cb->orig_bio->bi_io_vec[cb->orig_bio->bi_vcnt - 1].bv_page; last_offset = (page_offset(page) + PAGE_SIZE); last_offset = bio_end_offset(cb->orig_bio); em_tree = &BTRFS_I(inode)->extent_tree; tree = &BTRFS_I(inode)->io_tree; Loading Loading @@ -563,7 +568,6 @@ static noinline int add_ra_bio_pages(struct inode *inode, * * bio->bi_iter.bi_sector points to the compressed extent on disk * bio->bi_io_vec points to all of the inode pages * bio->bi_vcnt is a count of pages * * After the compressed pages are read, we copy the bytes into the * bio we were passed and then call the bio end_io calls Loading @@ -575,7 +579,6 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio, struct extent_map_tree *em_tree; struct compressed_bio *cb; struct btrfs_root *root = BTRFS_I(inode)->root; unsigned long uncompressed_len = bio->bi_vcnt * PAGE_SIZE; unsigned long compressed_len; unsigned long nr_pages; unsigned long pg_index; Loading Loading @@ -620,7 +623,7 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio, free_extent_map(em); em = NULL; cb->len = uncompressed_len; cb->len = bio->bi_iter.bi_size; cb->compressed_len = compressed_len; cb->compress_type = extent_compress_type(bio_flags); cb->orig_bio = bio; Loading Loading @@ -648,8 +651,7 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio, add_ra_bio_pages(inode, em_start + em_len, cb); /* include any pages we added in add_ra-bio_pages */ uncompressed_len = bio->bi_vcnt * PAGE_SIZE; cb->len = uncompressed_len; cb->len = bio->bi_iter.bi_size; comp_bio = compressed_bio_alloc(bdev, cur_disk_byte, GFP_NOFS); if (!comp_bio) Loading Loading @@ -959,9 +961,7 @@ int btrfs_compress_pages(int type, struct address_space *mapping, * * 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 * * vcnt is the count of pages in the biovec * orig_bio contains the pages from the file that we want to decompress into * * srclen is the number of bytes in pages_in * Loading @@ -970,18 +970,18 @@ int btrfs_compress_pages(int type, struct address_space *mapping, * be contiguous. They all correspond to the range of bytes covered by * the compressed extent. */ static int btrfs_decompress_biovec(int type, struct page **pages_in, u64 disk_start, struct bio_vec *bvec, int vcnt, size_t srclen) static int btrfs_decompress_bio(int type, struct page **pages_in, u64 disk_start, struct bio *orig_bio, size_t srclen) { struct list_head *workspace; int ret; workspace = find_workspace(type); ret = btrfs_compress_op[type-1]->decompress_biovec(workspace, pages_in, disk_start, bvec, vcnt, srclen); ret = btrfs_compress_op[type-1]->decompress_bio(workspace, pages_in, disk_start, orig_bio, srclen); free_workspace(type, workspace); return ret; } Loading Loading @@ -1021,9 +1021,7 @@ void btrfs_exit_compress(void) */ int btrfs_decompress_buf2page(char *buf, unsigned long buf_start, unsigned long total_out, u64 disk_start, struct bio_vec *bvec, int vcnt, unsigned long *pg_index, unsigned long *pg_offset) struct bio *bio) { unsigned long buf_offset; unsigned long current_buf_start; Loading @@ -1031,13 +1029,13 @@ int btrfs_decompress_buf2page(char *buf, unsigned long buf_start, unsigned long working_bytes = total_out - buf_start; unsigned long bytes; 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 * 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 */ if (total_out <= start_byte) Loading @@ -1057,28 +1055,26 @@ int btrfs_decompress_buf2page(char *buf, unsigned long buf_start, /* copy bytes from the working buffer into the pages */ while (working_bytes > 0) { bytes = min(PAGE_SIZE - *pg_offset, bytes = min_t(unsigned long, bvec.bv_len, PAGE_SIZE - buf_offset); bytes = min(bytes, working_bytes); kaddr = kmap_atomic(page_out); memcpy(kaddr + *pg_offset, buf + buf_offset, bytes); kaddr = kmap_atomic(bvec.bv_page); memcpy(kaddr + bvec.bv_offset, buf + buf_offset, bytes); kunmap_atomic(kaddr); flush_dcache_page(page_out); flush_dcache_page(bvec.bv_page); *pg_offset += bytes; buf_offset += bytes; working_bytes -= bytes; current_buf_start += bytes; /* check if we need to pick another page */ if (*pg_offset == PAGE_SIZE) { (*pg_index)++; if (*pg_index >= vcnt) bio_advance(bio, bytes); if (!bio->bi_iter.bi_size) return 0; bvec = bio_iter_iovec(bio, bio->bi_iter); page_out = bvec[*pg_index].bv_page; *pg_offset = 0; start_byte = page_offset(page_out) - disk_start; start_byte = page_offset(bvec.bv_page) - disk_start; /* * make sure our new page is covered by this Loading @@ -1099,38 +1095,6 @@ int btrfs_decompress_buf2page(char *buf, unsigned long buf_start, current_buf_start = buf_start + buf_offset; } } } 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; } } fs/btrfs/compression.h +3 −9 Original line number Diff line number Diff line Loading @@ -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); int btrfs_decompress_buf2page(char *buf, unsigned long buf_start, unsigned long total_out, u64 disk_start, struct bio_vec *bvec, int vcnt, unsigned long *pg_index, unsigned long *pg_offset); struct bio *bio); int btrfs_submit_compressed_write(struct inode *inode, u64 start, unsigned long len, u64 disk_start, Loading @@ -45,9 +43,6 @@ int btrfs_submit_compressed_write(struct inode *inode, u64 start, unsigned long nr_pages); int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio, 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 { BTRFS_COMPRESS_NONE = 0, Loading @@ -72,11 +67,10 @@ struct btrfs_compress_op { unsigned long *total_out, unsigned long max_out); int (*decompress_biovec)(struct list_head *workspace, int (*decompress_bio)(struct list_head *workspace, struct page **pages_in, u64 disk_start, struct bio_vec *bvec, int vcnt, struct bio *orig_bio, size_t srclen); int (*decompress)(struct list_head *workspace, Loading fs/btrfs/ctree.c +19 −30 Original line number Diff line number Diff line Loading @@ -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); Loading @@ -271,8 +271,7 @@ int btrfs_copy_root(struct btrfs_trans_handle *trans, else btrfs_set_header_owner(cow, new_root_objectid); write_extent_buffer(cow, root->fs_info->fsid, btrfs_header_fsid(), BTRFS_FSID_SIZE); write_extent_buffer_fsid(cow, root->fs_info->fsid); WARN_ON(btrfs_header_generation(buf) > trans->transid); if (new_root_objectid == BTRFS_TREE_RELOC_OBJECTID) Loading Loading @@ -1130,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); Loading @@ -1141,8 +1140,7 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans, else btrfs_set_header_owner(cow, root->root_key.objectid); write_extent_buffer(cow, root->fs_info->fsid, btrfs_header_fsid(), BTRFS_FSID_SIZE); write_extent_buffer_fsid(cow, root->fs_info->fsid); ret = update_ref_for_cow(trans, root, buf, cow, &last_ref); if (ret) { Loading Loading @@ -1670,7 +1668,7 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans, continue; } cur = btrfs_find_tree_block(root->fs_info, blocknr); cur = find_extent_buffer(root->fs_info, blocknr); if (cur) uptodate = btrfs_buffer_uptodate(cur, gen, 0); else Loading Loading @@ -2255,7 +2253,7 @@ static void reada_for_search(struct btrfs_root *root, search = btrfs_node_blockptr(node, slot); blocksize = root->nodesize; eb = btrfs_find_tree_block(root->fs_info, search); eb = find_extent_buffer(root->fs_info, search); if (eb) { free_extent_buffer(eb); return; Loading Loading @@ -2314,7 +2312,7 @@ static noinline void reada_for_balance(struct btrfs_root *root, if (slot > 0) { block1 = btrfs_node_blockptr(parent, slot - 1); gen = btrfs_node_ptr_generation(parent, slot - 1); eb = btrfs_find_tree_block(root->fs_info, block1); eb = find_extent_buffer(root->fs_info, block1); /* * if we get -eagain from btrfs_buffer_uptodate, we * don't want to return eagain here. That will loop Loading @@ -2327,7 +2325,7 @@ static noinline void reada_for_balance(struct btrfs_root *root, if (slot + 1 < nritems) { block2 = btrfs_node_blockptr(parent, slot + 1); gen = btrfs_node_ptr_generation(parent, slot + 1); eb = btrfs_find_tree_block(root->fs_info, block2); eb = find_extent_buffer(root->fs_info, block2); if (eb && btrfs_buffer_uptodate(eb, gen, 1) != 0) block2 = 0; free_extent_buffer(eb); Loading Loading @@ -2445,7 +2443,7 @@ read_block_for_search(struct btrfs_trans_handle *trans, blocknr = btrfs_node_blockptr(b, slot); gen = btrfs_node_ptr_generation(b, slot); tmp = btrfs_find_tree_block(root->fs_info, blocknr); tmp = find_extent_buffer(root->fs_info, blocknr); if (tmp) { /* first we do an atomic uptodate check */ if (btrfs_buffer_uptodate(tmp, gen, 1) > 0) { Loading Loading @@ -3350,7 +3348,7 @@ static noinline int insert_new_root(struct btrfs_trans_handle *trans, root_add_used(root, root->nodesize); memset_extent_buffer(c, 0, 0, sizeof(struct btrfs_header)); memzero_extent_buffer(c, 0, sizeof(struct btrfs_header)); btrfs_set_header_nritems(c, 1); btrfs_set_header_level(c, level); btrfs_set_header_bytenr(c, c->start); Loading @@ -3358,11 +3356,8 @@ static noinline int insert_new_root(struct btrfs_trans_handle *trans, btrfs_set_header_backref_rev(c, BTRFS_MIXED_BACKREF_REV); btrfs_set_header_owner(c, root->root_key.objectid); write_extent_buffer(c, root->fs_info->fsid, btrfs_header_fsid(), BTRFS_FSID_SIZE); write_extent_buffer(c, root->fs_info->chunk_tree_uuid, btrfs_header_chunk_tree_uuid(c), BTRFS_UUID_SIZE); write_extent_buffer_fsid(c, root->fs_info->fsid); write_extent_buffer_chunk_tree_uuid(c, root->fs_info->chunk_tree_uuid); btrfs_set_node_key(c, &lower_key, 0); btrfs_set_node_blockptr(c, 0, lower->start); Loading Loading @@ -3489,17 +3484,15 @@ static noinline int split_node(struct btrfs_trans_handle *trans, root_add_used(root, root->nodesize); memset_extent_buffer(split, 0, 0, sizeof(struct btrfs_header)); memzero_extent_buffer(split, 0, sizeof(struct btrfs_header)); btrfs_set_header_level(split, btrfs_header_level(c)); btrfs_set_header_bytenr(split, split->start); btrfs_set_header_generation(split, trans->transid); btrfs_set_header_backref_rev(split, BTRFS_MIXED_BACKREF_REV); btrfs_set_header_owner(split, root->root_key.objectid); write_extent_buffer(split, root->fs_info->fsid, btrfs_header_fsid(), BTRFS_FSID_SIZE); write_extent_buffer(split, root->fs_info->chunk_tree_uuid, btrfs_header_chunk_tree_uuid(split), BTRFS_UUID_SIZE); write_extent_buffer_fsid(split, root->fs_info->fsid); write_extent_buffer_chunk_tree_uuid(split, root->fs_info->chunk_tree_uuid); ret = tree_mod_log_eb_copy(root->fs_info, split, c, 0, mid, c_nritems - mid); Loading Loading @@ -4277,18 +4270,14 @@ static noinline int split_leaf(struct btrfs_trans_handle *trans, root_add_used(root, root->nodesize); memset_extent_buffer(right, 0, 0, sizeof(struct btrfs_header)); memzero_extent_buffer(right, 0, sizeof(struct btrfs_header)); btrfs_set_header_bytenr(right, right->start); btrfs_set_header_generation(right, trans->transid); btrfs_set_header_backref_rev(right, BTRFS_MIXED_BACKREF_REV); btrfs_set_header_owner(right, root->root_key.objectid); btrfs_set_header_level(right, 0); write_extent_buffer(right, fs_info->fsid, btrfs_header_fsid(), BTRFS_FSID_SIZE); write_extent_buffer(right, fs_info->chunk_tree_uuid, btrfs_header_chunk_tree_uuid(right), BTRFS_UUID_SIZE); write_extent_buffer_fsid(right, fs_info->fsid); write_extent_buffer_chunk_tree_uuid(right, fs_info->chunk_tree_uuid); if (split == 0) { if (mid <= slot) { Loading fs/btrfs/ctree.h +9 −5 Original line number Diff line number Diff line Loading @@ -90,9 +90,6 @@ static const int btrfs_csum_sizes[] = { 4 }; /* four bytes for CRC32 */ #define BTRFS_EMPTY_DIR_SIZE 0 /* specific to btrfs_map_block(), therefore not in include/linux/blk_types.h */ #define REQ_GET_READ_MIRRORS (1 << 30) /* ioprio of readahead is set to idle */ #define BTRFS_IOPRIO_READA (IOPRIO_PRIO_VALUE(IOPRIO_CLASS_IDLE, 0)) Loading Loading @@ -429,6 +426,10 @@ struct btrfs_space_info { struct list_head ro_bgs; struct list_head priority_tickets; struct list_head tickets; /* * tickets_id just indicates the next ticket will be handled, so note * it's not stored per ticket. */ u64 tickets_id; struct rw_semaphore groups_sem; Loading Loading @@ -798,7 +799,6 @@ struct btrfs_fs_info { spinlock_t super_lock; struct btrfs_super_block *super_copy; struct btrfs_super_block *super_for_commit; struct block_device *__bdev; struct super_block *sb; struct inode *btree_inode; struct backing_dev_info bdi; Loading Loading @@ -2210,6 +2210,8 @@ btrfs_disk_balance_args_to_cpu(struct btrfs_balance_args *cpu, cpu->target = le64_to_cpu(disk->target); cpu->flags = le64_to_cpu(disk->flags); cpu->limit = le64_to_cpu(disk->limit); cpu->stripes_min = le32_to_cpu(disk->stripes_min); cpu->stripes_max = le32_to_cpu(disk->stripes_max); } static inline void Loading @@ -2228,6 +2230,8 @@ btrfs_cpu_balance_args_to_disk(struct btrfs_disk_balance_args *disk, disk->target = cpu_to_le64(cpu->target); disk->flags = cpu_to_le64(cpu->flags); disk->limit = cpu_to_le64(cpu->limit); disk->stripes_min = cpu_to_le32(cpu->stripes_min); disk->stripes_max = cpu_to_le32(cpu->stripes_max); } /* struct btrfs_super_block */ Loading Loading @@ -3660,7 +3664,7 @@ struct reada_control *btrfs_reada_add(struct btrfs_root *root, int btrfs_reada_wait(void *handle); void btrfs_reada_detach(void *handle); int btree_readahead_hook(struct btrfs_fs_info *fs_info, struct extent_buffer *eb, u64 start, int err); struct extent_buffer *eb, int err); static inline int is_fstree(u64 rootid) { Loading Loading
fs/btrfs/check-integrity.c +12 −20 Original line number Diff line number Diff line Loading @@ -1539,7 +1539,7 @@ static int btrfsic_map_block(struct btrfsic_state *state, u64 bytenr, u32 len, struct btrfs_device *device; length = len; ret = btrfs_map_block(state->root->fs_info, READ, ret = btrfs_map_block(state->root->fs_info, BTRFS_MAP_READ, bytenr, &length, &multi, mirror_num); if (ret) { Loading Loading @@ -2819,10 +2819,11 @@ static void __btrfsic_submit_bio(struct bio *bio) * btrfsic_mount(), this might return NULL */ dev_state = btrfsic_dev_state_lookup(bio->bi_bdev); if (NULL != dev_state && (bio_op(bio) == REQ_OP_WRITE) && NULL != bio->bi_io_vec) { (bio_op(bio) == REQ_OP_WRITE) && bio_has_data(bio)) { unsigned int i; u64 dev_bytenr; u64 cur_bytenr; struct bio_vec *bvec; int bio_is_patched; char **mapped_datav; Loading @@ -2840,32 +2841,23 @@ static void __btrfsic_submit_bio(struct bio *bio) if (!mapped_datav) goto leave; cur_bytenr = dev_bytenr; for (i = 0; i < bio->bi_vcnt; i++) { BUG_ON(bio->bi_io_vec[i].bv_len != PAGE_SIZE); mapped_datav[i] = kmap(bio->bi_io_vec[i].bv_page); if (!mapped_datav[i]) { while (i > 0) { i--; kunmap(bio->bi_io_vec[i].bv_page); } kfree(mapped_datav); goto leave; } bio_for_each_segment_all(bvec, bio, i) { BUG_ON(bvec->bv_len != PAGE_SIZE); mapped_datav[i] = kmap(bvec->bv_page); if (dev_state->state->print_mask & BTRFSIC_PRINT_MASK_SUBMIT_BIO_BH_VERBOSE) pr_info("#%u: bytenr=%llu, len=%u, offset=%u\n", i, cur_bytenr, bio->bi_io_vec[i].bv_len, bio->bi_io_vec[i].bv_offset); cur_bytenr += bio->bi_io_vec[i].bv_len; i, cur_bytenr, bvec->bv_len, bvec->bv_offset); cur_bytenr += bvec->bv_len; } btrfsic_process_written_block(dev_state, dev_bytenr, mapped_datav, bio->bi_vcnt, bio, &bio_is_patched, NULL, bio->bi_opf); while (i > 0) { i--; kunmap(bio->bi_io_vec[i].bv_page); } bio_for_each_segment_all(bvec, bio, i) kunmap(bvec->bv_page); kfree(mapped_datav); } else if (NULL != dev_state && (bio->bi_opf & REQ_PREFLUSH)) { if (dev_state->state->print_mask & Loading
fs/btrfs/compression.c +53 −89 Original line number Diff line number Diff line Loading @@ -81,9 +81,9 @@ struct compressed_bio { u32 sums; }; static int btrfs_decompress_biovec(int type, struct page **pages_in, u64 disk_start, struct bio_vec *bvec, int vcnt, size_t srclen); static int btrfs_decompress_bio(int type, struct page **pages_in, u64 disk_start, struct bio *orig_bio, size_t srclen); static inline int compressed_bio_size(struct btrfs_root *root, unsigned long disk_size) Loading Loading @@ -120,7 +120,7 @@ static int check_compressed_csum(struct inode *inode, kaddr = kmap_atomic(page); csum = btrfs_csum_data(kaddr, csum, PAGE_SIZE); btrfs_csum_final(csum, (char *)&csum); btrfs_csum_final(csum, (u8 *)&csum); kunmap_atomic(kaddr); if (csum != *cb_sum) { Loading Loading @@ -175,11 +175,10 @@ static void end_compressed_bio_read(struct bio *bio) /* ok, we're the last bio for this extent, lets start * the decompression. */ ret = btrfs_decompress_biovec(cb->compress_type, ret = btrfs_decompress_bio(cb->compress_type, cb->compressed_pages, cb->start, cb->orig_bio->bi_io_vec, cb->orig_bio->bi_vcnt, cb->orig_bio, cb->compressed_len); csum_failed: if (ret) Loading Loading @@ -446,6 +445,13 @@ int btrfs_submit_compressed_write(struct inode *inode, u64 start, return 0; } static u64 bio_end_offset(struct bio *bio) { struct bio_vec *last = &bio->bi_io_vec[bio->bi_vcnt - 1]; return page_offset(last->bv_page) + last->bv_len + last->bv_offset; } static noinline int add_ra_bio_pages(struct inode *inode, u64 compressed_end, struct compressed_bio *cb) Loading @@ -464,8 +470,7 @@ static noinline int add_ra_bio_pages(struct inode *inode, u64 end; int misses = 0; page = cb->orig_bio->bi_io_vec[cb->orig_bio->bi_vcnt - 1].bv_page; last_offset = (page_offset(page) + PAGE_SIZE); last_offset = bio_end_offset(cb->orig_bio); em_tree = &BTRFS_I(inode)->extent_tree; tree = &BTRFS_I(inode)->io_tree; Loading Loading @@ -563,7 +568,6 @@ static noinline int add_ra_bio_pages(struct inode *inode, * * bio->bi_iter.bi_sector points to the compressed extent on disk * bio->bi_io_vec points to all of the inode pages * bio->bi_vcnt is a count of pages * * After the compressed pages are read, we copy the bytes into the * bio we were passed and then call the bio end_io calls Loading @@ -575,7 +579,6 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio, struct extent_map_tree *em_tree; struct compressed_bio *cb; struct btrfs_root *root = BTRFS_I(inode)->root; unsigned long uncompressed_len = bio->bi_vcnt * PAGE_SIZE; unsigned long compressed_len; unsigned long nr_pages; unsigned long pg_index; Loading Loading @@ -620,7 +623,7 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio, free_extent_map(em); em = NULL; cb->len = uncompressed_len; cb->len = bio->bi_iter.bi_size; cb->compressed_len = compressed_len; cb->compress_type = extent_compress_type(bio_flags); cb->orig_bio = bio; Loading Loading @@ -648,8 +651,7 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio, add_ra_bio_pages(inode, em_start + em_len, cb); /* include any pages we added in add_ra-bio_pages */ uncompressed_len = bio->bi_vcnt * PAGE_SIZE; cb->len = uncompressed_len; cb->len = bio->bi_iter.bi_size; comp_bio = compressed_bio_alloc(bdev, cur_disk_byte, GFP_NOFS); if (!comp_bio) Loading Loading @@ -959,9 +961,7 @@ int btrfs_compress_pages(int type, struct address_space *mapping, * * 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 * * vcnt is the count of pages in the biovec * orig_bio contains the pages from the file that we want to decompress into * * srclen is the number of bytes in pages_in * Loading @@ -970,18 +970,18 @@ int btrfs_compress_pages(int type, struct address_space *mapping, * be contiguous. They all correspond to the range of bytes covered by * the compressed extent. */ static int btrfs_decompress_biovec(int type, struct page **pages_in, u64 disk_start, struct bio_vec *bvec, int vcnt, size_t srclen) static int btrfs_decompress_bio(int type, struct page **pages_in, u64 disk_start, struct bio *orig_bio, size_t srclen) { struct list_head *workspace; int ret; workspace = find_workspace(type); ret = btrfs_compress_op[type-1]->decompress_biovec(workspace, pages_in, disk_start, bvec, vcnt, srclen); ret = btrfs_compress_op[type-1]->decompress_bio(workspace, pages_in, disk_start, orig_bio, srclen); free_workspace(type, workspace); return ret; } Loading Loading @@ -1021,9 +1021,7 @@ void btrfs_exit_compress(void) */ int btrfs_decompress_buf2page(char *buf, unsigned long buf_start, unsigned long total_out, u64 disk_start, struct bio_vec *bvec, int vcnt, unsigned long *pg_index, unsigned long *pg_offset) struct bio *bio) { unsigned long buf_offset; unsigned long current_buf_start; Loading @@ -1031,13 +1029,13 @@ int btrfs_decompress_buf2page(char *buf, unsigned long buf_start, unsigned long working_bytes = total_out - buf_start; unsigned long bytes; 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 * 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 */ if (total_out <= start_byte) Loading @@ -1057,28 +1055,26 @@ int btrfs_decompress_buf2page(char *buf, unsigned long buf_start, /* copy bytes from the working buffer into the pages */ while (working_bytes > 0) { bytes = min(PAGE_SIZE - *pg_offset, bytes = min_t(unsigned long, bvec.bv_len, PAGE_SIZE - buf_offset); bytes = min(bytes, working_bytes); kaddr = kmap_atomic(page_out); memcpy(kaddr + *pg_offset, buf + buf_offset, bytes); kaddr = kmap_atomic(bvec.bv_page); memcpy(kaddr + bvec.bv_offset, buf + buf_offset, bytes); kunmap_atomic(kaddr); flush_dcache_page(page_out); flush_dcache_page(bvec.bv_page); *pg_offset += bytes; buf_offset += bytes; working_bytes -= bytes; current_buf_start += bytes; /* check if we need to pick another page */ if (*pg_offset == PAGE_SIZE) { (*pg_index)++; if (*pg_index >= vcnt) bio_advance(bio, bytes); if (!bio->bi_iter.bi_size) return 0; bvec = bio_iter_iovec(bio, bio->bi_iter); page_out = bvec[*pg_index].bv_page; *pg_offset = 0; start_byte = page_offset(page_out) - disk_start; start_byte = page_offset(bvec.bv_page) - disk_start; /* * make sure our new page is covered by this Loading @@ -1099,38 +1095,6 @@ int btrfs_decompress_buf2page(char *buf, unsigned long buf_start, current_buf_start = buf_start + buf_offset; } } } 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; } }
fs/btrfs/compression.h +3 −9 Original line number Diff line number Diff line Loading @@ -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); int btrfs_decompress_buf2page(char *buf, unsigned long buf_start, unsigned long total_out, u64 disk_start, struct bio_vec *bvec, int vcnt, unsigned long *pg_index, unsigned long *pg_offset); struct bio *bio); int btrfs_submit_compressed_write(struct inode *inode, u64 start, unsigned long len, u64 disk_start, Loading @@ -45,9 +43,6 @@ int btrfs_submit_compressed_write(struct inode *inode, u64 start, unsigned long nr_pages); int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio, 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 { BTRFS_COMPRESS_NONE = 0, Loading @@ -72,11 +67,10 @@ struct btrfs_compress_op { unsigned long *total_out, unsigned long max_out); int (*decompress_biovec)(struct list_head *workspace, int (*decompress_bio)(struct list_head *workspace, struct page **pages_in, u64 disk_start, struct bio_vec *bvec, int vcnt, struct bio *orig_bio, size_t srclen); int (*decompress)(struct list_head *workspace, Loading
fs/btrfs/ctree.c +19 −30 Original line number Diff line number Diff line Loading @@ -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); Loading @@ -271,8 +271,7 @@ int btrfs_copy_root(struct btrfs_trans_handle *trans, else btrfs_set_header_owner(cow, new_root_objectid); write_extent_buffer(cow, root->fs_info->fsid, btrfs_header_fsid(), BTRFS_FSID_SIZE); write_extent_buffer_fsid(cow, root->fs_info->fsid); WARN_ON(btrfs_header_generation(buf) > trans->transid); if (new_root_objectid == BTRFS_TREE_RELOC_OBJECTID) Loading Loading @@ -1130,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); Loading @@ -1141,8 +1140,7 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans, else btrfs_set_header_owner(cow, root->root_key.objectid); write_extent_buffer(cow, root->fs_info->fsid, btrfs_header_fsid(), BTRFS_FSID_SIZE); write_extent_buffer_fsid(cow, root->fs_info->fsid); ret = update_ref_for_cow(trans, root, buf, cow, &last_ref); if (ret) { Loading Loading @@ -1670,7 +1668,7 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans, continue; } cur = btrfs_find_tree_block(root->fs_info, blocknr); cur = find_extent_buffer(root->fs_info, blocknr); if (cur) uptodate = btrfs_buffer_uptodate(cur, gen, 0); else Loading Loading @@ -2255,7 +2253,7 @@ static void reada_for_search(struct btrfs_root *root, search = btrfs_node_blockptr(node, slot); blocksize = root->nodesize; eb = btrfs_find_tree_block(root->fs_info, search); eb = find_extent_buffer(root->fs_info, search); if (eb) { free_extent_buffer(eb); return; Loading Loading @@ -2314,7 +2312,7 @@ static noinline void reada_for_balance(struct btrfs_root *root, if (slot > 0) { block1 = btrfs_node_blockptr(parent, slot - 1); gen = btrfs_node_ptr_generation(parent, slot - 1); eb = btrfs_find_tree_block(root->fs_info, block1); eb = find_extent_buffer(root->fs_info, block1); /* * if we get -eagain from btrfs_buffer_uptodate, we * don't want to return eagain here. That will loop Loading @@ -2327,7 +2325,7 @@ static noinline void reada_for_balance(struct btrfs_root *root, if (slot + 1 < nritems) { block2 = btrfs_node_blockptr(parent, slot + 1); gen = btrfs_node_ptr_generation(parent, slot + 1); eb = btrfs_find_tree_block(root->fs_info, block2); eb = find_extent_buffer(root->fs_info, block2); if (eb && btrfs_buffer_uptodate(eb, gen, 1) != 0) block2 = 0; free_extent_buffer(eb); Loading Loading @@ -2445,7 +2443,7 @@ read_block_for_search(struct btrfs_trans_handle *trans, blocknr = btrfs_node_blockptr(b, slot); gen = btrfs_node_ptr_generation(b, slot); tmp = btrfs_find_tree_block(root->fs_info, blocknr); tmp = find_extent_buffer(root->fs_info, blocknr); if (tmp) { /* first we do an atomic uptodate check */ if (btrfs_buffer_uptodate(tmp, gen, 1) > 0) { Loading Loading @@ -3350,7 +3348,7 @@ static noinline int insert_new_root(struct btrfs_trans_handle *trans, root_add_used(root, root->nodesize); memset_extent_buffer(c, 0, 0, sizeof(struct btrfs_header)); memzero_extent_buffer(c, 0, sizeof(struct btrfs_header)); btrfs_set_header_nritems(c, 1); btrfs_set_header_level(c, level); btrfs_set_header_bytenr(c, c->start); Loading @@ -3358,11 +3356,8 @@ static noinline int insert_new_root(struct btrfs_trans_handle *trans, btrfs_set_header_backref_rev(c, BTRFS_MIXED_BACKREF_REV); btrfs_set_header_owner(c, root->root_key.objectid); write_extent_buffer(c, root->fs_info->fsid, btrfs_header_fsid(), BTRFS_FSID_SIZE); write_extent_buffer(c, root->fs_info->chunk_tree_uuid, btrfs_header_chunk_tree_uuid(c), BTRFS_UUID_SIZE); write_extent_buffer_fsid(c, root->fs_info->fsid); write_extent_buffer_chunk_tree_uuid(c, root->fs_info->chunk_tree_uuid); btrfs_set_node_key(c, &lower_key, 0); btrfs_set_node_blockptr(c, 0, lower->start); Loading Loading @@ -3489,17 +3484,15 @@ static noinline int split_node(struct btrfs_trans_handle *trans, root_add_used(root, root->nodesize); memset_extent_buffer(split, 0, 0, sizeof(struct btrfs_header)); memzero_extent_buffer(split, 0, sizeof(struct btrfs_header)); btrfs_set_header_level(split, btrfs_header_level(c)); btrfs_set_header_bytenr(split, split->start); btrfs_set_header_generation(split, trans->transid); btrfs_set_header_backref_rev(split, BTRFS_MIXED_BACKREF_REV); btrfs_set_header_owner(split, root->root_key.objectid); write_extent_buffer(split, root->fs_info->fsid, btrfs_header_fsid(), BTRFS_FSID_SIZE); write_extent_buffer(split, root->fs_info->chunk_tree_uuid, btrfs_header_chunk_tree_uuid(split), BTRFS_UUID_SIZE); write_extent_buffer_fsid(split, root->fs_info->fsid); write_extent_buffer_chunk_tree_uuid(split, root->fs_info->chunk_tree_uuid); ret = tree_mod_log_eb_copy(root->fs_info, split, c, 0, mid, c_nritems - mid); Loading Loading @@ -4277,18 +4270,14 @@ static noinline int split_leaf(struct btrfs_trans_handle *trans, root_add_used(root, root->nodesize); memset_extent_buffer(right, 0, 0, sizeof(struct btrfs_header)); memzero_extent_buffer(right, 0, sizeof(struct btrfs_header)); btrfs_set_header_bytenr(right, right->start); btrfs_set_header_generation(right, trans->transid); btrfs_set_header_backref_rev(right, BTRFS_MIXED_BACKREF_REV); btrfs_set_header_owner(right, root->root_key.objectid); btrfs_set_header_level(right, 0); write_extent_buffer(right, fs_info->fsid, btrfs_header_fsid(), BTRFS_FSID_SIZE); write_extent_buffer(right, fs_info->chunk_tree_uuid, btrfs_header_chunk_tree_uuid(right), BTRFS_UUID_SIZE); write_extent_buffer_fsid(right, fs_info->fsid); write_extent_buffer_chunk_tree_uuid(right, fs_info->chunk_tree_uuid); if (split == 0) { if (mid <= slot) { Loading
fs/btrfs/ctree.h +9 −5 Original line number Diff line number Diff line Loading @@ -90,9 +90,6 @@ static const int btrfs_csum_sizes[] = { 4 }; /* four bytes for CRC32 */ #define BTRFS_EMPTY_DIR_SIZE 0 /* specific to btrfs_map_block(), therefore not in include/linux/blk_types.h */ #define REQ_GET_READ_MIRRORS (1 << 30) /* ioprio of readahead is set to idle */ #define BTRFS_IOPRIO_READA (IOPRIO_PRIO_VALUE(IOPRIO_CLASS_IDLE, 0)) Loading Loading @@ -429,6 +426,10 @@ struct btrfs_space_info { struct list_head ro_bgs; struct list_head priority_tickets; struct list_head tickets; /* * tickets_id just indicates the next ticket will be handled, so note * it's not stored per ticket. */ u64 tickets_id; struct rw_semaphore groups_sem; Loading Loading @@ -798,7 +799,6 @@ struct btrfs_fs_info { spinlock_t super_lock; struct btrfs_super_block *super_copy; struct btrfs_super_block *super_for_commit; struct block_device *__bdev; struct super_block *sb; struct inode *btree_inode; struct backing_dev_info bdi; Loading Loading @@ -2210,6 +2210,8 @@ btrfs_disk_balance_args_to_cpu(struct btrfs_balance_args *cpu, cpu->target = le64_to_cpu(disk->target); cpu->flags = le64_to_cpu(disk->flags); cpu->limit = le64_to_cpu(disk->limit); cpu->stripes_min = le32_to_cpu(disk->stripes_min); cpu->stripes_max = le32_to_cpu(disk->stripes_max); } static inline void Loading @@ -2228,6 +2230,8 @@ btrfs_cpu_balance_args_to_disk(struct btrfs_disk_balance_args *disk, disk->target = cpu_to_le64(cpu->target); disk->flags = cpu_to_le64(cpu->flags); disk->limit = cpu_to_le64(cpu->limit); disk->stripes_min = cpu_to_le32(cpu->stripes_min); disk->stripes_max = cpu_to_le32(cpu->stripes_max); } /* struct btrfs_super_block */ Loading Loading @@ -3660,7 +3664,7 @@ struct reada_control *btrfs_reada_add(struct btrfs_root *root, int btrfs_reada_wait(void *handle); void btrfs_reada_detach(void *handle); int btree_readahead_hook(struct btrfs_fs_info *fs_info, struct extent_buffer *eb, u64 start, int err); struct extent_buffer *eb, int err); static inline int is_fstree(u64 rootid) { Loading