Skip to content

Commit b10c31b

Browse files
committed
Merge tag 'for-6.17-rc5-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux
Pull btrfs fixes from David Sterba: - fix delayed inode tracking in xarray, eviction can race with insertion and leave behind a disconnected inode - on systems with large page (64K) and small block size (4K) fix compression read that can return partially filled folio - slightly relax compression option format for backward compatibility, allow to specify level for LZO although there's only one - fix simple quota accounting of compressed extents - validate minimum device size in 'device add' - update maintainers' entry * tag 'for-6.17-rc5-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux: btrfs: don't allow adding block device of less than 1 MB MAINTAINERS: update btrfs entry btrfs: fix subvolume deletion lockup caused by inodes xarray race btrfs: fix corruption reading compressed range when block size is smaller than page size btrfs: accept and ignore compression level for lzo btrfs: fix squota compressed stats leak
2 parents 02ffd6f + 3d12674 commit b10c31b

File tree

6 files changed

+56
-17
lines changed

6 files changed

+56
-17
lines changed

MAINTAINERS

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5258,7 +5258,6 @@ F: drivers/gpio/gpio-bt8xx.c
52585258

52595259
BTRFS FILE SYSTEM
52605260
M: Chris Mason <[email protected]>
5261-
M: Josef Bacik <[email protected]>
52625261
M: David Sterba <[email protected]>
52635262
52645263
S: Maintained

fs/btrfs/extent_io.c

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,24 @@ struct btrfs_bio_ctrl {
111111
*/
112112
unsigned long submit_bitmap;
113113
struct readahead_control *ractl;
114+
115+
/*
116+
* The start offset of the last used extent map by a read operation.
117+
*
118+
* This is for proper compressed read merge.
119+
* U64_MAX means we are starting the read and have made no progress yet.
120+
*
121+
* The current btrfs_bio_is_contig() only uses disk_bytenr as
122+
* the condition to check if the read can be merged with previous
123+
* bio, which is not correct. E.g. two file extents pointing to the
124+
* same extent but with different offset.
125+
*
126+
* So here we need to do extra checks to only merge reads that are
127+
* covered by the same extent map.
128+
* Just extent_map::start will be enough, as they are unique
129+
* inside the same inode.
130+
*/
131+
u64 last_em_start;
114132
};
115133

