Skip to content

Commit

Permalink
Merge tag 'for-6.12-rc4-tag' of git://git.kernel.org/pub/scm/linux/ke…
Browse files Browse the repository at this point in the history
…rnel/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
  • Loading branch information
torvalds committed Oct 24, 2024
2 parents 6cc65ab + 75f49c3 commit 4e46774
Show file tree
Hide file tree
Showing 9 changed files with 45 additions and 34 deletions.
2 changes: 2 additions & 0 deletions fs/btrfs/block-group.c
Original file line number Diff line number Diff line change
Expand Up @@ -3819,6 +3819,8 @@ void btrfs_free_reserved_bytes(struct btrfs_block_group *cache,
spin_lock(&cache->lock);
if (cache->ro)
space_info->bytes_readonly += num_bytes;
else if (btrfs_is_zoned(cache->fs_info))
space_info->bytes_zone_unusable += num_bytes;
cache->reserved -= num_bytes;
space_info->bytes_reserved -= num_bytes;
space_info->max_extent_size = 0;
Expand Down
4 changes: 2 additions & 2 deletions fs/btrfs/dir-item.c
Original file line number Diff line number Diff line change
Expand Up @@ -347,8 +347,8 @@ btrfs_search_dir_index_item(struct btrfs_root *root, struct btrfs_path *path,
return di;
}
/* Adjust return code if the key was not found in the next leaf. */
if (ret > 0)
ret = 0;
if (ret >= 0)
ret = -ENOENT;

return ERR_PTR(ret);
}
Expand Down
2 changes: 1 addition & 1 deletion fs/btrfs/disk-io.c
Original file line number Diff line number Diff line change
Expand Up @@ -1959,7 +1959,7 @@ static void btrfs_init_qgroup(struct btrfs_fs_info *fs_info)
fs_info->qgroup_seq = 1;
fs_info->qgroup_ulist = NULL;
fs_info->qgroup_rescan_running = false;
fs_info->qgroup_drop_subtree_thres = BTRFS_MAX_LEVEL;
fs_info->qgroup_drop_subtree_thres = BTRFS_QGROUP_DROP_SUBTREE_THRES_DEFAULT;
mutex_init(&fs_info->qgroup_rescan_lock);
}

