Commit e84d9601 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull btrfs fixes from David Sterba:

 - with large folios in use, fix partial incorrect update of a reflinked
   range

 - fix potential deadlock in iget when lookup fails and eviction is
   needed

 - in send, validate inline extent type while detecting file holes

 - fix memory leak after an error when creating a space info

 - remove zone statistics from sysfs again, the output size limitations
   make it unusable, we'll do it in another way in another release

 - test fixes:
     - return proper error codes from block remapping tests
     - fix tree root leaks in qgroup tests after errors

* tag 'for-6.19-rc5-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux:
  btrfs: remove zoned statistics from sysfs
  btrfs: fix memory leaks in create_space_info() error paths
  btrfs: invalidate pages instead of truncate after reflinking
  btrfs: update the Kconfig string for CONFIG_BTRFS_EXPERIMENTAL
  btrfs: send: check for inline extents in range_is_hole_in_parent()
  btrfs: tests: fix return 0 on rmap test failure
  btrfs: tests: fix root tree leak in btrfs_test_qgroups()
  btrfs: release path before iget_failed() in btrfs_read_locked_inode()
parents 47622aa8 437cc605
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -115,6 +115,10 @@ config BTRFS_EXPERIMENTAL

	  - extent tree v2 - complex rework of extent tracking

	  - large folio support
	  - large folio and block size (> page size) support

	  - shutdown ioctl and auto-degradation support

	  - asynchronous checksum generation for data writes

	  If unsure, say N.
+9 −0
Original line number Diff line number Diff line
@@ -4180,6 +4180,15 @@ static int btrfs_read_locked_inode(struct btrfs_inode *inode, struct btrfs_path

	return 0;
out:
	/*
	 * We may have a read locked leaf and iget_failed() triggers inode
	 * eviction which needs to release the delayed inode and that needs
	 * to lock the delayed inode's mutex. This can cause a ABBA deadlock
	 * with a task running delayed items, as that require first locking
	 * the delayed inode's mutex and then modifying its subvolume btree.
	 * So release the path before iget_failed().
	 */
	btrfs_release_path(path);
	iget_failed(vfs_inode);
	return ret;
}
+13 −10
Original line number Diff line number Diff line
@@ -705,7 +705,6 @@ static noinline int btrfs_clone_files(struct file *file, struct file *file_src,
	struct inode *src = file_inode(file_src);
	struct btrfs_fs_info *fs_info = inode_to_fs_info(inode);
	int ret;
	int wb_ret;
	u64 len = olen;
	u64 bs = fs_info->sectorsize;
	u64 end;
@@ -750,25 +749,29 @@ static noinline int btrfs_clone_files(struct file *file, struct file *file_src,
	btrfs_lock_extent(&BTRFS_I(inode)->io_tree, destoff, end, &cached_state);
	ret = btrfs_clone(src, inode, off, olen, len, destoff, 0);
	btrfs_unlock_extent(&BTRFS_I(inode)->io_tree, destoff, end, &cached_state);
	if (ret < 0)
		return ret;

	/*
	 * We may have copied an inline extent into a page of the destination
	 * range, so wait for writeback to complete before truncating pages
	 * range, so wait for writeback to complete before invalidating pages
	 * from the page cache. This is a rare case.
	 */
	wb_ret = btrfs_wait_ordered_range(BTRFS_I(inode), destoff, len);
	ret = ret ? ret : wb_ret;
	ret = btrfs_wait_ordered_range(BTRFS_I(inode), destoff, len);
	if (ret < 0)
		return ret;

	/*
	 * Truncate page cache pages so that future reads will see the cloned
	 * data immediately and not the previous data.
	 * Invalidate page cache so that future reads will see the cloned data
	 * immediately and not the previous data.
	 */
	truncate_inode_pages_range(&inode->i_data,
				round_down(destoff, PAGE_SIZE),
				round_up(destoff + len, PAGE_SIZE) - 1);
	ret = filemap_invalidate_inode(inode, false, destoff, end);
	if (ret < 0)
		return ret;

	btrfs_btree_balance_dirty(fs_info);

	return ret;
	return 0;
}

static int btrfs_remap_file_range_prep(struct file *file_in, loff_t pos_in,
+2 −0
Original line number Diff line number Diff line
@@ -6383,6 +6383,8 @@ static int range_is_hole_in_parent(struct send_ctx *sctx,
		extent_end = btrfs_file_extent_end(path);
		if (extent_end <= start)
			goto next;
		if (btrfs_file_extent_type(leaf, fi) == BTRFS_FILE_EXTENT_INLINE)
			return 0;
		if (btrfs_file_extent_disk_bytenr(leaf, fi) == 0) {
			search_start = extent_end;
			goto next;
+6 −2
Original line number Diff line number Diff line
@@ -306,18 +306,22 @@ static int create_space_info(struct btrfs_fs_info *info, u64 flags)
							  0);

		if (ret)
			return ret;
			goto out_free;
	}

	ret = btrfs_sysfs_add_space_info_type(space_info);
	if (ret)
		return ret;
		goto out_free;

	list_add(&space_info->list, &info->space_info);
	if (flags & BTRFS_BLOCK_GROUP_DATA)
		info->data_sinfo = space_info;

	return ret;

out_free:
	kfree(space_info);
	return ret;
}

int btrfs_init_space_info(struct btrfs_fs_info *fs_info)
Loading