Loading fs/btrfs/extent-tree.c +4 −2 Original line number Original line Diff line number Diff line Loading @@ -3997,7 +3997,7 @@ again: * We make the other tasks wait for the flush only when we can flush * We make the other tasks wait for the flush only when we can flush * all things. * all things. */ */ if (ret && flush == BTRFS_RESERVE_FLUSH_ALL) { if (ret && flush != BTRFS_RESERVE_NO_FLUSH) { flushing = true; flushing = true; space_info->flush = 1; space_info->flush = 1; } } Loading Loading @@ -5560,7 +5560,7 @@ static noinline int find_free_extent(struct btrfs_trans_handle *trans, int empty_cluster = 2 * 1024 * 1024; int empty_cluster = 2 * 1024 * 1024; struct btrfs_space_info *space_info; struct btrfs_space_info *space_info; int loop = 0; int loop = 0; int index = 0; int index = __get_raid_index(data); int alloc_type = (data & BTRFS_BLOCK_GROUP_DATA) ? int alloc_type = (data & BTRFS_BLOCK_GROUP_DATA) ? RESERVE_ALLOC_NO_ACCOUNT : RESERVE_ALLOC; RESERVE_ALLOC_NO_ACCOUNT : RESERVE_ALLOC; bool found_uncached_bg = false; bool found_uncached_bg = false; Loading Loading @@ -6788,11 +6788,13 @@ static noinline int walk_up_proc(struct btrfs_trans_handle *trans, &wc->flags[level]); &wc->flags[level]); if (ret < 0) { if (ret < 0) { btrfs_tree_unlock_rw(eb, path->locks[level]); btrfs_tree_unlock_rw(eb, path->locks[level]); path->locks[level] = 0; return ret; return ret; } } BUG_ON(wc->refs[level] == 0); BUG_ON(wc->refs[level] == 0); if (wc->refs[level] == 1) { if (wc->refs[level] == 1) { btrfs_tree_unlock_rw(eb, path->locks[level]); btrfs_tree_unlock_rw(eb, path->locks[level]); path->locks[level] = 0; return 1; return 1; } } } } Loading fs/btrfs/extent_map.c +13 −1 Original line number Original line Diff line number Diff line Loading @@ -171,6 +171,10 @@ static int mergable_maps(struct extent_map *prev, struct extent_map *next) if (test_bit(EXTENT_FLAG_COMPRESSED, &prev->flags)) if (test_bit(EXTENT_FLAG_COMPRESSED, &prev->flags)) return 0; return 0; if (test_bit(EXTENT_FLAG_LOGGING, &prev->flags) || test_bit(EXTENT_FLAG_LOGGING, &next->flags)) return 0; if (extent_map_end(prev) == next->start && if (extent_map_end(prev) == next->start && prev->flags == next->flags && prev->flags == next->flags && prev->bdev == next->bdev && prev->bdev == next->bdev && Loading Loading @@ -256,6 +260,7 @@ int unpin_extent_cache(struct extent_map_tree *tree, u64 start, u64 len, if (!em) if (!em) goto out; goto out; if (!test_bit(EXTENT_FLAG_LOGGING, &em->flags)) list_move(&em->list, &tree->modified_extents); list_move(&em->list, &tree->modified_extents); em->generation = gen; em->generation = gen; clear_bit(EXTENT_FLAG_PINNED, &em->flags); clear_bit(EXTENT_FLAG_PINNED, &em->flags); Loading @@ -281,6 +286,13 @@ out: } } void clear_em_logging(struct extent_map_tree *tree, struct extent_map *em) { clear_bit(EXTENT_FLAG_LOGGING, &em->flags); if (em->in_tree) try_merge_map(tree, em); } /** /** * add_extent_mapping - add new extent map to the extent tree * add_extent_mapping - add new extent map to the extent tree * @tree: tree to insert new map in * @tree: tree to insert new map in Loading fs/btrfs/extent_map.h +1 −0 Original line number Original line Diff line number Diff line Loading @@ -69,6 +69,7 @@ void free_extent_map(struct extent_map *em); int __init extent_map_init(void); int __init extent_map_init(void); void extent_map_exit(void); void extent_map_exit(void); int unpin_extent_cache(struct extent_map_tree *tree, u64 start, u64 len, u64 gen); int unpin_extent_cache(struct extent_map_tree *tree, u64 start, u64 len, u64 gen); void clear_em_logging(struct extent_map_tree *tree, struct extent_map *em); struct extent_map *search_extent_mapping(struct extent_map_tree *tree, struct extent_map *search_extent_mapping(struct extent_map_tree *tree, u64 start, u64 len); u64 start, u64 len); #endif #endif fs/btrfs/file-item.c +2 −2 Original line number Original line Diff line number Diff line Loading @@ -460,8 +460,8 @@ int btrfs_csum_one_bio(struct btrfs_root *root, struct inode *inode, if (!contig) if (!contig) offset = page_offset(bvec->bv_page) + bvec->bv_offset; offset = page_offset(bvec->bv_page) + bvec->bv_offset; if (!contig && (offset >= ordered->file_offset + ordered->len || if (offset >= ordered->file_offset + ordered->len || offset < ordered->file_offset)) { offset < ordered->file_offset) { unsigned long bytes_left; unsigned long bytes_left; sums->len = this_sum_bytes; sums->len = this_sum_bytes; this_sum_bytes = 0; this_sum_bytes = 0; Loading fs/btrfs/file.c +27 −8 Original line number Original line Diff line number Diff line Loading @@ -293,15 +293,24 @@ static int __btrfs_run_defrag_inode(struct btrfs_fs_info *fs_info, struct btrfs_key key; struct btrfs_key key; struct btrfs_ioctl_defrag_range_args range; struct btrfs_ioctl_defrag_range_args range; int num_defrag; int num_defrag; int index; int ret; /* get the inode */ /* get the inode */ key.objectid = defrag->root; key.objectid = defrag->root; btrfs_set_key_type(&key, BTRFS_ROOT_ITEM_KEY); btrfs_set_key_type(&key, BTRFS_ROOT_ITEM_KEY); key.offset = (u64)-1; key.offset = (u64)-1; index = srcu_read_lock(&fs_info->subvol_srcu); inode_root = btrfs_read_fs_root_no_name(fs_info, &key); inode_root = btrfs_read_fs_root_no_name(fs_info, &key); if (IS_ERR(inode_root)) { if (IS_ERR(inode_root)) { kmem_cache_free(btrfs_inode_defrag_cachep, defrag); ret = PTR_ERR(inode_root); return PTR_ERR(inode_root); goto cleanup; } if (btrfs_root_refs(&inode_root->root_item) == 0) { ret = -ENOENT; goto cleanup; } } key.objectid = defrag->ino; key.objectid = defrag->ino; Loading @@ -309,9 +318,10 @@ static int __btrfs_run_defrag_inode(struct btrfs_fs_info *fs_info, key.offset = 0; key.offset = 0; inode = btrfs_iget(fs_info->sb, &key, inode_root, NULL); inode = btrfs_iget(fs_info->sb, &key, inode_root, NULL); if (IS_ERR(inode)) { if (IS_ERR(inode)) { kmem_cache_free(btrfs_inode_defrag_cachep, defrag); ret = PTR_ERR(inode); return PTR_ERR(inode); goto cleanup; } } srcu_read_unlock(&fs_info->subvol_srcu, index); /* do a chunk of defrag */ /* do a chunk of defrag */ clear_bit(BTRFS_INODE_IN_DEFRAG, &BTRFS_I(inode)->runtime_flags); clear_bit(BTRFS_INODE_IN_DEFRAG, &BTRFS_I(inode)->runtime_flags); Loading Loading @@ -346,6 +356,10 @@ static int __btrfs_run_defrag_inode(struct btrfs_fs_info *fs_info, iput(inode); iput(inode); return 0; return 0; cleanup: srcu_read_unlock(&fs_info->subvol_srcu, index); kmem_cache_free(btrfs_inode_defrag_cachep, defrag); return ret; } } /* /* Loading Loading @@ -1595,9 +1609,10 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb, if (err < 0 && num_written > 0) if (err < 0 && num_written > 0) num_written = err; num_written = err; } } out: if (sync) if (sync) atomic_dec(&BTRFS_I(inode)->sync_writers); atomic_dec(&BTRFS_I(inode)->sync_writers); out: sb_end_write(inode->i_sb); sb_end_write(inode->i_sb); current->backing_dev_info = NULL; current->backing_dev_info = NULL; return num_written ? num_written : err; return num_written ? num_written : err; Loading Loading @@ -2242,6 +2257,7 @@ static int find_desired_extent(struct inode *inode, loff_t *offset, int origin) if (lockend <= lockstart) if (lockend <= lockstart) lockend = lockstart + root->sectorsize; lockend = lockstart + root->sectorsize; lockend--; len = lockend - lockstart + 1; len = lockend - lockstart + 1; len = max_t(u64, len, root->sectorsize); len = max_t(u64, len, root->sectorsize); Loading Loading @@ -2308,11 +2324,14 @@ static int find_desired_extent(struct inode *inode, loff_t *offset, int origin) } } } } if (!test_bit(EXTENT_FLAG_PREALLOC, &em->flags)) { *offset = start; *offset = start; free_extent_map(em); free_extent_map(em); break; break; } } } } } start = em->start + em->len; start = em->start + em->len; last_end = em->start + em->len; last_end = em->start + em->len; Loading Loading
fs/btrfs/extent-tree.c +4 −2 Original line number Original line Diff line number Diff line Loading @@ -3997,7 +3997,7 @@ again: * We make the other tasks wait for the flush only when we can flush * We make the other tasks wait for the flush only when we can flush * all things. * all things. */ */ if (ret && flush == BTRFS_RESERVE_FLUSH_ALL) { if (ret && flush != BTRFS_RESERVE_NO_FLUSH) { flushing = true; flushing = true; space_info->flush = 1; space_info->flush = 1; } } Loading Loading @@ -5560,7 +5560,7 @@ static noinline int find_free_extent(struct btrfs_trans_handle *trans, int empty_cluster = 2 * 1024 * 1024; int empty_cluster = 2 * 1024 * 1024; struct btrfs_space_info *space_info; struct btrfs_space_info *space_info; int loop = 0; int loop = 0; int index = 0; int index = __get_raid_index(data); int alloc_type = (data & BTRFS_BLOCK_GROUP_DATA) ? int alloc_type = (data & BTRFS_BLOCK_GROUP_DATA) ? RESERVE_ALLOC_NO_ACCOUNT : RESERVE_ALLOC; RESERVE_ALLOC_NO_ACCOUNT : RESERVE_ALLOC; bool found_uncached_bg = false; bool found_uncached_bg = false; Loading Loading @@ -6788,11 +6788,13 @@ static noinline int walk_up_proc(struct btrfs_trans_handle *trans, &wc->flags[level]); &wc->flags[level]); if (ret < 0) { if (ret < 0) { btrfs_tree_unlock_rw(eb, path->locks[level]); btrfs_tree_unlock_rw(eb, path->locks[level]); path->locks[level] = 0; return ret; return ret; } } BUG_ON(wc->refs[level] == 0); BUG_ON(wc->refs[level] == 0); if (wc->refs[level] == 1) { if (wc->refs[level] == 1) { btrfs_tree_unlock_rw(eb, path->locks[level]); btrfs_tree_unlock_rw(eb, path->locks[level]); path->locks[level] = 0; return 1; return 1; } } } } Loading
fs/btrfs/extent_map.c +13 −1 Original line number Original line Diff line number Diff line Loading @@ -171,6 +171,10 @@ static int mergable_maps(struct extent_map *prev, struct extent_map *next) if (test_bit(EXTENT_FLAG_COMPRESSED, &prev->flags)) if (test_bit(EXTENT_FLAG_COMPRESSED, &prev->flags)) return 0; return 0; if (test_bit(EXTENT_FLAG_LOGGING, &prev->flags) || test_bit(EXTENT_FLAG_LOGGING, &next->flags)) return 0; if (extent_map_end(prev) == next->start && if (extent_map_end(prev) == next->start && prev->flags == next->flags && prev->flags == next->flags && prev->bdev == next->bdev && prev->bdev == next->bdev && Loading Loading @@ -256,6 +260,7 @@ int unpin_extent_cache(struct extent_map_tree *tree, u64 start, u64 len, if (!em) if (!em) goto out; goto out; if (!test_bit(EXTENT_FLAG_LOGGING, &em->flags)) list_move(&em->list, &tree->modified_extents); list_move(&em->list, &tree->modified_extents); em->generation = gen; em->generation = gen; clear_bit(EXTENT_FLAG_PINNED, &em->flags); clear_bit(EXTENT_FLAG_PINNED, &em->flags); Loading @@ -281,6 +286,13 @@ out: } } void clear_em_logging(struct extent_map_tree *tree, struct extent_map *em) { clear_bit(EXTENT_FLAG_LOGGING, &em->flags); if (em->in_tree) try_merge_map(tree, em); } /** /** * add_extent_mapping - add new extent map to the extent tree * add_extent_mapping - add new extent map to the extent tree * @tree: tree to insert new map in * @tree: tree to insert new map in Loading
fs/btrfs/extent_map.h +1 −0 Original line number Original line Diff line number Diff line Loading @@ -69,6 +69,7 @@ void free_extent_map(struct extent_map *em); int __init extent_map_init(void); int __init extent_map_init(void); void extent_map_exit(void); void extent_map_exit(void); int unpin_extent_cache(struct extent_map_tree *tree, u64 start, u64 len, u64 gen); int unpin_extent_cache(struct extent_map_tree *tree, u64 start, u64 len, u64 gen); void clear_em_logging(struct extent_map_tree *tree, struct extent_map *em); struct extent_map *search_extent_mapping(struct extent_map_tree *tree, struct extent_map *search_extent_mapping(struct extent_map_tree *tree, u64 start, u64 len); u64 start, u64 len); #endif #endif
fs/btrfs/file-item.c +2 −2 Original line number Original line Diff line number Diff line Loading @@ -460,8 +460,8 @@ int btrfs_csum_one_bio(struct btrfs_root *root, struct inode *inode, if (!contig) if (!contig) offset = page_offset(bvec->bv_page) + bvec->bv_offset; offset = page_offset(bvec->bv_page) + bvec->bv_offset; if (!contig && (offset >= ordered->file_offset + ordered->len || if (offset >= ordered->file_offset + ordered->len || offset < ordered->file_offset)) { offset < ordered->file_offset) { unsigned long bytes_left; unsigned long bytes_left; sums->len = this_sum_bytes; sums->len = this_sum_bytes; this_sum_bytes = 0; this_sum_bytes = 0; Loading
fs/btrfs/file.c +27 −8 Original line number Original line Diff line number Diff line Loading @@ -293,15 +293,24 @@ static int __btrfs_run_defrag_inode(struct btrfs_fs_info *fs_info, struct btrfs_key key; struct btrfs_key key; struct btrfs_ioctl_defrag_range_args range; struct btrfs_ioctl_defrag_range_args range; int num_defrag; int num_defrag; int index; int ret; /* get the inode */ /* get the inode */ key.objectid = defrag->root; key.objectid = defrag->root; btrfs_set_key_type(&key, BTRFS_ROOT_ITEM_KEY); btrfs_set_key_type(&key, BTRFS_ROOT_ITEM_KEY); key.offset = (u64)-1; key.offset = (u64)-1; index = srcu_read_lock(&fs_info->subvol_srcu); inode_root = btrfs_read_fs_root_no_name(fs_info, &key); inode_root = btrfs_read_fs_root_no_name(fs_info, &key); if (IS_ERR(inode_root)) { if (IS_ERR(inode_root)) { kmem_cache_free(btrfs_inode_defrag_cachep, defrag); ret = PTR_ERR(inode_root); return PTR_ERR(inode_root); goto cleanup; } if (btrfs_root_refs(&inode_root->root_item) == 0) { ret = -ENOENT; goto cleanup; } } key.objectid = defrag->ino; key.objectid = defrag->ino; Loading @@ -309,9 +318,10 @@ static int __btrfs_run_defrag_inode(struct btrfs_fs_info *fs_info, key.offset = 0; key.offset = 0; inode = btrfs_iget(fs_info->sb, &key, inode_root, NULL); inode = btrfs_iget(fs_info->sb, &key, inode_root, NULL); if (IS_ERR(inode)) { if (IS_ERR(inode)) { kmem_cache_free(btrfs_inode_defrag_cachep, defrag); ret = PTR_ERR(inode); return PTR_ERR(inode); goto cleanup; } } srcu_read_unlock(&fs_info->subvol_srcu, index); /* do a chunk of defrag */ /* do a chunk of defrag */ clear_bit(BTRFS_INODE_IN_DEFRAG, &BTRFS_I(inode)->runtime_flags); clear_bit(BTRFS_INODE_IN_DEFRAG, &BTRFS_I(inode)->runtime_flags); Loading Loading @@ -346,6 +356,10 @@ static int __btrfs_run_defrag_inode(struct btrfs_fs_info *fs_info, iput(inode); iput(inode); return 0; return 0; cleanup: srcu_read_unlock(&fs_info->subvol_srcu, index); kmem_cache_free(btrfs_inode_defrag_cachep, defrag); return ret; } } /* /* Loading Loading @@ -1595,9 +1609,10 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb, if (err < 0 && num_written > 0) if (err < 0 && num_written > 0) num_written = err; num_written = err; } } out: if (sync) if (sync) atomic_dec(&BTRFS_I(inode)->sync_writers); atomic_dec(&BTRFS_I(inode)->sync_writers); out: sb_end_write(inode->i_sb); sb_end_write(inode->i_sb); current->backing_dev_info = NULL; current->backing_dev_info = NULL; return num_written ? num_written : err; return num_written ? num_written : err; Loading Loading @@ -2242,6 +2257,7 @@ static int find_desired_extent(struct inode *inode, loff_t *offset, int origin) if (lockend <= lockstart) if (lockend <= lockstart) lockend = lockstart + root->sectorsize; lockend = lockstart + root->sectorsize; lockend--; len = lockend - lockstart + 1; len = lockend - lockstart + 1; len = max_t(u64, len, root->sectorsize); len = max_t(u64, len, root->sectorsize); Loading Loading @@ -2308,11 +2324,14 @@ static int find_desired_extent(struct inode *inode, loff_t *offset, int origin) } } } } if (!test_bit(EXTENT_FLAG_PREALLOC, &em->flags)) { *offset = start; *offset = start; free_extent_map(em); free_extent_map(em); break; break; } } } } } start = em->start + em->len; start = em->start + em->len; last_end = em->start + em->len; last_end = em->start + em->len; Loading