Expand Down
17 changes: 9 additions & 8 deletions fs/btrfs/extent_io.c
Original file line number Diff line number Diff line change
Expand Up @@ -262,22 +262,23 @@ static noinline int lock_delalloc_folios(struct inode *inode,

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

if (folio == locked_folio)
continue;

if (btrfs_folio_start_writer_lock(fs_info, folio, start,
len))
goto out;

folio_lock(folio);
if (!folio_test_dirty(folio) || folio->mapping != mapping) {
btrfs_folio_end_writer_lock(fs_info, folio, start,
len);
folio_unlock(folio);
goto out;
}
range_start = max_t(u64, folio_pos(folio), start);
range_len = min_t(u64, folio_pos(folio) + folio_size(folio),
end + 1) - range_start;
btrfs_folio_set_writer_lock(fs_info, folio, range_start, range_len);

processed_end = folio_pos(folio) + folio_size(folio) - 1;
processed_end = range_start + range_len - 1;
}
folio_batch_release(&fbatch);
cond_resched();
Expand Down
31 changes: 16 additions & 15 deletions fs/btrfs/extent_map.c
Original file line number Diff line number Diff line change
Expand Up @@ -243,13 +243,19 @@ static bool mergeable_maps(const struct extent_map *prev, const struct extent_ma
/*
* Handle the on-disk data extents merge for @prev and @next.
*
* @prev: left extent to merge
* @next: right extent to merge
* @merged: the extent we will not discard after the merge; updated with new values
*
* After this, one of the two extents is the new merged extent and the other is
* removed from the tree and likely freed. Note that @merged is one of @prev/@next
* so there is const/non-const aliasing occurring here.
*
* Only touches disk_bytenr/disk_num_bytes/offset/ram_bytes.
* For now only uncompressed regular extent can be merged.
*
* @prev and @next will be both updated to point to the new merged range.
* Thus one of them should be removed by the caller.
*/
static void merge_ondisk_extents(struct extent_map *prev, struct extent_map *next)
static void merge_ondisk_extents(const struct extent_map *prev, const struct extent_map *next,
struct extent_map *merged)
{
u64 new_disk_bytenr;
u64 new_disk_num_bytes;
Expand Down Expand Up @@ -284,15 +290,10 @@ static void merge_ondisk_extents(struct extent_map *prev, struct extent_map *nex
new_disk_bytenr;
new_offset = prev->disk_bytenr + prev->offset - new_disk_bytenr;

prev->disk_bytenr = new_disk_bytenr;
prev->disk_num_bytes = new_disk_num_bytes;
prev->ram_bytes = new_disk_num_bytes;
prev->offset = new_offset;

next->disk_bytenr = new_disk_bytenr;
next->disk_num_bytes = new_disk_num_bytes;
next->ram_bytes = new_disk_num_bytes;
next->offset = new_offset;
merged->disk_bytenr = new_disk_bytenr;
merged->disk_num_bytes = new_disk_num_bytes;
merged->ram_bytes = new_disk_num_bytes;
merged->offset = new_offset;
}

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

if (em->disk_bytenr < EXTENT_MAP_LAST_BYTE)
merge_ondisk_extents(merge, em);
merge_ondisk_extents(merge, em, em);
em->flags |= EXTENT_FLAG_MERGED;

validate_extent_map(fs_info, em);
Expand All @@ -378,7 +379,7 @@ static void try_merge_map(struct btrfs_inode *inode, struct extent_map *em)
if (rb && can_merge_extent_map(merge) && mergeable_maps(em, merge)) {
em->len += merge->len;
if (em->disk_bytenr < EXTENT_MAP_LAST_BYTE)
merge_ondisk_extents(em, merge);
merge_ondisk_extents(em, merge, em);
validate_extent_map(fs_info, em);
rb_erase(&merge->rb_node, &tree->root);
RB_CLEAR_NODE(&merge->rb_node);
Expand Down
7 changes: 2 additions & 5 deletions fs/btrfs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -4368,11 +4368,8 @@ static int btrfs_unlink_subvol(struct btrfs_trans_handle *trans,
*/
if (btrfs_ino(inode) == BTRFS_EMPTY_SUBVOL_DIR_OBJECTID) {
di = btrfs_search_dir_index_item(root, path, dir_ino, &fname.disk_name);
if (IS_ERR_OR_NULL(di)) {
if (!di)
ret = -ENOENT;
else
ret = PTR_ERR(di);
if (IS_ERR(di)) {
ret = PTR_ERR(di);
btrfs_abort_transaction(trans, ret);
goto out;
}
Expand Down
2 changes: 1 addition & 1 deletion fs/btrfs/qgroup.c
Original file line number Diff line number Diff line change
Expand Up @@ -1407,7 +1407,7 @@ int btrfs_quota_disable(struct btrfs_fs_info *fs_info)
fs_info->quota_root = NULL;
fs_info->qgroup_flags &= ~BTRFS_QGROUP_STATUS_FLAG_ON;
fs_info->qgroup_flags &= ~BTRFS_QGROUP_STATUS_FLAG_SIMPLE_MODE;
fs_info->qgroup_drop_subtree_thres = BTRFS_MAX_LEVEL;
fs_info->qgroup_drop_subtree_thres = BTRFS_QGROUP_DROP_SUBTREE_THRES_DEFAULT;
spin_unlock(&fs_info->qgroup_lock);

btrfs_free_qgroup_config(fs_info);
Expand Down
2 changes: 2 additions & 0 deletions fs/btrfs/qgroup.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,8 @@ struct btrfs_inode;
#define BTRFS_QGROUP_RUNTIME_FLAG_CANCEL_RESCAN (1ULL << 63)
#define BTRFS_QGROUP_RUNTIME_FLAG_NO_ACCOUNTING (1ULL << 62)

#define BTRFS_QGROUP_DROP_SUBTREE_THRES_DEFAULT (3)

/*
* Record a dirty extent, and info qgroup to update quota on it
*/
Expand Down
12 changes: 10 additions & 2 deletions fs/btrfs/super.c
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,15 @@ static int btrfs_parse_param(struct fs_context *fc, struct fs_parameter *param)
fallthrough;
case Opt_compress:
case Opt_compress_type:
/*
* Provide the same semantics as older kernels that don't use fs
* context, specifying the "compress" option clears
* "force-compress" without the need to pass
* "compress-force=[no|none]" before specifying "compress".
*/
if (opt != Opt_compress_force && opt != Opt_compress_force_type)
btrfs_clear_opt(ctx->mount_opt, FORCE_COMPRESS);

if (opt == Opt_compress || opt == Opt_compress_force) {
ctx->compress_type = BTRFS_COMPRESS_ZLIB;
ctx->compress_level = BTRFS_ZLIB_DEFAULT_LEVEL;
Expand Down Expand Up @@ -1498,8 +1507,7 @@ static int btrfs_reconfigure(struct fs_context *fc)
sync_filesystem(sb);
set_bit(BTRFS_FS_STATE_REMOUNTING, &fs_info->fs_state);

if (!mount_reconfigure &&
!btrfs_check_options(fs_info, &ctx->mount_opt, fc->sb_flags))
if (!btrfs_check_options(fs_info, &ctx->mount_opt, fc->sb_flags))
return -EINVAL;

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

0 comments on commit 4e46774

Please sign in to comment.