Commit 45af60e7 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull btrfs fixes from David Sterba:
 "A few more fixes:

   - fix unaligned compressed writes in zoned mode

   - fix false positive lockdep warning when cloning inline extent

   - remove wrong BUG_ON in tree-log error handling"

* tag 'for-5.13-rc2-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux:
  btrfs: zoned: fix parallel compressed writes
  btrfs: zoned: pass start block to btrfs_use_zone_append
  btrfs: do not BUG_ON in link_to_fixup_dir
  btrfs: release path before starting transaction when cloning inline extent
parents 8bb14ca1 764c7c9a
Loading
Loading
Loading
Loading
+38 −4
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@
#include "compression.h"
#include "extent_io.h"
#include "extent_map.h"
#include "zoned.h"

static const char* const btrfs_compress_types[] = { "", "zlib", "lzo", "zstd" };

@@ -349,6 +350,7 @@ static void end_compressed_bio_write(struct bio *bio)
	 */
	inode = cb->inode;
	cb->compressed_pages[0]->mapping = cb->inode->i_mapping;
	btrfs_record_physical_zoned(inode, cb->start, bio);
	btrfs_writepage_endio_finish_ordered(cb->compressed_pages[0],
			cb->start, cb->start + cb->len - 1,
			bio->bi_status == BLK_STS_OK);
@@ -401,6 +403,8 @@ blk_status_t btrfs_submit_compressed_write(struct btrfs_inode *inode, u64 start,
	u64 first_byte = disk_start;
	blk_status_t ret;
	int skip_sum = inode->flags & BTRFS_INODE_NODATASUM;
	const bool use_append = btrfs_use_zone_append(inode, disk_start);
	const unsigned int bio_op = use_append ? REQ_OP_ZONE_APPEND : REQ_OP_WRITE;

	WARN_ON(!PAGE_ALIGNED(start));
	cb = kmalloc(compressed_bio_size(fs_info, compressed_len), GFP_NOFS);
@@ -418,10 +422,31 @@ blk_status_t btrfs_submit_compressed_write(struct btrfs_inode *inode, u64 start,
	cb->nr_pages = nr_pages;

	bio = btrfs_bio_alloc(first_byte);
	bio->bi_opf = REQ_OP_WRITE | write_flags;
	bio->bi_opf = bio_op | write_flags;
	bio->bi_private = cb;
	bio->bi_end_io = end_compressed_bio_write;

	if (use_append) {
		struct extent_map *em;
		struct map_lookup *map;
		struct block_device *bdev;

		em = btrfs_get_chunk_map(fs_info, disk_start, PAGE_SIZE);
		if (IS_ERR(em)) {
			kfree(cb);
			bio_put(bio);
			return BLK_STS_NOTSUPP;
		}

		map = em->map_lookup;
		/* We only support single profile for now */
		ASSERT(map->num_stripes == 1);
		bdev = map->stripes[0].dev->bdev;

		bio_set_dev(bio, bdev);
		free_extent_map(em);
	}

	if (blkcg_css) {
		bio->bi_opf |= REQ_CGROUP_PUNT;
		kthread_associate_blkcg(blkcg_css);
@@ -432,6 +457,7 @@ blk_status_t btrfs_submit_compressed_write(struct btrfs_inode *inode, u64 start,
	bytes_left = compressed_len;
	for (pg_index = 0; pg_index < cb->nr_pages; pg_index++) {
		int submit = 0;
		int len;

		page = compressed_pages[pg_index];
		page->mapping = inode->vfs_inode.i_mapping;
@@ -439,9 +465,13 @@ blk_status_t btrfs_submit_compressed_write(struct btrfs_inode *inode, u64 start,
			submit = btrfs_bio_fits_in_stripe(page, PAGE_SIZE, bio,
							  0);

		if (pg_index == 0 && use_append)
			len = bio_add_zone_append_page(bio, page, PAGE_SIZE, 0);
		else
			len = bio_add_page(bio, page, PAGE_SIZE, 0);

		page->mapping = NULL;
		if (submit || bio_add_page(bio, page, PAGE_SIZE, 0) <
		    PAGE_SIZE) {
		if (submit || len < PAGE_SIZE) {
			/*
			 * inc the count before we submit the bio so
			 * we know the end IO handler won't happen before
@@ -465,11 +495,15 @@ blk_status_t btrfs_submit_compressed_write(struct btrfs_inode *inode, u64 start,
			}

			bio = btrfs_bio_alloc(first_byte);
			bio->bi_opf = REQ_OP_WRITE | write_flags;
			bio->bi_opf = bio_op | write_flags;
			bio->bi_private = cb;
			bio->bi_end_io = end_compressed_bio_write;
			if (blkcg_css)
				bio->bi_opf |= REQ_CGROUP_PUNT;
			/*
			 * Use bio_add_page() to ensure the bio has at least one
			 * page.
			 */
			bio_add_page(bio, page, PAGE_SIZE, 0);
		}
		if (bytes_left < PAGE_SIZE) {
+1 −1
Original line number Diff line number Diff line
@@ -3753,7 +3753,7 @@ static noinline_for_stack int __extent_writepage_io(struct btrfs_inode *inode,
		/* Note that em_end from extent_map_end() is exclusive */
		iosize = min(em_end, end + 1) - cur;

		if (btrfs_use_zone_append(inode, em))
		if (btrfs_use_zone_append(inode, em->block_start))
			opf = REQ_OP_ZONE_APPEND;

		free_extent_map(em);
+1 −1
Original line number Diff line number Diff line
@@ -7786,7 +7786,7 @@ static int btrfs_dio_iomap_begin(struct inode *inode, loff_t start,
	iomap->bdev = fs_info->fs_devices->latest_bdev;
	iomap->length = len;

	if (write && btrfs_use_zone_append(BTRFS_I(inode), em))
	if (write && btrfs_use_zone_append(BTRFS_I(inode), em->block_start))
		iomap->flags |= IOMAP_F_ZONE_APPEND;

	free_extent_map(em);
+5 −0
Original line number Diff line number Diff line
@@ -281,6 +281,11 @@ static int clone_copy_inline_extent(struct inode *dst,
	ret = btrfs_inode_set_file_extent_range(BTRFS_I(dst), 0, aligned_end);
out:
	if (!ret && !trans) {
		/*
		 * Release path before starting a new transaction so we don't
		 * hold locks that would confuse lockdep.
		 */
		btrfs_release_path(path);
		/*
		 * No transaction here means we copied the inline extent into a
		 * page of the destination inode.
+0 −2
Original line number Diff line number Diff line
@@ -1858,8 +1858,6 @@ static noinline int link_to_fixup_dir(struct btrfs_trans_handle *trans,
		ret = btrfs_update_inode(trans, root, BTRFS_I(inode));
	} else if (ret == -EEXIST) {
		ret = 0;
	} else {
		BUG(); /* Logic Error */
	}
	iput(inode);

Loading