From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-3.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=no autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 963ACC48BE8 for ; Fri, 18 Jun 2021 20:58:10 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 7A39D61261 for ; Fri, 18 Jun 2021 20:58:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234257AbhFRVAT (ORCPT ); Fri, 18 Jun 2021 17:00:19 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48816 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232431AbhFRVAS (ORCPT ); Fri, 18 Jun 2021 17:00:18 -0400 Received: from zeniv-ca.linux.org.uk (zeniv-ca.linux.org.uk [IPv6:2607:5300:60:148a::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 19127C061574; Fri, 18 Jun 2021 13:58:09 -0700 (PDT) Received: from viro by zeniv-ca.linux.org.uk with local (Exim 4.94.2 #2 (Red Hat Linux)) id 1luLYz-009kX3-Jo; Fri, 18 Jun 2021 20:58:05 +0000 Date: Fri, 18 Jun 2021 20:58:05 +0000 From: Al Viro To: Omar Sandoval Cc: Linus Torvalds , linux-fsdevel , linux-btrfs , Linux API , Kernel Team Subject: Re: [PATCH RESEND x3 v9 1/9] iov_iter: add copy_struct_from_iter() Message-ID: References: <6caae597eb20da5ea23e53e8e64ce0c4f4d9c6d2.1623972519.git.osandov@fb.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: Sender: Al Viro Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org On Fri, Jun 18, 2021 at 01:32:26PM -0700, Omar Sandoval wrote: > RWF_ENCODED is intended to be used like this: > > struct encoded_iov encoded_iov = { > /* compression metadata */ ... > }; > char compressed_data[] = ...; > struct iovec iov[] = { > { &encoded_iov, sizeof(encoded_iov) }, > { compressed_data, sizeof(compressed_data) }, > }; > pwritev2(fd, iov, 2, -1, RWF_ENCODED); > > Basically, we squirrel away the compression metadata in the first > element of the iovec array, and we use iov[0].iov_len so that we can > support future extensions of struct encoded_iov in the style of > copy_struct_from_user(). Yecchhh... > So this doesn't require nr_seg == 1. On the contrary, it's expected that > the rest of the iovec has the compressed payload. And to support the > copy_struct_from_user()-style versioning, we need to know the size of > the struct encoded_iov that userspace gave us, which is the reason for > the iov_iter_single_seg_count(). > > I know this interface isn't the prettiest. It started as a > Btrfs-specific ioctl, but this approach was suggested as a way to avoid > having a whole new I/O path: > https://lore.kernel.org/linux-fsdevel/20190905021012.GL7777@dread.disaster.area/ > The copy_struct_from_iter() thing was proposed as a way to allow future > extensions here: > https://lore.kernel.org/linux-btrfs/20191022020215.csdwgi3ky27rfidf@yavin.dot.cyphar.com/ > > Please let me know if you have any suggestions for how to improve this. Just put the size of the encoded part first and be done with that. Magical effect of the iovec sizes is a bloody bad idea. And on top of #work.iov_iter something like bool iov_iter_check_zeroes(struct iov_iter *i, size_t bytes) { bool failed = false; iterate_and_advance(i, bytes, base, len, off, failed = (check_zeroed_user(base, len) != 1), failed = (memchr_inv(base, 0, len) != NULL), ) if (unlikely(failed)) iov_iter_revert(i, bytes); return !failed; } would do "is that chunk all-zeroes?" just fine. It's that simple...