Commit 28506304 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull btrfs fixes from David Sterba:
 "A few more fixes, the zoned accounting fix is spread across a few
  patches, preparatory and the actual fixes:

   - zoned mode:
      - fix accounting of unusable zone space
      - fix zone activation condition for DUP profile
      - preparatory patches

   - improved error handling of missing chunks

   - fix compiler warning"

* tag 'for-6.3-rc3-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux:
  btrfs: zoned: drop space_info->active_total_bytes
  btrfs: zoned: count fresh BG region as zone unusable
  btrfs: use temporary variable for space_info in btrfs_update_block_group
  btrfs: rename BTRFS_FS_NO_OVERCOMMIT to BTRFS_FS_ACTIVE_ZONE_TRACKING
  btrfs: zoned: fix btrfs_can_activate_zone() to support DUP profile
  btrfs: fix compiler warning on SPARC/PA-RISC handling fscrypt_setup_filename
  btrfs: handle missing chunk mapping more gracefully
parents 6dd74c51 e15acc25
Loading
Loading
Loading
Loading
+12 −16
Original line number Diff line number Diff line
@@ -1175,14 +1175,8 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans,
			< block_group->zone_unusable);
		WARN_ON(block_group->space_info->disk_total
			< block_group->length * factor);
		WARN_ON(test_bit(BLOCK_GROUP_FLAG_ZONE_IS_ACTIVE,
				 &block_group->runtime_flags) &&
			block_group->space_info->active_total_bytes
			< block_group->length);
	}
	block_group->space_info->total_bytes -= block_group->length;
	if (test_bit(BLOCK_GROUP_FLAG_ZONE_IS_ACTIVE, &block_group->runtime_flags))
		block_group->space_info->active_total_bytes -= block_group->length;
	block_group->space_info->bytes_readonly -=
		(block_group->length - block_group->zone_unusable);
	block_group->space_info->bytes_zone_unusable -=