116134
static void submit_one_bio(struct btrfs_bio_ctrl *bio_ctrl)
@@ -909,7 +927,7 @@ static void btrfs_readahead_expand(struct readahead_control *ractl,
909927
* return 0 on success, otherwise return error
910928
*/
911929
static int btrfs_do_readpage(struct folio *folio, struct extent_map **em_cached,
912-
struct btrfs_bio_ctrl *bio_ctrl, u64 *prev_em_start)
930+
struct btrfs_bio_ctrl *bio_ctrl)
913931
{
914932
struct inode *inode = folio->mapping->host;
915933
struct btrfs_fs_info *fs_info = inode_to_fs_info(inode);
@@ -1019,12 +1037,11 @@ static int btrfs_do_readpage(struct folio *folio, struct extent_map **em_cached,
10191037
* non-optimal behavior (submitting 2 bios for the same extent).
10201038
*/
10211039
if (compress_type != BTRFS_COMPRESS_NONE &&
1022-
prev_em_start && *prev_em_start != (u64)-1 &&
1023-
*prev_em_start != em->start)
1040+
bio_ctrl->last_em_start != U64_MAX &&
1041+
bio_ctrl->last_em_start != em->start)
10241042
force_bio_submit = true;
10251043

1026-
if (prev_em_start)
1027-
*prev_em_start = em->start;
1044+
bio_ctrl->last_em_start = em->start;
10281045

10291046
btrfs_free_extent_map(em);
10301047
em = NULL;
@@ -1238,12 +1255,15 @@ int btrfs_read_folio(struct file *file, struct folio *folio)
12381255
const u64 start = folio_pos(folio);
12391256
const u64 end = start + folio_size(folio) - 1;
12401257
struct extent_state *cached_state = NULL;
1241-
struct btrfs_bio_ctrl bio_ctrl = { .opf = REQ_OP_READ };
1258+
struct btrfs_bio_ctrl bio_ctrl = {
1259+
.opf = REQ_OP_READ,
1260+
.last_em_start = U64_MAX,
1261+
};
12421262
struct extent_map *em_cached = NULL;
12431263
int ret;
12441264

12451265
lock_extents_for_read(inode, start, end, &cached_state);
1246-
ret = btrfs_do_readpage(folio, &em_cached, &bio_ctrl, NULL);
1266+
ret = btrfs_do_readpage(folio, &em_cached, &bio_ctrl);
12471267
btrfs_unlock_extent(&inode->io_tree, start, end, &cached_state);
12481268

12491269
btrfs_free_extent_map(em_cached);
@@ -2583,20 +2603,20 @@ void btrfs_readahead(struct readahead_control *rac)
25832603
{
25842604
struct btrfs_bio_ctrl bio_ctrl = {
25852605
.opf = REQ_OP_READ | REQ_RAHEAD,
2586-
.ractl = rac
2606+
.ractl = rac,
2607+
.last_em_start = U64_MAX,
25872608
};
25882609
struct folio *folio;
25892610
struct btrfs_inode *inode = BTRFS_I(rac->mapping->host);
25902611
const u64 start = readahead_pos(rac);
25912612
const u64 end = start + readahead_length(rac) - 1;
25922613
struct extent_state *cached_state = NULL;
25932614
struct extent_map *em_cached = NULL;
2594-
u64 prev_em_start = (u64)-1;
25952615

25962616
lock_extents_for_read(inode, start, end, &cached_state);
25972617

25982618
while ((folio = readahead_folio(rac)) != NULL)
2599-
btrfs_do_readpage(folio, &em_cached, &bio_ctrl, &prev_em_start);
2619+
btrfs_do_readpage(folio, &em_cached, &bio_ctrl);
26002620

26012621
btrfs_unlock_extent(&inode->io_tree, start, end, &cached_state);
26022622

fs/btrfs/inode.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5696,7 +5696,17 @@ static void btrfs_del_inode_from_root(struct btrfs_inode *inode)
56965696
bool empty = false;
56975697

56985698
xa_lock(&root->inodes);
5699-
entry = __xa_erase(&root->inodes, btrfs_ino(inode));
5699+
/*
5700+
* This btrfs_inode is being freed and has already been unhashed at this
5701+
* point. It's possible that another btrfs_inode has already been
5702+
* allocated for the same inode and inserted itself into the root, so
5703+
* don't delete it in that case.
5704+
*
5705+
* Note that this shouldn't need to allocate memory, so the gfp flags
5706+
* don't really matter.
5707+
*/
5708+
entry = __xa_cmpxchg(&root->inodes, btrfs_ino(inode), inode, NULL,
5709+
GFP_ATOMIC);
57005710
if (entry == inode)
57015711
empty = xa_empty(&root->inodes);
57025712
xa_unlock(&root->inodes);

fs/btrfs/qgroup.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1455,6 +1455,7 @@ static int __qgroup_excl_accounting(struct btrfs_fs_info *fs_info, u64 ref_root,
14551455
struct btrfs_qgroup *qgroup;
14561456
LIST_HEAD(qgroup_list);
14571457
u64 num_bytes = src->excl;
1458+
u64 num_bytes_cmpr = src->excl_cmpr;
14581459
int ret = 0;
14591460

14601461
qgroup = find_qgroup_rb(fs_info, ref_root);
@@ -1466,11 +1467,12 @@ static int __qgroup_excl_accounting(struct btrfs_fs_info *fs_info, u64 ref_root,
14661467
struct btrfs_qgroup_list *glist;
14671468

14681469
qgroup->rfer += sign * num_bytes;
1469-
qgroup->rfer_cmpr += sign * num_bytes;
1470+
qgroup->rfer_cmpr += sign * num_bytes_cmpr;
14701471

14711472
WARN_ON(sign < 0 && qgroup->excl < num_bytes);
1473+
WARN_ON(sign < 0 && qgroup->excl_cmpr < num_bytes_cmpr);
14721474
qgroup->excl += sign * num_bytes;
1473-
qgroup->excl_cmpr += sign * num_bytes;
1475+
qgroup->excl_cmpr += sign * num_bytes_cmpr;
14741476

14751477
if (sign > 0)
14761478
qgroup_rsv_add_by_qgroup(fs_info, qgroup, src);

fs/btrfs/super.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -299,9 +299,12 @@ static int btrfs_parse_compress(struct btrfs_fs_context *ctx,
299299
btrfs_set_opt(ctx->mount_opt, COMPRESS);
300300
btrfs_clear_opt(ctx->mount_opt, NODATACOW);
301301
btrfs_clear_opt(ctx->mount_opt, NODATASUM);
302-
} else if (btrfs_match_compress_type(string, "lzo", false)) {
302+
} else if (btrfs_match_compress_type(string, "lzo", true)) {
303303
ctx->compress_type = BTRFS_COMPRESS_LZO;
304-
ctx->compress_level = 0;
304+
ctx->compress_level = btrfs_compress_str2level(BTRFS_COMPRESS_LZO,
305+
string + 3);
306+
if (string[3] == ':' && string[4])
307+
btrfs_warn(NULL, "Compression level ignored for LZO");
305308
btrfs_set_opt(ctx->mount_opt, COMPRESS);
306309
btrfs_clear_opt(ctx->mount_opt, NODATACOW);
307310
btrfs_clear_opt(ctx->mount_opt, NODATASUM);
@@ -1079,7 +1082,7 @@ static int btrfs_show_options(struct seq_file *seq, struct dentry *dentry)
10791082
seq_printf(seq, ",compress-force=%s", compress_type);
10801083
else
10811084
seq_printf(seq, ",compress=%s", compress_type);
1082-
if (info->compress_level)
1085+
if (info->compress_level && info->compress_type != BTRFS_COMPRESS_LZO)
10831086
seq_printf(seq, ":%d", info->compress_level);
10841087
}
10851088
if (btrfs_test_opt(info, NOSSD))

fs/btrfs/volumes.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2722,6 +2722,11 @@ int btrfs_init_new_device(struct btrfs_fs_info *fs_info, const char *device_path
27222722
goto error;
27232723
}
27242724

2725+
if (bdev_nr_bytes(file_bdev(bdev_file)) <= BTRFS_DEVICE_RANGE_RESERVED) {
2726+
ret = -EINVAL;
2727+
goto error;
2728+
}
2729+
27252730
if (fs_devices->seeding) {
27262731
seeding_dev = true;
27272732
down_write(&sb->s_umount);

0 commit comments

Comments
 (0)