Skip to content

Commit 23c2c8c

Browse files
committed
Merge tag 'for-5.9-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux
Pull more btrfs updates from David Sterba: "One minor update, the rest are fixes that have arrived a bit late for the first batch. There are also some recent fixes for bugs that were discovered during the merge window and pop up during testing. User visible change: - show correct subvolume path in /proc/mounts for bind mounts Fixes: - fix compression messages when remounting with different level or compression algorithm - tree-log: fix some memory leaks on error handling paths - restore I_VERSION on remount - fix return values and error code mixups - fix umount crash with quotas enabled when removing sysfs files - fix trim range on a shrunk device" * tag 'for-5.9-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux: btrfs: trim: fix underflow in trim length to prevent access beyond device boundary btrfs: fix return value mixup in btrfs_get_extent btrfs: sysfs: fix NULL pointer dereference at btrfs_sysfs_del_qgroups() btrfs: check correct variable after allocation in btrfs_backref_iter_alloc btrfs: make sure SB_I_VERSION doesn't get unset by remount btrfs: fix memory leaks after failure to lookup checksums during inode logging btrfs: don't show full path of bind mounts in subvol= btrfs: fix messages after changing compression level by remount btrfs: only search for left_info if there is no right_info in try_merge_free_space btrfs: inode: fix NULL pointer dereference if inode doesn't need compression
2 parents 69307ad + c57dd1f commit 23c2c8c

File tree

9 files changed

+65
-25
lines changed

9 files changed

+65
-25
lines changed