@@ -3476,6 +3470,7 @@ int btrfs_update_block_group(struct btrfs_trans_handle *trans,
	spin_unlock(&info->delalloc_root_lock);

	while (total) {
		struct btrfs_space_info *space_info;
		bool reclaim = false;

		cache = btrfs_lookup_block_group(info, bytenr);
@@ -3483,6 +3478,7 @@ int btrfs_update_block_group(struct btrfs_trans_handle *trans,
			ret = -ENOENT;
			break;
		}
		space_info = cache->space_info;
		factor = btrfs_bg_type_to_factor(cache->flags);

		/*
@@ -3497,7 +3493,7 @@ int btrfs_update_block_group(struct btrfs_trans_handle *trans,
		byte_in_group = bytenr - cache->start;
		WARN_ON(byte_in_group > cache->length);

		spin_lock(&cache->space_info->lock);
		spin_lock(&space_info->lock);
		spin_lock(&cache->lock);

		if (btrfs_test_opt(info, SPACE_CACHE) &&
@@ -3510,24 +3506,24 @@ int btrfs_update_block_group(struct btrfs_trans_handle *trans,
			old_val += num_bytes;
			cache->used = old_val;
			cache->reserved -= num_bytes;
			cache->space_info->bytes_reserved -= num_bytes;
			cache->space_info->bytes_used += num_bytes;
			cache->space_info->disk_used += num_bytes * factor;
			space_info->bytes_reserved -= num_bytes;
			space_info->bytes_used += num_bytes;
			space_info->disk_used += num_bytes * factor;
			spin_unlock(&cache->lock);
			spin_unlock(&cache->space_info->lock);
			spin_unlock(&space_info->lock);
		} else {
			old_val -= num_bytes;
			cache->used = old_val;
			cache->pinned += num_bytes;
			btrfs_space_info_update_bytes_pinned(info,
					cache->space_info, num_bytes);
			cache->space_info->bytes_used -= num_bytes;
			cache->space_info->disk_used -= num_bytes * factor;
			btrfs_space_info_update_bytes_pinned(info, space_info,
							     num_bytes);
			space_info->bytes_used -= num_bytes;
			space_info->disk_used -= num_bytes * factor;

			reclaim = should_reclaim_block_group(cache, num_bytes);

			spin_unlock(&cache->lock);
			spin_unlock(&cache->space_info->lock);
			spin_unlock(&space_info->lock);

			set_extent_dirty(&trans->transaction->pinned_extents,
					 bytenr, bytenr + num_bytes - 1,
+7 −1
Original line number Diff line number Diff line
@@ -2693,8 +2693,13 @@ static int __btrfs_add_free_space_zoned(struct btrfs_block_group *block_group,
		bg_reclaim_threshold = READ_ONCE(sinfo->bg_reclaim_threshold);

	spin_lock(&ctl->tree_lock);
	/* Count initial region as zone_unusable until it gets activated. */
	if (!used)
		to_free = size;
	else if (initial &&
		 test_bit(BTRFS_FS_ACTIVE_ZONE_TRACKING, &block_group->fs_info->flags) &&
		 (block_group->flags & (BTRFS_BLOCK_GROUP_METADATA | BTRFS_BLOCK_GROUP_SYSTEM)))
		to_free = 0;
	else if (initial)
		to_free = block_group->zone_capacity;
	else if (offset >= block_group->alloc_offset)
@@ -2722,7 +2727,8 @@ static int __btrfs_add_free_space_zoned(struct btrfs_block_group *block_group,
	reclaimable_unusable = block_group->zone_unusable -
			       (block_group->length - block_group->zone_capacity);
	/* All the region is now unusable. Mark it as unused and reclaim */
	if (block_group->zone_unusable == block_group->length) {
	if (block_group->zone_unusable == block_group->length &&
	    block_group->alloc_offset) {
		btrfs_mark_bg_unused(block_group);
	} else if (bg_reclaim_threshold &&
		   reclaimable_unusable >=
+2 −5
Original line number Diff line number Diff line
@@ -120,11 +120,8 @@ enum {
	/* Indicate that we want to commit the transaction. */
	BTRFS_FS_NEED_TRANS_COMMIT,

	/*
	 * Indicate metadata over-commit is disabled. This is set when active
	 * zone tracking is needed.
	 */
	BTRFS_FS_NO_OVERCOMMIT,
	/* This is set when active zone tracking is needed. */
	BTRFS_FS_ACTIVE_ZONE_TRACKING,

	/*
	 * Indicate if we have some features changed, this is mostly for
+6 −1
Original line number Diff line number Diff line
@@ -5421,8 +5421,13 @@ static int btrfs_inode_by_name(struct btrfs_inode *dir, struct dentry *dentry,
		return -ENOMEM;

	ret = fscrypt_setup_filename(&dir->vfs_inode, &dentry->d_name, 1, &fname);
	if (ret)
	if (ret < 0)
		goto out;
	/*
	 * fscrypt_setup_filename() should never return a positive value, but
	 * gcc on sparc/parisc thinks it can, so assert that doesn't happen.
	 */
	ASSERT(ret == 0);

	/* This needs to handle no-key deletions later on */

+10 −32
Original line number Diff line number Diff line
@@ -308,8 +308,6 @@ void btrfs_add_bg_to_space_info(struct btrfs_fs_info *info,
	ASSERT(found);
	spin_lock(&found->lock);
	found->total_bytes += block_group->length;
	if (test_bit(BLOCK_GROUP_FLAG_ZONE_IS_ACTIVE, &block_group->runtime_flags))
		found->active_total_bytes += block_group->length;
	found->disk_total += block_group->length * factor;
	found->bytes_used += block_group->used;
	found->disk_used += block_group->used * factor;
@@ -379,22 +377,6 @@ static u64 calc_available_free_space(struct btrfs_fs_info *fs_info,
	return avail;
}

static inline u64 writable_total_bytes(struct btrfs_fs_info *fs_info,
				       struct btrfs_space_info *space_info)
{
	/*
	 * On regular filesystem, all total_bytes are always writable. On zoned
	 * filesystem, there may be a limitation imposed by max_active_zones.
	 * For metadata allocation, we cannot finish an existing active block
	 * group to avoid a deadlock. Thus, we need to consider only the active
	 * groups to be writable for metadata space.
	 */
	if (!btrfs_is_zoned(fs_info) || (space_info->flags & BTRFS_BLOCK_GROUP_DATA))
		return space_info->total_bytes;

	return space_info->active_total_bytes;
}

int btrfs_can_overcommit(struct btrfs_fs_info *fs_info,
			 struct btrfs_space_info *space_info, u64 bytes,
			 enum btrfs_reserve_flush_enum flush)
@@ -407,13 +389,13 @@ int btrfs_can_overcommit(struct btrfs_fs_info *fs_info,
		return 0;

	used = btrfs_space_info_used(space_info, true);
	if (test_bit(BTRFS_FS_NO_OVERCOMMIT, &fs_info->flags) &&
	if (test_bit(BTRFS_FS_ACTIVE_ZONE_TRACKING, &fs_info->flags) &&
	    (space_info->flags & BTRFS_BLOCK_GROUP_METADATA))
		avail = 0;
	else
		avail = calc_available_free_space(fs_info, space_info, flush);

	if (used + bytes < writable_total_bytes(fs_info, space_info) + avail)
	if (used + bytes < space_info->total_bytes + avail)
		return 1;
	return 0;
}
@@ -449,7 +431,7 @@ void btrfs_try_granting_tickets(struct btrfs_fs_info *fs_info,
		ticket = list_first_entry(head, struct reserve_ticket, list);

		/* Check and see if our ticket can be satisfied now. */
		if ((used + ticket->bytes <= writable_total_bytes(fs_info, space_info)) ||
		if ((used + ticket->bytes <= space_info->total_bytes) ||
		    btrfs_can_overcommit(fs_info, space_info, ticket->bytes,
					 flush)) {
			btrfs_space_info_update_bytes_may_use(fs_info,
@@ -829,7 +811,6 @@ btrfs_calc_reclaim_metadata_size(struct btrfs_fs_info *fs_info,
{
	u64 used;
	u64 avail;
	u64 total;
	u64 to_reclaim = space_info->reclaim_size;

	lockdep_assert_held(&space_info->lock);
@@ -844,9 +825,8 @@ btrfs_calc_reclaim_metadata_size(struct btrfs_fs_info *fs_info,
	 * space.  If that's the case add in our overage so we make sure to put
	 * appropriate pressure on the flushing state machine.
	 */
	total = writable_total_bytes(fs_info, space_info);
	if (total + avail < used)
		to_reclaim += used - (total + avail);
	if (space_info->total_bytes + avail < used)
		to_reclaim += used - (space_info->total_bytes + avail);

	return to_reclaim;
}
@@ -856,11 +836,10 @@ static bool need_preemptive_reclaim(struct btrfs_fs_info *fs_info,
{
	u64 global_rsv_size = fs_info->global_block_rsv.reserved;
	u64 ordered, delalloc;
	u64 total = writable_total_bytes(fs_info, space_info);
	u64 thresh;
	u64 used;

	thresh = mult_perc(total, 90);
	thresh = mult_perc(space_info->total_bytes, 90);

	lockdep_assert_held(&space_info->lock);

@@ -923,8 +902,8 @@ static bool need_preemptive_reclaim(struct btrfs_fs_info *fs_info,
					   BTRFS_RESERVE_FLUSH_ALL);
	used = space_info->bytes_used + space_info->bytes_reserved +
	       space_info->bytes_readonly + global_rsv_size;
	if (used < total)
		thresh += total - used;
	if (used < space_info->total_bytes)
		thresh += space_info->total_bytes - used;
	thresh >>= space_info->clamp;

	used = space_info->bytes_pinned;
@@ -1651,7 +1630,7 @@ static int __reserve_bytes(struct btrfs_fs_info *fs_info,
	 * can_overcommit() to ensure we can overcommit to continue.
	 */
	if (!pending_tickets &&
	    ((used + orig_bytes <= writable_total_bytes(fs_info, space_info)) ||
	    ((used + orig_bytes <= space_info->total_bytes) ||
	     btrfs_can_overcommit(fs_info, space_info, orig_bytes, flush))) {
		btrfs_space_info_update_bytes_may_use(fs_info, space_info,
						      orig_bytes);
@@ -1665,8 +1644,7 @@ static int __reserve_bytes(struct btrfs_fs_info *fs_info,
	 */
	if (ret && unlikely(flush == BTRFS_RESERVE_FLUSH_EMERGENCY)) {
		used = btrfs_space_info_used(space_info, false);
		if (used + orig_bytes <=
		    writable_total_bytes(fs_info, space_info)) {
		if (used + orig_bytes <= space_info->total_bytes) {
			btrfs_space_info_update_bytes_may_use(fs_info, space_info,
							      orig_bytes);
			ret = 0;
Loading