From patchwork Wed Aug 14 20:38:43 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 13764105 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 217CCC52D7F for ; Wed, 14 Aug 2024 20:42:04 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id A0F056B00BC; Wed, 14 Aug 2024 16:42:03 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 996B16B00BE; Wed, 14 Aug 2024 16:42:03 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 7EB6B6B00BF; Wed, 14 Aug 2024 16:42:03 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0015.hostedemail.com [216.40.44.15]) by kanga.kvack.org (Postfix) with ESMTP id 5C4266B00BC for ; Wed, 14 Aug 2024 16:42:03 -0400 (EDT) Received: from smtpin12.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay07.hostedemail.com (Postfix) with ESMTP id 1E2391611A3 for ; Wed, 14 Aug 2024 20:42:03 +0000 (UTC) X-FDA: 82452022926.12.45FF3F6 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by imf16.hostedemail.com (Postfix) with ESMTP id 6F06D18000A for ; Wed, 14 Aug 2024 20:42:01 +0000 (UTC) Authentication-Results: imf16.hostedemail.com; dkim=pass header.d=redhat.com header.s=mimecast20190719 header.b=HRN0mQcA; spf=temperror (imf16.hostedemail.com: error in processing during lookup of dhowells@redhat.com: DNS error) smtp.mailfrom=dhowells@redhat.com; dmarc=pass (policy=none) header.from=redhat.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1723668049; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=iXFw+oU47qKVQiA+0YFU3Ycf5Gk6FAGXhwuof46YCCg=; b=iojAFykjtI3dnS1T6+zxRl0c6vaoGhYinxo0YFDIX8rM46GS7Ha1v7loVl+sXxiESVBX5x BcYLXYJPcj7yGecFU/fGanhccx2nPAXsB8jVGhXg1iv/2rYi6DrC/37ayz1TzjOL8rn4l5 fVoM5sRbnuYZLPyf9MHvggQAW4H6fFQ= ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1723668049; a=rsa-sha256; cv=none; b=vQAOYTBS4bcoY3rEuQ3NjJ3wBanWUYl9vYrpq63XU5HGnnj2bWTw15ss9G35/f3j4fGCs/ d6GdU1Q/I58LrLTfliAkjGDtcTng0ZmwKgpZ9jbaVAHewpGSZU9RjLbxbC5eqO35xglFre YlP5gz+4kWrfi7VBcDpMlElruHfN02s= ARC-Authentication-Results: i=1; imf16.hostedemail.com; dkim=pass header.d=redhat.com header.s=mimecast20190719 header.b=HRN0mQcA; spf=temperror (imf16.hostedemail.com: error in processing during lookup of dhowells@redhat.com: DNS error) smtp.mailfrom=dhowells@redhat.com; dmarc=pass (policy=none) header.from=redhat.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1723668120; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=iXFw+oU47qKVQiA+0YFU3Ycf5Gk6FAGXhwuof46YCCg=; b=HRN0mQcA50HKyY204oYv0rvtprGmEtV/x//tWxsTok+tUi1RmDCFTqmUVNeK/k2FOEsf2E TXEUBvqVv11G9wbwn8YGuD4hxe2m3UHttdVkta7Gd84VFaUQpaQ0bqULnnO8qHHDBk+xCo kkwlU1wEEZJBY2UC53TjM1BTR58vkRs= Received: from mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-515-0YvQwBjyPzaCGwVpAix73g-1; Wed, 14 Aug 2024 16:41:57 -0400 X-MC-Unique: 0YvQwBjyPzaCGwVpAix73g-1 Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id C84201954B16; Wed, 14 Aug 2024 20:41:53 +0000 (UTC) Received: from warthog.procyon.org.uk.com (unknown [10.42.28.30]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 910B51955D88; Wed, 14 Aug 2024 20:41:47 +0000 (UTC) From: David Howells To: Christian Brauner , Steve French , Matthew Wilcox Cc: David Howells , Jeff Layton , Gao Xiang , Dominique Martinet , Marc Dionne , Paulo Alcantara , Shyam Prasad N , Tom Talpey , Eric Van Hensbergen , Ilya Dryomov , netfs@lists.linux.dev, linux-afs@lists.infradead.org, linux-cifs@vger.kernel.org, linux-nfs@vger.kernel.org, ceph-devel@vger.kernel.org, v9fs@lists.linux.dev, linux-erofs@lists.ozlabs.org, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Steve French , Enzo Matsumiya Subject: [PATCH v2 23/25] cifs: Use iterate_and_advance*() routines directly for hashing Date: Wed, 14 Aug 2024 21:38:43 +0100 Message-ID: <20240814203850.2240469-24-dhowells@redhat.com> In-Reply-To: <20240814203850.2240469-1-dhowells@redhat.com> References: <20240814203850.2240469-1-dhowells@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.17 X-Stat-Signature: yyhmf1h57ribozff5kfanzp6tyhzmqhi X-Rspamd-Queue-Id: 6F06D18000A X-Rspam-User: X-Rspamd-Server: rspam08 X-HE-Tag: 1723668121-382355 X-HE-Meta: U2FsdGVkX1+dtLyL9afcCVgUsS398SXILXeVu2chDWU/iU2vhS4ROIsnRK2hVZo4Hcj2YtdZhbY2ya/Tj4oti01RYOUf3Um9ZLjKUlRpuFeYA2AqdEpV8MY4qHGd6SRXE0b+MXeXareWJ6Mus2oBi3PNQsYhUw9F9O5Mmc1MGJdZiPo3ovYtKsOmlVKKxtBWyvNkRkw2DlFbw5WYGU0fI1dKJDh5lnjRKUIbX5CY7yqKl/2GFYD//cjQ7eyDtyqabFaJkYErA+qEeRjjFpQWEa+gjIrH3O/NfBASuUkKpsrd11oih6vyTX6pEnZEs7m1K2SpVoPOivQTDKYzRx7Clf9RsWFnUpKunLkPo3n6JqcfjNAbDqzohlSwYetwmCkS9APbmF2IVPoMxbkt+0EG/0GKm+wTO2hFTdSvOecqPvJJOJxUj81GxcsGj/BNtdnmLPnPeU3OSNyYM4Lrxg+i7RP+/n0habx4On2+2vw9pSSm0LoIT8JetWnGiRHDoNwprQXKXOx4g+Gil0KSve9JJ0LHzPs8BwmRgHCexW7tsgxxrJ0BpehzjS4Ho5mSPrG1HCR8x3m5+X03elZxmefnZlX2VipeyAKvRkPiy5Sm1OE6ozck15QAW47Iykfw5xMet9n76L0rMxB1+4lmJU7cXHNdhO6j0Cq7vzWIlYqHUHtLGMY3MvJUEQLJQx4u1au7xPiFnZhzVZjmrNoPxHCpZvsjoypzSNtrErq0cbI0E/jSQgT5WM2g1/tMig6VFe5Bvx2atvKOntt8lt2GR+Cmny16uGZzb252fEDcXNX9M3vqdgMNnB+gYLwdpc9eKkcRfZrAcp1KOz2jvmAdM1KTb9ULfot4MAg+RqrpEsHiYFFFoc87OvU+p6wM2h1W4wlAUAFwQo61SB7uecBKHinHZZS1lrs510oc4ridIal3wjyhkP1ulAo5Nwk/yBdvMwe/s2P0AYiqYc9o96ktRlo oSRQOyS3 Jh266kI/O2Elae61c2Mgp9Ov+IXiPhCYa4u9uAo4bTr3vbhVVkLspNyuJcAO/SwAz4blRSAfqRqXWkgdFdkWuB9ytHV8R7siQo16QNvuCYKSy+FPxk2vXnbxkC8njoPmjKhlkEABHIdieVhBNdxFaiwDhyPYPTnSAMzFyqEoTzfDSpjyDVj2s6L04gDU6uHUZPiv3DmXHMV/jgVY9wBsMJBhC8ZddAnvn5bTuS0cultr+eobegYO5oD07X/OQHhnDFD4HvAn40yAyaAdKgRHCaUFpfcQf++pJOtXL5r6UlOMsbj+xVcVzDNPaC88YkwDyOw3/xev9tKzYk5GQ41bTBvgWWQ+0U7FD/o4bKhxWbtsRhLSzwvPXSzMBeEyQAupY21LZRmHcEVHfSZRx+GJqeudNRrLKrSjCL3plwf32xXv6T30KIp7rldOq4YVadexA64WheYUjWMbxfjvKwZgFulkBEmCGFhkm9O9duHdBAPUKdCkLgaay6DbBja0VayyvGyx9dp7LvShn1JTLem4BTJnmdX+oNVSEtso4oUibGHMa5qqoVG5hZFh7ihBzXaO5FyQ35+gYTxVtMVY= X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: List-Subscribe: List-Unsubscribe: Replace the bespoke cifs iterators of ITER_BVEC and ITER_KVEC to do hashing with iterate_and_advance_kernel() - a variant on iterate_and_advance() that only supports kernel-internal ITER_* types and not UBUF/IOVEC types. The bespoke ITER_XARRAY is left because we don't really want to be calling crypto_shash_update() under the RCU read lock for large amounts of data; besides, ITER_XARRAY is going to be phased out. Signed-off-by: David Howells cc: Steve French cc: Paulo Alcantara cc: Tom Talpey cc: Enzo Matsumiya cc: linux-cifs@vger.kernel.org --- fs/smb/client/cifsencrypt.c | 109 ++++++++---------------------------- include/linux/iov_iter.h | 47 ++++++++++++++++ 2 files changed, 70 insertions(+), 86 deletions(-) diff --git a/fs/smb/client/cifsencrypt.c b/fs/smb/client/cifsencrypt.c index 6322f0f68a17..991a1ab047e7 100644 --- a/fs/smb/client/cifsencrypt.c +++ b/fs/smb/client/cifsencrypt.c @@ -21,82 +21,10 @@ #include #include #include +#include #include "../common/arc4.h" #include -/* - * Hash data from a BVEC-type iterator. - */ -static int cifs_shash_bvec(const struct iov_iter *iter, ssize_t maxsize, - struct shash_desc *shash) -{ - const struct bio_vec *bv = iter->bvec; - unsigned long start = iter->iov_offset; - unsigned int i; - void *p; - int ret; - - for (i = 0; i < iter->nr_segs; i++) { - size_t off, len; - - len = bv[i].bv_len; - if (start >= len) { - start -= len; - continue; - } - - len = min_t(size_t, maxsize, len - start); - off = bv[i].bv_offset + start; - - p = kmap_local_page(bv[i].bv_page); - ret = crypto_shash_update(shash, p + off, len); - kunmap_local(p); - if (ret < 0) - return ret; - - maxsize -= len; - if (maxsize <= 0) - break; - start = 0; - } - - return 0; -} - -/* - * Hash data from a KVEC-type iterator. - */ -static int cifs_shash_kvec(const struct iov_iter *iter, ssize_t maxsize, - struct shash_desc *shash) -{ - const struct kvec *kv = iter->kvec; - unsigned long start = iter->iov_offset; - unsigned int i; - int ret; - - for (i = 0; i < iter->nr_segs; i++) { - size_t len; - - len = kv[i].iov_len; - if (start >= len) { - start -= len; - continue; - } - - len = min_t(size_t, maxsize, len - start); - ret = crypto_shash_update(shash, kv[i].iov_base + start, len); - if (ret < 0) - return ret; - maxsize -= len; - - if (maxsize <= 0) - break; - start = 0; - } - - return 0; -} - /* * Hash data from an XARRAY-type iterator. */ @@ -145,27 +73,36 @@ static ssize_t cifs_shash_xarray(const struct iov_iter *iter, ssize_t maxsize, return 0; } +static size_t cifs_shash_step(void *iter_base, size_t progress, size_t len, + void *priv, void *priv2) +{ + struct shash_desc *shash = priv; + int ret, *pret = priv2; + + ret = crypto_shash_update(shash, iter_base, len); + if (ret < 0) { + *pret = ret; + return len; + } + return 0; +} + /* * Pass the data from an iterator into a hash. */ static int cifs_shash_iter(const struct iov_iter *iter, size_t maxsize, struct shash_desc *shash) { - if (maxsize == 0) - return 0; + struct iov_iter tmp_iter = *iter; + int err = -EIO; - switch (iov_iter_type(iter)) { - case ITER_BVEC: - return cifs_shash_bvec(iter, maxsize, shash); - case ITER_KVEC: - return cifs_shash_kvec(iter, maxsize, shash); - case ITER_XARRAY: + if (iov_iter_type(iter) == ITER_XARRAY) return cifs_shash_xarray(iter, maxsize, shash); - default: - pr_err("cifs_shash_iter(%u) unsupported\n", iov_iter_type(iter)); - WARN_ON_ONCE(1); - return -EIO; - } + + if (iterate_and_advance_kernel(&tmp_iter, maxsize, shash, &err, + cifs_shash_step) != maxsize) + return err; + return 0; } int __cifs_calc_signature(struct smb_rqst *rqst, diff --git a/include/linux/iov_iter.h b/include/linux/iov_iter.h index a223370a59a7..c4aa58032faf 100644 --- a/include/linux/iov_iter.h +++ b/include/linux/iov_iter.h @@ -328,4 +328,51 @@ size_t iterate_and_advance(struct iov_iter *iter, size_t len, void *priv, return iterate_and_advance2(iter, len, priv, NULL, ustep, step); } +/** + * iterate_and_advance_kernel - Iterate over a kernel-internal iterator + * @iter: The iterator to iterate over. + * @len: The amount to iterate over. + * @priv: Data for the step functions. + * @priv2: More data for the step functions. + * @step: Function for other iterators; given kernel addresses. + * + * Iterate over the next part of an iterator, up to the specified length. The + * buffer is presented in segments, which for kernel iteration are broken up by + * physical pages and mapped, with the mapped address being presented. + * + * [!] Note This will only handle BVEC, KVEC, FOLIOQ, XARRAY and DISCARD-type + * iterators; it will not handle UBUF or IOVEC-type iterators. + * + * A step functions, @step, must be provided, one for handling mapped kernel + * addresses and the other is given user addresses which have the potential to + * fault since no pinning is performed. + * + * The step functions are passed the address and length of the segment, @priv, + * @priv2 and the amount of data so far iterated over (which can, for example, + * be added to @priv to point to the right part of a second buffer). The step + * functions should return the amount of the segment they didn't process (ie. 0 + * indicates complete processsing). + * + * This function returns the amount of data processed (ie. 0 means nothing was + * processed and the value of @len means processes to completion). + */ +static __always_inline +size_t iterate_and_advance_kernel(struct iov_iter *iter, size_t len, void *priv, + void *priv2, iov_step_f step) +{ + if (unlikely(iter->count < len)) + len = iter->count; + if (unlikely(!len)) + return 0; + if (iov_iter_is_bvec(iter)) + return iterate_bvec(iter, len, priv, priv2, step); + if (iov_iter_is_kvec(iter)) + return iterate_kvec(iter, len, priv, priv2, step); + if (iov_iter_is_folioq(iter)) + return iterate_folioq(iter, len, priv, priv2, step); + if (iov_iter_is_xarray(iter)) + return iterate_xarray(iter, len, priv, priv2, step); + return iterate_discard(iter, len, priv, priv2, step); +} + #endif /* _LINUX_IOV_ITER_H */