Skip to content

Commit 4e46774

Browse files
committed
Merge tag 'for-6.12-rc4-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux
Pull btrfs fixes from David Sterba: - mount option fixes: - fix handling of compression mount options on remount - reject rw remount in case there are options that don't work in read-write mode (like rescue options) - fix zone accounting of unusable space - fix in-memory corruption when merging extent maps - fix delalloc range locking for sector < page - use more convenient default value of drop subtree threshold, clean more subvolumes without the fallback to marking quotas inconsistent - fix smatch warning about incorrect value passed to ERR_PTR * tag 'for-6.12-rc4-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux: btrfs: fix passing 0 to ERR_PTR in btrfs_search_dir_index_item() btrfs: reject ro->rw reconfiguration if there are hard ro requirements btrfs: fix read corruption due to race with extent map merging btrfs: fix the delalloc range locking if sector size < page size btrfs: qgroup: set a more sane default value for subtree drop threshold btrfs: clear force-compress on remount when compress mount option is given btrfs: zoned: fix zone unusable accounting for freed reserved extent
2 parents 6cc65ab + 75f49c3 commit 4e46774

File tree

9 files changed

+45
-34
lines changed

9 files changed

+45
-34
lines changed

fs/btrfs/block-group.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3819,6 +3819,8 @@ void btrfs_free_reserved_bytes(struct btrfs_block_group *cache,
38193819
spin_lock(&cache->lock);
38203820
if (cache->ro)
38213821
space_info->bytes_readonly += num_bytes;
3822+
else if (btrfs_is_zoned(cache->fs_info))
3823+
space_info->bytes_zone_unusable += num_bytes;
38223824
cache->reserved -= num_bytes;
38233825
space_info->bytes_reserved -= num_bytes;
38243826
space_info->max_extent_size = 0;

fs/btrfs/dir-item.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -347,8 +347,8 @@ btrfs_search_dir_index_item(struct btrfs_root *root, struct btrfs_path *path,
347347
return di;
348348
}
349349
/* Adjust return code if the key was not found in the next leaf. */
350-
if (ret > 0)
351-
ret = 0;
350+
if (ret >= 0)
351+
ret = -ENOENT;
352352

353353
return ERR_PTR(ret);
354354
}

fs/btrfs/disk-io.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1959,7 +1959,7 @@ static void btrfs_init_qgroup(struct btrfs_fs_info *fs_info)
19591959
fs_info->qgroup_seq = 1;
19601960
fs_info->qgroup_ulist = NULL;
19611961
fs_info->qgroup_rescan_running = false;
1962-
fs_info->qgroup_drop_subtree_thres = BTRFS_MAX_LEVEL;
1962+
fs_info->qgroup_drop_subtree_thres = BTRFS_QGROUP_DROP_SUBTREE_THRES_DEFAULT;
19631963
mutex_init(&fs_info->qgroup_rescan_lock);
19641964
}
19651965

