Commit 9907ab37 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'for-5.9-rc2-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux

Pull btrfs fixes from David Sterba:

 - fix swapfile activation on subvolumes with deleted snapshots

 - error value mixup when removing directory entries from tree log

 - fix lzo compression level reset after previous level setting

 - fix space cache memory leak after transaction abort

 - fix const function attribute

 - more error handling improvements

* tag 'for-5.9-rc2-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux:
  btrfs: detect nocow for swap after snapshot delete
  btrfs: check the right error variable in btrfs_del_dir_entries_in_log
  btrfs: fix space cache memory leak after transaction abort
  btrfs: use the correct const function attribute for btrfs_get_num_csums
  btrfs: reset compression level for lzo on remount
  btrfs: handle errors from async submission
parents c41c3ec4 a84d5d42
...@@ -68,7 +68,7 @@ const char *btrfs_super_csum_driver(u16 csum_type) ...@@ -68,7 +68,7 @@ const char *btrfs_super_csum_driver(u16 csum_type)
btrfs_csums[csum_type].name; btrfs_csums[csum_type].name;
} }
size_t __const btrfs_get_num_csums(void) size_t __attribute_const__ btrfs_get_num_csums(void)
{ {
return ARRAY_SIZE(btrfs_csums); return ARRAY_SIZE(btrfs_csums);
} }
......
...@@ -2262,7 +2262,7 @@ BTRFS_SETGET_STACK_FUNCS(super_uuid_tree_generation, struct btrfs_super_block, ...@@ -2262,7 +2262,7 @@ BTRFS_SETGET_STACK_FUNCS(super_uuid_tree_generation, struct btrfs_super_block,
int btrfs_super_csum_size(const struct btrfs_super_block *s); int btrfs_super_csum_size(const struct btrfs_super_block *s);
const char *btrfs_super_csum_name(u16 csum_type); const char *btrfs_super_csum_name(u16 csum_type);
const char *btrfs_super_csum_driver(u16 csum_type); const char *btrfs_super_csum_driver(u16 csum_type);
size_t __const btrfs_get_num_csums(void); size_t __attribute_const__ btrfs_get_num_csums(void);
/* /*
...@@ -2518,7 +2518,7 @@ int btrfs_pin_extent_for_log_replay(struct btrfs_trans_handle *trans, ...@@ -2518,7 +2518,7 @@ int btrfs_pin_extent_for_log_replay(struct btrfs_trans_handle *trans,
u64 bytenr, u64 num_bytes); u64 bytenr, u64 num_bytes);
int btrfs_exclude_logged_extents(struct extent_buffer *eb); int btrfs_exclude_logged_extents(struct extent_buffer *eb);
int btrfs_cross_ref_exist(struct btrfs_root *root, int btrfs_cross_ref_exist(struct btrfs_root *root,
u64 objectid, u64 offset, u64 bytenr); u64 objectid, u64 offset, u64 bytenr, bool strict);
struct extent_buffer *btrfs_alloc_tree_block(struct btrfs_trans_handle *trans, struct extent_buffer *btrfs_alloc_tree_block(struct btrfs_trans_handle *trans,
struct btrfs_root *root, struct btrfs_root *root,
u64 parent, u64 root_objectid, u64 parent, u64 root_objectid,
...@@ -2934,7 +2934,7 @@ struct extent_map *btrfs_get_extent_fiemap(struct btrfs_inode *inode, ...@@ -2934,7 +2934,7 @@ struct extent_map *btrfs_get_extent_fiemap(struct btrfs_inode *inode,
u64 start, u64 len); u64 start, u64 len);
noinline int can_nocow_extent(struct inode *inode, u64 offset, u64 *len, noinline int can_nocow_extent(struct inode *inode, u64 offset, u64 *len,
u64 *orig_start, u64 *orig_block_len, u64 *orig_start, u64 *orig_block_len,
u64 *ram_bytes); u64 *ram_bytes, bool strict);
void __btrfs_del_delalloc_inode(struct btrfs_root *root, void __btrfs_del_delalloc_inode(struct btrfs_root *root,
struct btrfs_inode *inode); struct btrfs_inode *inode);
......
...@@ -4551,6 +4551,7 @@ static void btrfs_cleanup_bg_io(struct btrfs_block_group *cache) ...@@ -4551,6 +4551,7 @@ static void btrfs_cleanup_bg_io(struct btrfs_block_group *cache)
cache->io_ctl.inode = NULL; cache->io_ctl.inode = NULL;
iput(inode); iput(inode);
} }
ASSERT(cache->io_ctl.pages == NULL);
btrfs_put_block_group(cache); btrfs_put_block_group(cache);
} }
......
...@@ -2306,7 +2306,8 @@ static noinline int check_delayed_ref(struct btrfs_root *root, ...@@ -2306,7 +2306,8 @@ static noinline int check_delayed_ref(struct btrfs_root *root,
static noinline int check_committed_ref(struct btrfs_root *root, static noinline int check_committed_ref(struct btrfs_root *root,
struct btrfs_path *path, struct btrfs_path *path,
u64 objectid, u64 offset, u64 bytenr) u64 objectid, u64 offset, u64 bytenr,
bool strict)
{ {
struct btrfs_fs_info *fs_info = root->fs_info; struct btrfs_fs_info *fs_info = root->fs_info;
struct btrfs_root *extent_root = fs_info->extent_root; struct btrfs_root *extent_root = fs_info->extent_root;
...@@ -2348,9 +2349,13 @@ static noinline int check_committed_ref(struct btrfs_root *root, ...@@ -2348,9 +2349,13 @@ static noinline int check_committed_ref(struct btrfs_root *root,
btrfs_extent_inline_ref_size(BTRFS_EXTENT_DATA_REF_KEY)) btrfs_extent_inline_ref_size(BTRFS_EXTENT_DATA_REF_KEY))
goto out; goto out;
/* If extent created before last snapshot => it's definitely shared */ /*
if (btrfs_extent_generation(leaf, ei) <= * If extent created before last snapshot => it's shared unless the
btrfs_root_last_snapshot(&root->root_item)) * snapshot has been deleted. Use the heuristic if strict is false.
*/
if (!strict &&
(btrfs_extent_generation(leaf, ei) <=
btrfs_root_last_snapshot(&root->root_item)))
goto out; goto out;
iref = (struct btrfs_extent_inline_ref *)(ei + 1); iref = (struct btrfs_extent_inline_ref *)(ei + 1);
...@@ -2375,7 +2380,7 @@ static noinline int check_committed_ref(struct btrfs_root *root, ...@@ -2375,7 +2380,7 @@ static noinline int check_committed_ref(struct btrfs_root *root,
} }
int btrfs_cross_ref_exist(struct btrfs_root *root, u64 objectid, u64 offset, int btrfs_cross_ref_exist(struct btrfs_root *root, u64 objectid, u64 offset,
u64 bytenr) u64 bytenr, bool strict)
{ {
struct btrfs_path *path; struct btrfs_path *path;
int ret; int ret;
...@@ -2386,7 +2391,7 @@ int btrfs_cross_ref_exist(struct btrfs_root *root, u64 objectid, u64 offset, ...@@ -2386,7 +2391,7 @@ int btrfs_cross_ref_exist(struct btrfs_root *root, u64 objectid, u64 offset,
do { do {
ret = check_committed_ref(root, path, objectid, ret = check_committed_ref(root, path, objectid,
offset, bytenr); offset, bytenr, strict);
if (ret && ret != -ENOENT) if (ret && ret != -ENOENT)
goto out; goto out;
......
...@@ -1571,7 +1571,7 @@ static int check_can_nocow(struct btrfs_inode *inode, loff_t pos, ...@@ -1571,7 +1571,7 @@ static int check_can_nocow(struct btrfs_inode *inode, loff_t pos,
} }
ret = can_nocow_extent(&inode->vfs_inode, lockstart, &num_bytes, ret = can_nocow_extent(&inode->vfs_inode, lockstart, &num_bytes,
NULL, NULL, NULL); NULL, NULL, NULL, false);
if (ret <= 0) { if (ret <= 0) {
ret = 0; ret = 0;
if (!nowait) if (!nowait)
......
...@@ -1186,7 +1186,6 @@ static int __btrfs_wait_cache_io(struct btrfs_root *root, ...@@ -1186,7 +1186,6 @@ static int __btrfs_wait_cache_io(struct btrfs_root *root,
ret = update_cache_item(trans, root, inode, path, offset, ret = update_cache_item(trans, root, inode, path, offset,
io_ctl->entries, io_ctl->bitmaps); io_ctl->entries, io_ctl->bitmaps);
out: out:
io_ctl_free(io_ctl);
if (ret) { if (ret) {
invalidate_inode_pages2(inode->i_mapping); invalidate_inode_pages2(inode->i_mapping);
BTRFS_I(inode)->generation = 0; BTRFS_I(inode)->generation = 0;
...@@ -1347,6 +1346,7 @@ static int __btrfs_write_out_cache(struct btrfs_root *root, struct inode *inode, ...@@ -1347,6 +1346,7 @@ static int __btrfs_write_out_cache(struct btrfs_root *root, struct inode *inode,
* them out later * them out later
*/ */
io_ctl_drop_pages(io_ctl); io_ctl_drop_pages(io_ctl);
io_ctl_free(io_ctl);
unlock_extent_cached(&BTRFS_I(inode)->io_tree, 0, unlock_extent_cached(&BTRFS_I(inode)->io_tree, 0,
i_size_read(inode) - 1, &cached_state); i_size_read(inode) - 1, &cached_state);
......
...@@ -1610,7 +1610,7 @@ static noinline int run_delalloc_nocow(struct btrfs_inode *inode, ...@@ -1610,7 +1610,7 @@ static noinline int run_delalloc_nocow(struct btrfs_inode *inode,
goto out_check; goto out_check;
ret = btrfs_cross_ref_exist(root, ino, ret = btrfs_cross_ref_exist(root, ino,
found_key.offset - found_key.offset -
extent_offset, disk_bytenr); extent_offset, disk_bytenr, false);
if (ret) { if (ret) {
/* /*
* ret could be -EIO if the above fails to read * ret could be -EIO if the above fails to read
...@@ -2161,11 +2161,8 @@ static blk_status_t btrfs_submit_bio_start(void *private_data, struct bio *bio, ...@@ -2161,11 +2161,8 @@ static blk_status_t btrfs_submit_bio_start(void *private_data, struct bio *bio,
u64 bio_offset) u64 bio_offset)
{ {
struct inode *inode = private_data; struct inode *inode = private_data;
blk_status_t ret = 0;
ret = btrfs_csum_one_bio(BTRFS_I(inode), bio, 0, 0); return btrfs_csum_one_bio(BTRFS_I(inode), bio, 0, 0);
BUG_ON(ret); /* -ENOMEM */
return 0;
} }
/* /*
...@@ -6953,6 +6950,8 @@ static struct extent_map *btrfs_new_extent_direct(struct btrfs_inode *inode, ...@@ -6953,6 +6950,8 @@ static struct extent_map *btrfs_new_extent_direct(struct btrfs_inode *inode,
* @orig_start: (optional) Return the original file offset of the file extent * @orig_start: (optional) Return the original file offset of the file extent
* @orig_len: (optional) Return the original on-disk length of the file extent * @orig_len: (optional) Return the original on-disk length of the file extent
* @ram_bytes: (optional) Return the ram_bytes of the file extent * @ram_bytes: (optional) Return the ram_bytes of the file extent
* @strict: if true, omit optimizations that might force us into unnecessary
* cow. e.g., don't trust generation number.
* *
* This function will flush ordered extents in the range to ensure proper * This function will flush ordered extents in the range to ensure proper
* nocow checks for (nowait == false) case. * nocow checks for (nowait == false) case.
...@@ -6967,7 +6966,7 @@ static struct extent_map *btrfs_new_extent_direct(struct btrfs_inode *inode, ...@@ -6967,7 +6966,7 @@ static struct extent_map *btrfs_new_extent_direct(struct btrfs_inode *inode,
*/ */
noinline int can_nocow_extent(struct inode *inode, u64 offset, u64 *len, noinline int can_nocow_extent(struct inode *inode, u64 offset, u64 *len,
u64 *orig_start, u64 *orig_block_len, u64 *orig_start, u64 *orig_block_len,
u64 *ram_bytes) u64 *ram_bytes, bool strict)
{ {
struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
struct btrfs_path *path; struct btrfs_path *path;
...@@ -7045,8 +7044,9 @@ noinline int can_nocow_extent(struct inode *inode, u64 offset, u64 *len, ...@@ -7045,8 +7044,9 @@ noinline int can_nocow_extent(struct inode *inode, u64 offset, u64 *len,
* Do the same check as in btrfs_cross_ref_exist but without the * Do the same check as in btrfs_cross_ref_exist but without the
* unnecessary search. * unnecessary search.
*/ */
if (btrfs_file_extent_generation(leaf, fi) <= if (!strict &&
btrfs_root_last_snapshot(&root->root_item)) (btrfs_file_extent_generation(leaf, fi) <=
btrfs_root_last_snapshot(&root->root_item)))
goto out; goto out;
backref_offset = btrfs_file_extent_offset(leaf, fi); backref_offset = btrfs_file_extent_offset(leaf, fi);
...@@ -7082,7 +7082,8 @@ noinline int can_nocow_extent(struct inode *inode, u64 offset, u64 *len, ...@@ -7082,7 +7082,8 @@ noinline int can_nocow_extent(struct inode *inode, u64 offset, u64 *len,
*/ */
ret = btrfs_cross_ref_exist(root, btrfs_ino(BTRFS_I(inode)), ret = btrfs_cross_ref_exist(root, btrfs_ino(BTRFS_I(inode)),
key.offset - backref_offset, disk_bytenr); key.offset - backref_offset, disk_bytenr,
strict);
if (ret) { if (ret) {
ret = 0; ret = 0;
goto out; goto out;
...@@ -7303,7 +7304,7 @@ static int btrfs_get_blocks_direct_write(struct extent_map **map, ...@@ -7303,7 +7304,7 @@ static int btrfs_get_blocks_direct_write(struct extent_map **map,
block_start = em->block_start + (start - em->start); block_start = em->block_start + (start - em->start);
if (can_nocow_extent(inode, start, &len, &orig_start, if (can_nocow_extent(inode, start, &len, &orig_start,
&orig_block_len, &ram_bytes) == 1 && &orig_block_len, &ram_bytes, false) == 1 &&
btrfs_inc_nocow_writers(fs_info, block_start)) { btrfs_inc_nocow_writers(fs_info, block_start)) {
struct extent_map *em2; struct extent_map *em2;
...@@ -7619,10 +7620,8 @@ static blk_status_t btrfs_submit_bio_start_direct_io(void *private_data, ...@@ -7619,10 +7620,8 @@ static blk_status_t btrfs_submit_bio_start_direct_io(void *private_data,
struct bio *bio, u64 offset) struct bio *bio, u64 offset)
{ {
struct inode *inode = private_data; struct inode *inode = private_data;
blk_status_t ret;
ret = btrfs_csum_one_bio(BTRFS_I(inode), bio, offset, 1); return btrfs_csum_one_bio(BTRFS_I(inode), bio, offset, 1);
BUG_ON(ret); /* -ENOMEM */
return 0;
} }
static void btrfs_end_dio_bio(struct bio *bio) static void btrfs_end_dio_bio(struct bio *bio)
...@@ -10136,7 +10135,7 @@ static int btrfs_swap_activate(struct swap_info_struct *sis, struct file *file, ...@@ -10136,7 +10135,7 @@ static int btrfs_swap_activate(struct swap_info_struct *sis, struct file *file,
free_extent_map(em); free_extent_map(em);
em = NULL; em = NULL;
ret = can_nocow_extent(inode, start, &len, NULL, NULL, NULL); ret = can_nocow_extent(inode, start, &len, NULL, NULL, NULL, true);
if (ret < 0) { if (ret < 0) {
goto out; goto out;
} else if (ret) { } else if (ret) {
......
...@@ -625,6 +625,7 @@ int btrfs_parse_options(struct btrfs_fs_info *info, char *options, ...@@ -625,6 +625,7 @@ int btrfs_parse_options(struct btrfs_fs_info *info, char *options,
} else if (strncmp(args[0].from, "lzo", 3) == 0) { } else if (strncmp(args[0].from, "lzo", 3) == 0) {
compress_type = "lzo"; compress_type = "lzo";
info->compress_type = BTRFS_COMPRESS_LZO; info->compress_type = BTRFS_COMPRESS_LZO;
info->compress_level = 0;
btrfs_set_opt(info->mount_opt, COMPRESS); btrfs_set_opt(info->mount_opt, COMPRESS);
btrfs_clear_opt(info->mount_opt, NODATACOW); btrfs_clear_opt(info->mount_opt, NODATACOW);
btrfs_clear_opt(info->mount_opt, NODATASUM); btrfs_clear_opt(info->mount_opt, NODATASUM);
......
...@@ -3449,11 +3449,13 @@ int btrfs_del_dir_entries_in_log(struct btrfs_trans_handle *trans, ...@@ -3449,11 +3449,13 @@ int btrfs_del_dir_entries_in_log(struct btrfs_trans_handle *trans,
btrfs_free_path(path); btrfs_free_path(path);
out_unlock: out_unlock:
mutex_unlock(&dir->log_mutex); mutex_unlock(&dir->log_mutex);
if (ret == -ENOSPC) { if (err == -ENOSPC) {
btrfs_set_log_full_commit(trans); btrfs_set_log_full_commit(trans);
ret = 0; err = 0;
} else if (ret < 0) } else if (err < 0 && err != -ENOENT) {
btrfs_abort_transaction(trans, ret); /* ENOENT can be returned if the entry hasn't been fsynced yet */
btrfs_abort_transaction(trans, err);
}
btrfs_end_log_trans(root); btrfs_end_log_trans(root);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment