Commit a39da514 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by David Sterba
Browse files

btrfs: limit write bios to a single ordered extent



Currently buffered writeback bios are allowed to span multiple
ordered_extents, although that basically never actually happens since
commit 4a445b7b ("btrfs: don't merge pages into bio if their page
offset is not contiguous").

Supporting bios than span ordered_extents complicates the file
checksumming code, and prevents us from adding an ordered_extent pointer
to the btrfs_bio structure.  Use the existing code to limit a bio to
single ordered_extent for zoned device writes for all writes.

This allows to remove the REQ_BTRFS_ONE_ORDERED flags, and the
handling of multiple ordered_extents in btrfs_csum_one_bio.

Reviewed-by: default avatarJohannes Thumshirn <johannes.thumshirn@wdc.com>
Reviewed-by: default avatarJosef Bacik <josef@toxicpanda.com>
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarDavid Sterba <dsterba@suse.com>
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
parent c731cd0b
Loading
Loading
Loading
Loading
+0 −3
Original line number Diff line number Diff line
@@ -457,9 +457,6 @@ static void btrfs_submit_mirrored_bio(struct btrfs_io_context *bioc, int dev_nr)
static void __btrfs_submit_bio(struct bio *bio, struct btrfs_io_context *bioc,
			       struct btrfs_io_stripe *smap, int mirror_num)
{
	/* Do not leak our private flag into the block layer. */
	bio->bi_opf &= ~REQ_BTRFS_ONE_ORDERED;

	if (!bioc) {
		/* Single mirror read/write fast path. */
		btrfs_bio(bio)->mirror_num = mirror_num;
+0 −3
Original line number Diff line number Diff line
@@ -102,9 +102,6 @@ static inline void btrfs_bio_end_io(struct btrfs_bio *bbio, blk_status_t status)
	bbio->end_io(bbio);
}

/* Bio only refers to one ordered extent. */
#define REQ_BTRFS_ONE_ORDERED			REQ_DRV

/* Submit using blkcg_punt_bio_submit. */
#define REQ_BTRFS_CGROUP_PUNT			REQ_FS_PRIVATE

+0 −2
Original line number Diff line number Diff line
@@ -293,8 +293,6 @@ void btrfs_submit_compressed_write(struct btrfs_inode *inode, u64 start,
	ASSERT(IS_ALIGNED(start, fs_info->sectorsize) &&
	       IS_ALIGNED(len, fs_info->sectorsize));

	write_flags |= REQ_BTRFS_ONE_ORDERED;

	cb = alloc_compressed_bio(inode, start, REQ_OP_WRITE | write_flags,
				  end_compressed_bio_write);
	cb->start = start;
+2 −9
Original line number Diff line number Diff line
@@ -826,13 +826,8 @@ static void alloc_new_bio(struct btrfs_inode *inode,
	bio_ctrl->bbio = bbio;
	bio_ctrl->len_to_oe_boundary = U32_MAX;

	/*
	 * Limit the extent to the ordered boundary for Zone Append.
	 * Compressed bios aren't submitted directly, so it doesn't apply to
	 * them.
	 */
	if (bio_ctrl->compress_type == BTRFS_COMPRESS_NONE &&
	    btrfs_use_zone_append(bbio)) {
	/* Limit data write bios to the ordered boundary. */
	if (bio_ctrl->wbc) {
		struct btrfs_ordered_extent *ordered;

		ordered = btrfs_lookup_ordered_extent(inode, file_offset);
@@ -842,9 +837,7 @@ static void alloc_new_bio(struct btrfs_inode *inode,
					ordered->disk_num_bytes - file_offset);
			btrfs_put_ordered_extent(ordered);
		}
	}

	if (bio_ctrl->wbc) {
		/*
		 * Pick the last added device to support cgroup writeback.  For
		 * multi-device file systems this means blk-cgroup policies have
+0 −38
Original line number Diff line number Diff line
@@ -733,8 +733,6 @@ blk_status_t btrfs_csum_one_bio(struct btrfs_bio *bbio)
	struct bio_vec bvec;
	int index;
	unsigned int blockcount;
	unsigned long total_bytes = 0;
	unsigned long this_sum_bytes = 0;
	int i;
	unsigned nofs_flag;

@@ -776,34 +774,6 @@ blk_status_t btrfs_csum_one_bio(struct btrfs_bio *bbio)
						 - 1);

		for (i = 0; i < blockcount; i++) {
			if (!(bio->bi_opf & REQ_BTRFS_ONE_ORDERED) &&
			    !in_range(offset, ordered->file_offset,
				      ordered->num_bytes)) {
				unsigned long bytes_left;

				sums->len = this_sum_bytes;
				this_sum_bytes = 0;
				btrfs_add_ordered_sum(ordered, sums);
				btrfs_put_ordered_extent(ordered);

				bytes_left = bio->bi_iter.bi_size - total_bytes;

				nofs_flag = memalloc_nofs_save();
				sums = kvzalloc(btrfs_ordered_sum_size(fs_info,
						      bytes_left), GFP_KERNEL);
				memalloc_nofs_restore(nofs_flag);
				if (!sums)
					return BLK_STS_RESOURCE;

				sums->len = bytes_left;
				ordered = btrfs_lookup_ordered_extent(inode,
								offset);
				ASSERT(ordered); /* Logic error */
				sums->logical = (bio->bi_iter.bi_sector << SECTOR_SHIFT)
					+ total_bytes;
				index = 0;
			}

			data = bvec_kmap_local(&bvec);
			crypto_shash_digest(shash,
					    data + (i * fs_info->sectorsize),
@@ -812,18 +782,10 @@ blk_status_t btrfs_csum_one_bio(struct btrfs_bio *bbio)
			kunmap_local(data);
			index += fs_info->csum_size;
			offset += fs_info->sectorsize;
			this_sum_bytes += fs_info->sectorsize;
			total_bytes += fs_info->sectorsize;
		}

	}
	this_sum_bytes = 0;

	/*
	 * The ->sums assignment is for zoned writes, where a bio never spans
	 * ordered extents and is only done unconditionally because that's cheaper
	 * than a branch.
	 */
	bbio->sums = sums;
	btrfs_add_ordered_sum(ordered, sums);
	btrfs_put_ordered_extent(ordered);