All of lore.kernel.org
 help / color / mirror / Atom feed
From: Omar Sandoval <osandov@osandov.com>
To: Nikolay Borisov <nborisov@suse.com>
Cc: linux-btrfs@vger.kernel.org, kernel-team@fb.com,
	linux-fsdevel@vger.kernel.org, linux-api@vger.kernel.org
Subject: Re: [PATCH v11 13/14] btrfs: send: send compressed extents with encoded writes
Date: Mon, 18 Oct 2021 17:11:30 -0700	[thread overview]
Message-ID: <YW4NMkw0K4uMrckI@relinquished.localdomain> (raw)
In-Reply-To: <58a04b59-a2fb-bd26-606e-6ddf8bd31552@suse.com>

On Mon, Oct 18, 2021 at 02:59:08PM +0300, Nikolay Borisov wrote:
> 
> 
> On 1.09.21 г. 20:01, Omar Sandoval wrote:
> > From: Omar Sandoval <osandov@fb.com>
> > 
> > Now that all of the pieces are in place, we can use the ENCODED_WRITE
> > command to send compressed extents when appropriate.
> > 
> > Signed-off-by: Omar Sandoval <osandov@fb.com>
> 
> Overall looks sane but consider some of the nits below.
> 
> 
> <snip>
> 
> > +static int send_encoded_extent(struct send_ctx *sctx, struct btrfs_path *path,
> > +			       u64 offset, u64 len)
> > +{
> > +	struct btrfs_root *root = sctx->send_root;
> > +	struct btrfs_fs_info *fs_info = root->fs_info;
> > +	struct inode *inode;
> > +	struct fs_path *p;
> > +	struct extent_buffer *leaf = path->nodes[0];
> > +	struct btrfs_key key;
> > +	struct btrfs_file_extent_item *ei;
> > +	u64 block_start;
> > +	u64 block_len;
> > +	u32 data_offset;
> > +	struct btrfs_cmd_header *hdr;
> > +	u32 crc;
> > +	int ret;
> > +
> > +	inode = btrfs_iget(fs_info->sb, sctx->cur_ino, root);
> > +	if (IS_ERR(inode))
> > +		return PTR_ERR(inode);
> > +
> > +	p = fs_path_alloc();
> > +	if (!p) {
> > +		ret = -ENOMEM;
> > +		goto out;
> > +	}
> > +
> > +	ret = begin_cmd(sctx, BTRFS_SEND_C_ENCODED_WRITE);
> > +	if (ret < 0)
> > +		goto out;
> > +
> > +	ret = get_cur_path(sctx, sctx->cur_ino, sctx->cur_inode_gen, p);
> > +	if (ret < 0)
> > +		goto out;
> > +
> > +	btrfs_item_key_to_cpu(leaf, &key, path->slots[0]);
> > +	ei = btrfs_item_ptr(leaf, path->slots[0],
> > +			    struct btrfs_file_extent_item);
> > +	block_start = btrfs_file_extent_disk_bytenr(leaf, ei);
> 
> block_start is somewhat ambiguous here, this is just the disk bytenr of
> the extent.
> 
> > +	block_len = btrfs_file_extent_disk_num_bytes(leaf, ei);
> 
> Why is this called block_len when it's just the size in bytes on-disk?

I copied this naming from extent_map since btrfs_encoded_read() was the
reference for this code, but I'll change the naming here.

> > +
> > +	TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, p);
> > +	TLV_PUT_U64(sctx, BTRFS_SEND_A_FILE_OFFSET, offset);
> > +	TLV_PUT_U64(sctx, BTRFS_SEND_A_UNENCODED_FILE_LEN,
> > +		    min(key.offset + btrfs_file_extent_num_bytes(leaf, ei) - offset,
> > +			len));
> > +	TLV_PUT_U64(sctx, BTRFS_SEND_A_UNENCODED_LEN,
> > +		    btrfs_file_extent_ram_bytes(leaf, ei));
> > +	TLV_PUT_U64(sctx, BTRFS_SEND_A_UNENCODED_OFFSET,
> > +		    offset - key.offset + btrfs_file_extent_offset(leaf, ei));
> > +	ret = btrfs_encoded_io_compression_from_extent(
> > +				btrfs_file_extent_compression(leaf, ei));
> > +	if (ret < 0)
> > +		goto out;
> > +	TLV_PUT_U32(sctx, BTRFS_SEND_A_COMPRESSION, ret);
> > +	TLV_PUT_U32(sctx, BTRFS_SEND_A_ENCRYPTION, 0);
> > +
> > +	ret = put_data_header(sctx, block_len);
> > +	if (ret < 0)
> > +		goto out;
> > +
> > +	data_offset = ALIGN(sctx->send_size, PAGE_SIZE);
> 
> nit: The whole data_offset warrants a comment here, since send_buf is
> now mapped from send_buf_pages, so all the TLV you've put before are
> actually stored in the beginning of send_buf_pages, so by doing the
> above you ensure the data write begins on a clean page boundary ...

