Skip to content

Commit

Permalink
Merge tag 'for-6.10-rc6-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:

 - fix folio refcounting when releasing them (encoded write, dummy
   extent buffer)

 - fix out of bounds read when checking qgroup inherit data

 - fix how configurable chunk size is handled in zoned mode

 - in the ref-verify tool, fix uninitialized return value when checking
   extent owner ref and simple quota are not enabled

* tag 'for-6.10-rc6-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux:
  btrfs: fix folio refcount in __alloc_dummy_extent_buffer()
  btrfs: fix folio refcount in btrfs_do_encoded_write()
  btrfs: fix uninitialized return value in the ref-verify tool
  btrfs: always do the basic checks for btrfs_qgroup_inherit structure
  btrfs: zoned: fix calc_available_free_space() for zoned mode
  • Loading branch information
torvalds committed Jul 4, 2024
2 parents 033771c + a56c85f commit 661e504
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 9 deletions.
2 changes: 1 addition & 1 deletion fs/btrfs/extent_io.c
Original file line number Diff line number Diff line change
Expand Up @@ -3553,7 +3553,7 @@ struct extent_buffer *__alloc_dummy_extent_buffer(struct btrfs_fs_info *fs_info,
for (int i = 0; i < num_folios; i++) {
if (eb->folios[i]) {
detach_extent_buffer_folio(eb, eb->folios[i]);
__folio_put(eb->folios[i]);
folio_put(eb->folios[i]);
}
}
__free_extent_buffer(eb);
Expand Down
2 changes: 1 addition & 1 deletion fs/btrfs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -10385,7 +10385,7 @@ ssize_t btrfs_do_encoded_write(struct kiocb *iocb, struct iov_iter *from,
out_folios:
for (i = 0; i < nr_folios; i++) {
if (folios[i])
__folio_put(folios[i]);
folio_put(folios[i]);
}
kvfree(folios);
out:
Expand Down
10 changes: 8 additions & 2 deletions fs/btrfs/qgroup.c
Original file line number Diff line number Diff line change
Expand Up @@ -3062,8 +3062,6 @@ int btrfs_qgroup_check_inherit(struct btrfs_fs_info *fs_info,
struct btrfs_qgroup_inherit *inherit,
size_t size)
{
if (!btrfs_qgroup_enabled(fs_info))
return 0;
if (inherit->flags & ~BTRFS_QGROUP_INHERIT_FLAGS_SUPP)
return -EOPNOTSUPP;
if (size < sizeof(*inherit) || size > PAGE_SIZE)
Expand All @@ -3084,6 +3082,14 @@ int btrfs_qgroup_check_inherit(struct btrfs_fs_info *fs_info,
if (size != struct_size(inherit, qgroups, inherit->num_qgroups))
return -EINVAL;

/*
* Skip the inherit source qgroups check if qgroup is not enabled.
* Qgroup can still be later enabled causing problems, but in that case
* btrfs_qgroup_inherit() would just ignore those invalid ones.
*/
if (!btrfs_qgroup_enabled(fs_info))
return 0;

/*
* Now check all the remaining qgroups, they should all:
*
Expand Down
9 changes: 7 additions & 2 deletions fs/btrfs/ref-verify.c
Original file line number Diff line number Diff line change
Expand Up @@ -441,7 +441,8 @@ static int process_extent_item(struct btrfs_fs_info *fs_info,
u32 item_size = btrfs_item_size(leaf, slot);
unsigned long end, ptr;
u64 offset, flags, count;
int type, ret;
int type;
int ret = 0;

ei = btrfs_item_ptr(leaf, slot, struct btrfs_extent_item);
flags = btrfs_extent_flags(leaf, ei);
Expand Down Expand Up @@ -486,7 +487,11 @@ static int process_extent_item(struct btrfs_fs_info *fs_info,
key->objectid, key->offset);
break;
case BTRFS_EXTENT_OWNER_REF_KEY:
WARN_ON(!btrfs_fs_incompat(fs_info, SIMPLE_QUOTA));
if (!btrfs_fs_incompat(fs_info, SIMPLE_QUOTA)) {
btrfs_err(fs_info,
"found extent owner ref without simple quotas enabled");
ret = -EINVAL;
}
break;
default:
btrfs_err(fs_info, "invalid key type in iref");
Expand Down
24 changes: 21 additions & 3 deletions fs/btrfs/space-info.c
Original file line number Diff line number Diff line change
Expand Up @@ -373,11 +373,18 @@ static u64 calc_available_free_space(struct btrfs_fs_info *fs_info,
* "optimal" chunk size based on the fs size. However when we actually
* allocate the chunk we will strip this down further, making it no more
* than 10% of the disk or 1G, whichever is smaller.
*
* On the zoned mode, we need to use zone_size (=
* data_sinfo->chunk_size) as it is.
*/
data_sinfo = btrfs_find_space_info(fs_info, BTRFS_BLOCK_GROUP_DATA);
data_chunk_size = min(data_sinfo->chunk_size,
mult_perc(fs_info->fs_devices->total_rw_bytes, 10));
data_chunk_size = min_t(u64, data_chunk_size, SZ_1G);
if (!btrfs_is_zoned(fs_info)) {
data_chunk_size = min(data_sinfo->chunk_size,
mult_perc(fs_info->fs_devices->total_rw_bytes, 10));
data_chunk_size = min_t(u64, data_chunk_size, SZ_1G);
} else {
data_chunk_size = data_sinfo->chunk_size;
}

/*
* Since data allocations immediately use block groups as part of the
Expand Down Expand Up @@ -405,6 +412,17 @@ static u64 calc_available_free_space(struct btrfs_fs_info *fs_info,
avail >>= 3;
else
avail >>= 1;

/*
* On the zoned mode, we always allocate one zone as one chunk.
* Returning non-zone size alingned bytes here will result in
* less pressure for the async metadata reclaim process, and it
* will over-commit too much leading to ENOSPC. Align down to the
* zone size to avoid that.
*/
if (btrfs_is_zoned(fs_info))
avail = ALIGN_DOWN(avail, fs_info->zone_size);

return avail;
}

Expand Down

0 comments on commit 661e504

Please sign in to comment.