Commit 4e467744 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
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
parents 6cc65abe 75f49c3d
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -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;
+2 −2
Original line number Diff line number Diff line
@@ -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);
}
+1 −1
Original line number Diff line number Diff line
@@ -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);
}

+9 −8
Original line number Diff line number Diff line
@@ -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();
+16 −15
Original line number Diff line number Diff line
@@ -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;
@@ -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,
@@ -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);
@@ -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);
Loading