Yup, I'll add a comment.

> > +	if (data_offset > sctx->send_max_size ||
> > +	    sctx->send_max_size - data_offset < block_len) {
> > +		ret = -EOVERFLOW;
> > +		goto out;
> > +	}
> > +
> > +	ret = btrfs_encoded_read_regular_fill_pages(inode, block_start,
> > +						    block_len,
> > +						    sctx->send_buf_pages +
> > +						    (data_offset >> PAGE_SHIFT));
> > +	if (ret)
> > +		goto out;
> > +
> > +	hdr = (struct btrfs_cmd_header *)sctx->send_buf;
> > +	hdr->len = cpu_to_le32(sctx->send_size + block_len - sizeof(*hdr));
> > +	hdr->crc = 0;
> > +	crc = btrfs_crc32c(0, sctx->send_buf, sctx->send_size);
> > +	crc = btrfs_crc32c(crc, sctx->send_buf + data_offset, block_len);
> 
> ... and because of that you can't simply use send_cmd ;(
> 
> > +	hdr->crc = cpu_to_le32(crc);
> > +
> > +	ret = write_buf(sctx->send_filp, sctx->send_buf, sctx->send_size,
> > +			&sctx->send_off);
> > +	if (!ret) {
> > +		ret = write_buf(sctx->send_filp, sctx->send_buf + data_offset,
> > +				block_len, &sctx->send_off);
> > +	}
> > +	sctx->total_send_size += sctx->send_size + block_len;
> > +	sctx->cmd_send_size[le16_to_cpu(hdr->cmd)] +=
> > +		sctx->send_size + block_len;
> > +	sctx->send_size = 0;
> > +
> > +tlv_put_failure:
> > +out:
> > +	fs_path_free(p);
> > +	iput(inode);
> > +	return ret;
> > +}
> > +
> > +static int send_extent_data(struct send_ctx *sctx, struct btrfs_path *path,
> > +			    const u64 offset, const u64 len)
> 
> nit: Instead of sending around a btrfs_path struct around and
> "polluting" callees to deal with the oddities of our btree interface i.e
> btrfs_item_ptr et al. Why not refactor the code so that when we know we
> are about to send an extent data simply initialize some struct
> extent_info with all the necessary data items: extent type, compression
> type, based on the extent type properly initialize a size attribute etc
> and pass that. Right now you have send_extent_data fiddling with
> path->nodes[0], then based on that you either call
> send_encoded_inline_extent or send_encoded_extent, instead pass
> extent_info to send_extent_data/clone_range and be done with it.

I don't like this for a few reasons:

* An extra "struct extent_info" layer of abstraction would just be extra
  cognitive overhead. I hate having to trace back where the fields in
  some struct came from when it's information that's readily available
  in more well-known data structures.
* send_encoded_inline_extent() (called by send_extent_data()) needs the
  btrfs_path in order to get the inline data anyways.
* clone_range() also already deals with btrfs_paths, so it's not new.

  reply	other threads:[~2021-10-19  0:11 UTC|newest]