fs/btrfs/extent_io.c

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -262,22 +262,23 @@ static noinline int lock_delalloc_folios(struct inode *inode,
262262

263263
for (i = 0; i < found_folios; i++) {
264264
struct folio *folio = fbatch.folios[i];
265-
u32 len = end + 1 - start;
265+
u64 range_start;
266+
u32 range_len;
266267

267268
if (folio == locked_folio)
268269
continue;
269270

270-
if (btrfs_folio_start_writer_lock(fs_info, folio, start,
271-
len))
272-
goto out;
273-
271+
folio_lock(folio);
274272
if (!folio_test_dirty(folio) || folio->mapping != mapping) {
275-
btrfs_folio_end_writer_lock(fs_info, folio, start,
276-
len);
273+
folio_unlock(folio);
277274
goto out;
278275
}
276+
range_start = max_t(u64, folio_pos(folio), start);
277+
range_len = min_t(u64, folio_pos(folio) + folio_size(folio),
278+
end + 1) - range_start;
279+
btrfs_folio_set_writer_lock(fs_info, folio, range_start, range_len);
279280

280-
processed_end = folio_pos(folio) + folio_size(folio) - 1;
281+
processed_end = range_start + range_len - 1;
281282
}
282283
folio_batch_release(&fbatch);
283284
cond_resched();

fs/btrfs/extent_map.c

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -243,13 +243,19 @@ static bool mergeable_maps(const struct extent_map *prev, const struct extent_ma
243243
/*
244244
* Handle the on-disk data extents merge for @prev and @next.
245245
*
246+
* @prev: left extent to merge
247+
* @next: right extent to merge
248+
* @merged: the extent we will not discard after the merge; updated with new values
249+
*
250+
* After this, one of the two extents is the new merged extent and the other is
251+
* removed from the tree and likely freed. Note that @merged is one of @prev/@next
252+
* so there is const/non-const aliasing occurring here.
253+
*
246254
* Only touches disk_bytenr/disk_num_bytes/offset/ram_bytes.
247255
* For now only uncompressed regular extent can be merged.
248-
*
249-
* @prev and @next will be both updated to point to the new merged range.
250-
* Thus one of them should be removed by the caller.
251256
*/
252-
static void merge_ondisk_extents(struct extent_map *prev, struct extent_map *next)
257+
static void merge_ondisk_extents(const struct extent_map *prev, const struct extent_map *next,
258+
struct extent_map *merged)
253259
{
254260
u64 new_disk_bytenr;
255261
u64 new_disk_num_bytes;
@@ -284,15 +290,10 @@ static void merge_ondisk_extents(struct extent_map *prev, struct extent_map *nex
284290
new_disk_bytenr;
285291
new_offset = prev->disk_bytenr + prev->offset - new_disk_bytenr;
286292

287-
prev->disk_bytenr = new_disk_bytenr;
288-
prev->disk_num_bytes = new_disk_num_bytes;
289-
prev->ram_bytes = new_disk_num_bytes;
290-
prev->offset = new_offset;
291-
292-
next->disk_bytenr = new_disk_bytenr;
293-
next->disk_num_bytes = new_disk_num_bytes;
294-
next->ram_bytes = new_disk_num_bytes;
295-
next->offset = new_offset;
293+
merged->disk_bytenr = new_disk_bytenr;
294+
merged->disk_num_bytes = new_disk_num_bytes;
295+
merged->ram_bytes = new_disk_num_bytes;
296+
merged->offset = new_offset;
296297
}
297298

298299
static void dump_extent_map(struct btrfs_fs_info *fs_info, const char *prefix,
@@ -361,7 +362,7 @@ static void try_merge_map(struct btrfs_inode *inode, struct extent_map *em)
361362
em->generation = max(em->generation, merge->generation);
362363

363364
if (em->disk_bytenr < EXTENT_MAP_LAST_BYTE)
364-
merge_ondisk_extents(merge, em);
365+
merge_ondisk_extents(merge, em, em);
365366
em->flags |= EXTENT_FLAG_MERGED;
366367

367368
validate_extent_map(fs_info, em);
@@ -378,7 +379,7 @@ static void try_merge_map(struct btrfs_inode *inode, struct extent_map *em)
378379
if (rb && can_merge_extent_map(merge) && mergeable_maps(em, merge)) {
379380
em->len += merge->len;
380381
if (em->disk_bytenr < EXTENT_MAP_LAST_BYTE)
381-
merge_ondisk_extents(em, merge);
382+
merge_ondisk_extents(em, merge, em);
382383
validate_extent_map(fs_info, em);
383384
rb_erase(&merge->rb_node, &tree->root);
384385
RB_CLEAR_NODE(&merge->rb_node);

fs/btrfs/inode.c

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4368,11 +4368,8 @@ static int btrfs_unlink_subvol(struct btrfs_trans_handle *trans,
43684368
*/
43694369
if (btrfs_ino(inode) == BTRFS_EMPTY_SUBVOL_DIR_OBJECTID) {
43704370
di = btrfs_search_dir_index_item(root, path, dir_ino, &fname.disk_name);
4371-
if (IS_ERR_OR_NULL(di)) {
4372-
if (!di)
4373-
ret = -ENOENT;
4374-
else
4375-
ret = PTR_ERR(di);
4371+
if (IS_ERR(di)) {
4372+
ret = PTR_ERR(di);
43764373
btrfs_abort_transaction(trans, ret);
43774374
goto out;
43784375
}

fs/btrfs/qgroup.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1407,7 +1407,7 @@ int btrfs_quota_disable(struct btrfs_fs_info *fs_info)
14071407
fs_info->quota_root = NULL;
14081408
fs_info->qgroup_flags &= ~BTRFS_QGROUP_STATUS_FLAG_ON;
14091409
fs_info->qgroup_flags &= ~BTRFS_QGROUP_STATUS_FLAG_SIMPLE_MODE;
1410-
fs_info->qgroup_drop_subtree_thres = BTRFS_MAX_LEVEL;
1410+
fs_info->qgroup_drop_subtree_thres = BTRFS_QGROUP_DROP_SUBTREE_THRES_DEFAULT;
14111411
spin_unlock(&fs_info->qgroup_lock);
14121412

14131413
btrfs_free_qgroup_config(fs_info);

fs/btrfs/qgroup.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,8 @@ struct btrfs_inode;
121121
#define BTRFS_QGROUP_RUNTIME_FLAG_CANCEL_RESCAN (1ULL << 63)
122122
#define BTRFS_QGROUP_RUNTIME_FLAG_NO_ACCOUNTING (1ULL << 62)
123123

124+
#define BTRFS_QGROUP_DROP_SUBTREE_THRES_DEFAULT (3)
125+
124126
/*
125127
* Record a dirty extent, and info qgroup to update quota on it
126128
*/

fs/btrfs/super.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,15 @@ static int btrfs_parse_param(struct fs_context *fc, struct fs_parameter *param)
340340
fallthrough;
341341
case Opt_compress:
342342
case Opt_compress_type:
343+
/*
344+
* Provide the same semantics as older kernels that don't use fs
345+
* context, specifying the "compress" option clears
346+
* "force-compress" without the need to pass
347+
* "compress-force=[no|none]" before specifying "compress".
348+
*/
349+
if (opt != Opt_compress_force && opt != Opt_compress_force_type)
350+
btrfs_clear_opt(ctx->mount_opt, FORCE_COMPRESS);
351+
343352
if (opt == Opt_compress || opt == Opt_compress_force) {
344353
ctx->compress_type = BTRFS_COMPRESS_ZLIB;
345354
ctx->compress_level = BTRFS_ZLIB_DEFAULT_LEVEL;
@@ -1498,8 +1507,7 @@ static int btrfs_reconfigure(struct fs_context *fc)
14981507
sync_filesystem(sb);
14991508
set_bit(BTRFS_FS_STATE_REMOUNTING, &fs_info->fs_state);
15001509

1501-
if (!mount_reconfigure &&
1502-
!btrfs_check_options(fs_info, &ctx->mount_opt, fc->sb_flags))
1510+
if (!btrfs_check_options(fs_info, &ctx->mount_opt, fc->sb_flags))
15031511
return -EINVAL;
15041512

15051513
ret = btrfs_check_features(fs_info, !(fc->sb_flags & SB_RDONLY));

0 commit comments

Comments
 (0)