fs/btrfs/backref.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2303,7 +2303,7 @@ struct btrfs_backref_iter *btrfs_backref_iter_alloc(
23032303
return NULL;
23042304

23052305
ret->path = btrfs_alloc_path();
2306-
if (!ret) {
2306+
if (!ret->path) {
23072307
kfree(ret);
23082308
return NULL;
23092309
}

fs/btrfs/extent-io-tree.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ struct io_failure_record;
3434
*/
3535
#define CHUNK_ALLOCATED EXTENT_DIRTY
3636
#define CHUNK_TRIMMED EXTENT_DEFRAG
37+
#define CHUNK_STATE_MASK (CHUNK_ALLOCATED | \
38+
CHUNK_TRIMMED)
3739

3840
enum {
3941
IO_TREE_FS_PINNED_EXTENTS,

fs/btrfs/extent-tree.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include "delalloc-space.h"
3434
#include "block-group.h"
3535
#include "discard.h"
36+
#include "rcu-string.h"
3637

3738
#undef SCRAMBLE_DELAYED_REFS
3839

@@ -5668,6 +5669,19 @@ static int btrfs_trim_free_extents(struct btrfs_device *device, u64 *trimmed)
56685669
&start, &end,
56695670
CHUNK_TRIMMED | CHUNK_ALLOCATED);
56705671

5672+
/* Check if there are any CHUNK_* bits left */
5673+
if (start > device->total_bytes) {
5674+
WARN_ON(IS_ENABLED(CONFIG_BTRFS_DEBUG));
5675+
btrfs_warn_in_rcu(fs_info,
5676+
"ignoring attempt to trim beyond device size: offset %llu length %llu device %s device size %llu",
5677+
start, end - start + 1,
5678+
rcu_str_deref(device->name),
5679+
device->total_bytes);
5680+
mutex_unlock(&fs_info->chunk_mutex);
5681+
ret = 0;
5682+
break;
5683+
}
5684+
56715685
/* Ensure we skip the reserved area in the first 1M */
56725686
start = max_t(u64, start, SZ_1M);
56735687

fs/btrfs/free-space-cache.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2282,7 +2282,7 @@ static int insert_into_bitmap(struct btrfs_free_space_ctl *ctl,
22822282
static bool try_merge_free_space(struct btrfs_free_space_ctl *ctl,
22832283
struct btrfs_free_space *info, bool update_stat)
22842284
{
2285-
struct btrfs_free_space *left_info;
2285+
struct btrfs_free_space *left_info = NULL;
22862286
struct btrfs_free_space *right_info;
22872287
bool merged = false;
22882288
u64 offset = info->offset;
@@ -2298,7 +2298,7 @@ static bool try_merge_free_space(struct btrfs_free_space_ctl *ctl,
22982298
if (right_info && rb_prev(&right_info->offset_index))
22992299
left_info = rb_entry(rb_prev(&right_info->offset_index),
23002300
struct btrfs_free_space, offset_index);
2301-
else
2301+
else if (!right_info)
23022302
left_info = tree_search_offset(ctl, offset - 1, 0, 0);
23032303

23042304
/* See try_merge_free_space() comment. */

fs/btrfs/inode.c

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -654,12 +654,18 @@ static noinline int compress_file_range(struct async_chunk *async_chunk)
654654
page_error_op |
655655
PAGE_END_WRITEBACK);
656656

657-
for (i = 0; i < nr_pages; i++) {
658-
WARN_ON(pages[i]->mapping);
659-
put_page(pages[i]);
657+
/*
658+
* Ensure we only free the compressed pages if we have
659+
* them allocated, as we can still reach here with
660+
* inode_need_compress() == false.
661+
*/
662+
if (pages) {
663+
for (i = 0; i < nr_pages; i++) {
664+
WARN_ON(pages[i]->mapping);
665+
put_page(pages[i]);
666+
}
667+
kfree(pages);
660668
}
661-
kfree(pages);
662-
663669
return 0;
664670
}
665671
}
@@ -6622,7 +6628,7 @@ struct extent_map *btrfs_get_extent(struct btrfs_inode *inode,
66226628
extent_type == BTRFS_FILE_EXTENT_PREALLOC) {
66236629
/* Only regular file could have regular/prealloc extent */
66246630
if (!S_ISREG(inode->vfs_inode.i_mode)) {
6625-
ret = -EUCLEAN;
6631+
err = -EUCLEAN;
66266632
btrfs_crit(fs_info,
66276633
"regular/prealloc extent found for non-regular inode %llu",
66286634
btrfs_ino(inode));

fs/btrfs/super.c

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,7 @@ int btrfs_parse_options(struct btrfs_fs_info *info, char *options,
517517
char *compress_type;
518518
bool compress_force = false;
519519
enum btrfs_compression_type saved_compress_type;
520+
int saved_compress_level;
520521
bool saved_compress_force;
521522
int no_compress = 0;
522523

@@ -598,6 +599,7 @@ int btrfs_parse_options(struct btrfs_fs_info *info, char *options,
598599
info->compress_type : BTRFS_COMPRESS_NONE;
599600
saved_compress_force =
600601
btrfs_test_opt(info, FORCE_COMPRESS);
602+
saved_compress_level = info->compress_level;
601603
if (token == Opt_compress ||
602604
token == Opt_compress_force ||
603605
strncmp(args[0].from, "zlib", 4) == 0) {
@@ -642,6 +644,8 @@ int btrfs_parse_options(struct btrfs_fs_info *info, char *options,
642644
no_compress = 0;
643645
} else if (strncmp(args[0].from, "no", 2) == 0) {
644646
compress_type = "no";
647+
info->compress_level = 0;
648+
info->compress_type = 0;
645649
btrfs_clear_opt(info->mount_opt, COMPRESS);
646650
btrfs_clear_opt(info->mount_opt, FORCE_COMPRESS);
647651
compress_force = false;
@@ -662,11 +666,11 @@ int btrfs_parse_options(struct btrfs_fs_info *info, char *options,
662666
*/
663667
btrfs_clear_opt(info->mount_opt, FORCE_COMPRESS);
664668
}
665-
if ((btrfs_test_opt(info, COMPRESS) &&
666-
(info->compress_type != saved_compress_type ||
667-
compress_force != saved_compress_force)) ||
668-
(!btrfs_test_opt(info, COMPRESS) &&
669-
no_compress == 1)) {
669+
if (no_compress == 1) {
670+
btrfs_info(info, "use no compression");
671+
} else if ((info->compress_type != saved_compress_type) ||
672+
(compress_force != saved_compress_force) ||
673+
(info->compress_level != saved_compress_level)) {
670674
btrfs_info(info, "%s %s compression, level %d",
671675
(compress_force) ? "force" : "use",
672676
compress_type, info->compress_level);
@@ -1382,6 +1386,7 @@ static int btrfs_show_options(struct seq_file *seq, struct dentry *dentry)
13821386
{
13831387
struct btrfs_fs_info *info = btrfs_sb(dentry->d_sb);
13841388
const char *compress_type;
1389+
const char *subvol_name;
13851390

13861391
if (btrfs_test_opt(info, DEGRADED))
13871392
seq_puts(seq, ",degraded");
@@ -1468,8 +1473,13 @@ static int btrfs_show_options(struct seq_file *seq, struct dentry *dentry)
14681473
seq_puts(seq, ",ref_verify");
14691474
seq_printf(seq, ",subvolid=%llu",
14701475
BTRFS_I(d_inode(dentry))->root->root_key.objectid);
1471-
seq_puts(seq, ",subvol=");
1472-
seq_dentry(seq, dentry, " \t\n\\");
1476+
subvol_name = btrfs_get_subvol_name_from_objectid(info,
1477+
BTRFS_I(d_inode(dentry))->root->root_key.objectid);
1478+
if (!IS_ERR(subvol_name)) {
1479+
seq_puts(seq, ",subvol=");
1480+
seq_escape(seq, subvol_name, " \t\n\\");
1481+
kfree(subvol_name);
1482+
}
14731483
return 0;
14741484
}
14751485

@@ -1950,6 +1960,12 @@ static int btrfs_remount(struct super_block *sb, int *flags, char *data)
19501960
set_bit(BTRFS_FS_OPEN, &fs_info->flags);
19511961
}
19521962
out:
1963+
/*
1964+
* We need to set SB_I_VERSION here otherwise it'll get cleared by VFS,
1965+
* since the absence of the flag means it can be toggled off by remount.
1966+
*/
1967+
*flags |= SB_I_VERSION;
1968+
19531969
wake_up_process(fs_info->transaction_kthread);
19541970
btrfs_remount_cleanup(fs_info, old_opts);
19551971
clear_bit(BTRFS_FS_STATE_REMOUNTING, &fs_info->fs_state);

fs/btrfs/sysfs.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1565,9 +1565,11 @@ void btrfs_sysfs_del_qgroups(struct btrfs_fs_info *fs_info)
15651565
rbtree_postorder_for_each_entry_safe(qgroup, next,
15661566
&fs_info->qgroup_tree, node)
15671567
btrfs_sysfs_del_one_qgroup(fs_info, qgroup);
1568-
kobject_del(fs_info->qgroups_kobj);
1569-
kobject_put(fs_info->qgroups_kobj);
1570-
fs_info->qgroups_kobj = NULL;
1568+
if (fs_info->qgroups_kobj) {
1569+
kobject_del(fs_info->qgroups_kobj);
1570+
kobject_put(fs_info->qgroups_kobj);
1571+
fs_info->qgroups_kobj = NULL;
1572+
}
15711573
}
15721574

15731575
/* Called when qgroups get initialized, thus there is no need for locking */

fs/btrfs/tree-log.c

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4036,11 +4036,8 @@ static noinline int copy_items(struct btrfs_trans_handle *trans,
40364036
fs_info->csum_root,
40374037
ds + cs, ds + cs + cl - 1,
40384038
&ordered_sums, 0);
4039-
if (ret) {
4040-
btrfs_release_path(dst_path);
4041-
kfree(ins_data);
4042-
return ret;
4043-
}
4039+
if (ret)
4040+
break;
40444041
}
40454042
}
40464043
}
@@ -4053,7 +4050,6 @@ static noinline int copy_items(struct btrfs_trans_handle *trans,
40534050
* we have to do this after the loop above to avoid changing the
40544051
* log tree while trying to change the log tree.
40554052
*/
4056-
ret = 0;
40574053
while (!list_empty(&ordered_sums)) {
40584054
struct btrfs_ordered_sum *sums = list_entry(ordered_sums.next,
40594055
struct btrfs_ordered_sum,

fs/btrfs/volumes.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4720,6 +4720,10 @@ int btrfs_shrink_device(struct btrfs_device *device, u64 new_size)
47204720
}
47214721

47224722
mutex_lock(&fs_info->chunk_mutex);
4723+
/* Clear all state bits beyond the shrunk device size */
4724+
clear_extent_bits(&device->alloc_state, new_size, (u64)-1,
4725+
CHUNK_STATE_MASK);
4726+
47234727
btrfs_device_set_disk_total_bytes(device, new_size);
47244728
if (list_empty(&device->post_commit_list))
47254729
list_add_tail(&device->post_commit_list,

0 commit comments

Comments
 (0)