Thread overview: 62+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-09-01 17:00 [PATCH v11 00/14] btrfs: add ioctls and send/receive support for reading/writing compressed data Omar Sandoval
2021-09-01 17:00 ` [PATCH v11 01/14] fs: export rw_verify_area() Omar Sandoval
2021-11-18 19:19   ` Omar Sandoval
2022-01-04 19:06     ` Omar Sandoval
2021-09-01 17:00 ` [PATCH v11 02/14] fs: export variant of generic_write_checks without iov_iter Omar Sandoval
2021-10-14 12:03   ` Nikolay Borisov
2021-09-01 17:00 ` [PATCH v11 03/14] btrfs: don't advance offset for compressed bios in btrfs_csum_one_bio() Omar Sandoval
2021-10-14 12:05   ` Nikolay Borisov
2021-10-18 18:09     ` Omar Sandoval
2021-09-01 17:00 ` [PATCH v11 04/14] btrfs: add ram_bytes and offset to btrfs_ordered_extent Omar Sandoval
2021-10-21 12:44   ` Nikolay Borisov
2021-10-21 16:55     ` Omar Sandoval
2021-09-01 17:01 ` [PATCH v11 05/14] btrfs: support different disk extent size for delalloc Omar Sandoval
2021-09-01 17:01 ` [PATCH v11 06/14] btrfs: optionally extend i_size in cow_file_range_inline() Omar Sandoval
2021-10-14 12:54   ` Nikolay Borisov
2021-09-01 17:01 ` [PATCH v11 07/14] btrfs: add definitions + documentation for encoded I/O ioctls Omar Sandoval
2021-10-15  9:42   ` Nikolay Borisov
2021-10-18 18:16     ` Omar Sandoval
2021-09-01 17:01 ` [PATCH v11 08/14] btrfs: add BTRFS_IOC_ENCODED_READ Omar Sandoval
2021-10-15 11:45   ` Nikolay Borisov
2021-10-18 23:59     ` Omar Sandoval
2021-09-01 17:01 ` [PATCH v11 09/14] btrfs: add BTRFS_IOC_ENCODED_WRITE Omar Sandoval
2021-09-01 17:01 ` [PATCH v11 10/14] btrfs: add send stream v2 definitions Omar Sandoval
2021-10-18 12:46   ` Nikolay Borisov
2021-10-18 15:11   ` Nikolay Borisov
2021-10-18 18:58     ` Omar Sandoval
2021-10-19  7:01       ` Nikolay Borisov
2021-09-01 17:01 ` [PATCH v11 11/14] btrfs: send: write larger chunks when using stream v2 Omar Sandoval
2021-10-18 12:57   ` Nikolay Borisov
2021-09-01 17:01 ` [PATCH v11 12/14] btrfs: send: allocate send buffer with alloc_page() and vmap() for v2 Omar Sandoval
2021-10-18 11:10   ` Nikolay Borisov
2021-09-01 17:01 ` [PATCH v11 13/14] btrfs: send: send compressed extents with encoded writes Omar Sandoval
2021-10-18 11:59   ` Nikolay Borisov
2021-10-19  0:11     ` Omar Sandoval [this message]
2021-09-01 17:01 ` [PATCH v11 14/14] btrfs: send: enable support for stream v2 and compressed writes Omar Sandoval
2021-10-18 12:44   ` Nikolay Borisov
2021-10-18 18:34     ` Omar Sandoval
2021-09-01 17:01 ` [PATCH v11 01/10] btrfs-progs: receive: support v2 send stream larger tlv_len Omar Sandoval
2021-10-20 13:49   ` Nikolay Borisov
2021-10-20 18:48     ` Omar Sandoval
2021-09-01 17:01 ` [PATCH v11 02/10] btrfs-progs: receive: dynamically allocate sctx->read_buf Omar Sandoval
2021-10-20 14:09   ` Nikolay Borisov
2021-10-20 14:35     ` Nikolay Borisov
2021-10-20 17:44       ` Omar Sandoval
2021-09-01 17:01 ` [PATCH v11 03/10] btrfs-progs: receive: support v2 send stream DATA tlv format Omar Sandoval
2021-10-20 14:36   ` Nikolay Borisov
2021-09-01 17:01 ` [PATCH v11 04/10] btrfs-progs: receive: add send stream v2 cmds and attrs to send.h Omar Sandoval
2021-10-20 14:38   ` Nikolay Borisov
2021-09-01 17:01 ` [PATCH v11 05/10] btrfs-progs: receive: process encoded_write commands Omar Sandoval
2021-10-21 13:33   ` Nikolay Borisov
2021-10-21 16:52     ` Omar Sandoval
2021-09-01 17:01 ` [PATCH v11 06/10] btrfs-progs: receive: encoded_write fallback to explicit decode and write Omar Sandoval
2021-10-21 13:55   ` Nikolay Borisov
2021-10-21 17:22     ` Omar Sandoval
2021-09-01 17:01 ` [PATCH v11 07/10] btrfs-progs: receive: process fallocate commands Omar Sandoval
2021-10-21 14:21   ` Nikolay Borisov
2021-10-21 17:28     ` Omar Sandoval
2021-09-01 17:01 ` [PATCH v11 08/10] btrfs-progs: receive: process setflags ioctl commands Omar Sandoval
2021-10-21 14:22   ` Nikolay Borisov
2021-09-01 17:01 ` [PATCH v11 09/10] btrfs-progs: send: stream v2 ioctl flags Omar Sandoval
2021-10-22  6:35   ` Nikolay Borisov
2021-09-01 17:01 ` [PATCH v11 10/10] btrfs-progs: receive: add tests for basic encoded_write send/receive Omar Sandoval

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=YW4NMkw0K4uMrckI@relinquished.localdomain \
    --to=osandov@osandov.com \
    --cc=kernel-team@fb.com \
    --cc=linux-api@vger.kernel.org \
    --cc=linux-btrfs@vger.kernel.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=nborisov@suse.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.