Commit 661e504d authored by Linus Torvalds's avatar Linus Torvalds
Browse files
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
parents 033771c0 a56c85fa
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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);
+1 −1
Original line number Diff line number Diff line
@@ -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:
+8 −2
Original line number Diff line number Diff line
@@ -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)
@@ -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:
	 *
+7 −2
Original line number Diff line number Diff line
@@ -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);
@@ -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");
+21 −3
Original line number Diff line number Diff line
@@ -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);
	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
@@ -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;
}