From patchwork Mon Jul 29 16:19:51 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 13745445 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 817A8C3DA61 for ; Mon, 29 Jul 2024 16:23:09 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 1A5DC6B00BD; Mon, 29 Jul 2024 12:23:09 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 108D46B00BE; Mon, 29 Jul 2024 12:23:09 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id EC3286B00BF; Mon, 29 Jul 2024 12:23:08 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0014.hostedemail.com [216.40.44.14]) by kanga.kvack.org (Postfix) with ESMTP id CCC636B00BD for ; Mon, 29 Jul 2024 12:23:08 -0400 (EDT) Received: from smtpin21.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay09.hostedemail.com (Postfix) with ESMTP id 80C008048C for ; Mon, 29 Jul 2024 16:23:08 +0000 (UTC) X-FDA: 82393309656.21.35DBF37 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by imf17.hostedemail.com (Postfix) with ESMTP id B134F4000B for ; Mon, 29 Jul 2024 16:23:06 +0000 (UTC) Authentication-Results: imf17.hostedemail.com; dkim=pass header.d=redhat.com header.s=mimecast20190719 header.b=cTmqAxjo; spf=pass (imf17.hostedemail.com: domain of dhowells@redhat.com designates 170.10.129.124 as permitted sender) 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=1722270115; 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=buZw6b0nUIRREozdmRyhm21DaGUchoRzJLQCJCt8tmEyStcHnx2QXj2ZJtJeKC7O2LC0X6 6QLcFXw3o1SG4YuCm+KNQl382xU8e8peGUD1qJl9wYLMFkkZ2VgfrtiMNBMD0OUZk673kP yZ67v9TKnpUSm011JQ1NLn94bb+nbpw= ARC-Authentication-Results: i=1; imf17.hostedemail.com; dkim=pass header.d=redhat.com header.s=mimecast20190719 header.b=cTmqAxjo; spf=pass (imf17.hostedemail.com: domain of dhowells@redhat.com designates 170.10.129.124 as permitted sender) smtp.mailfrom=dhowells@redhat.com; dmarc=pass (policy=none) header.from=redhat.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1722270115; a=rsa-sha256; cv=none; b=RVhB4OaGxyBDdo7HBKzn2vAXlTHcn4E3MeCzv2mskiI4WUP+qNtAaA1GXhUZ4yZRvc/9mP CpTMbTxxZ1CCemHNvVyVkUh7lcTvYDOx8HB4HZIJLISk9PJWlTdZ/Z5+Jbxur0Eb/T5G/u ukE+vtdvWAgEjkQTy+UZ1FcG29CTRYQ= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1722270186; 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=cTmqAxjo5oxWmSH9Xkqygr2JUdRuUu/IkNOw2+aXTHpj4e8XHFCfPTfazd3mL/Q1z1nstQ tTI7DBh1mg4dXkfPL0kVewU5EZsSiy1Hrm01D9CA+hiFwZVtL5+Sh564oTgxwxaPOHzYJQ DbtzoctmgINAHTXppPy4UqadY9shO3A= 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-683-Rp35iph8MDSlXbzmKb2lfw-1; Mon, 29 Jul 2024 12:23:00 -0400 X-MC-Unique: Rp35iph8MDSlXbzmKb2lfw-1 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (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 775131955BF8; Mon, 29 Jul 2024 16:22:57 +0000 (UTC) Received: from warthog.procyon.org.uk.com (unknown [10.42.28.216]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 585A119560AE; Mon, 29 Jul 2024 16:22:51 +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 22/24] cifs: Use iterate_and_advance*() routines directly for hashing Date: Mon, 29 Jul 2024 17:19:51 +0100 Message-ID: <20240729162002.3436763-23-dhowells@redhat.com> In-Reply-To: <20240729162002.3436763-1-dhowells@redhat.com> References: <20240729162002.3436763-1-dhowells@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 X-Rspamd-Server: rspam06 X-Rspamd-Queue-Id: B134F4000B X-Stat-Signature: cesxw1chc3fw5hw5s3txurpofcd8cp61 X-Rspam-User: X-HE-Tag: 1722270186-444716 X-HE-Meta: U2FsdGVkX1+A/4l7wCE1GT6x6d0K4lPfwT85MFAGprWMiL/dAT6U8dSZJRbpjmZIPZ2Kx4T3ftVtR7o1O+kz2rVga+1waWWT945AMib+MKfQGXduhpifu1ibg7N4SUS1COduT7T/KCLYAimS1qRjsIhdLvft+Qo9dtY3dzJH4EaKptOJr1u0VJIMznSBcooD2fvMxnq4jMogSJeVLvHm6ltmnvNti1sGQDOHckXE70XHiueRA7uZ6frYebhRZ2JPHxCoErpqHYkFvL/WDLZlxpL12fb3KL3a/oWgt0aFTdM582L1rtIYlbM9IujwCmA1/U8aS+PmkNScZpwfsyLwjYnyoNWxItnLmbJLy6NNxT9UT+sEy1S5nhwohTfv3xBNMwR7kI13qoPpBa3oqdZx8192+d7ftPomouH9C9enloSJwe8vrWFBj9oWB08cMlWLGcuDihEyrvLyrWSKe6JR2pq75Jetuu3xY9HoVYx6qQ0vsDMuseHy9H3/pwKOCnXqzDHKKKgrEPDOVKqAvjA7gx0FItcRH5q5EW4joUZfZ3CKJBGZ2auRg+3x5mssbJXF53AKDcy3ttNL+nPqGeq2+t46ljqke+Wrw1e/anOELVFk1LCG3KZ4uKNQJXW3Bo34doLiy0Zjc/aDp3pZ1W60EPgTpmZ6lhTSFDPBAjaCzA3+X5EGFkBYlLR1I25bz6MGpwTzfDJy6d/9zC4S7Nm/9BONaGA4kSVzDwyz93A5MTOFygrwOW8h9GbJYwNwQ37pj+KM37aBHjTb7iSn/+6BhYDYXXyqvssO7JcAt1SUw/K6IvY/j4RNMCevXjvIQfJX+4zHkq7Xn8JkuEEer3OWsDBFwD1hfrbeMiGlNAA2Gnd1sR1BpnaK7WbOhzedaZNCNeG+lkdpeyaJUqVxGDiOlwSOjcrhs3z2sI36OSIDoMhC1qh+9miJ5Yf8Jc6wqudCNauRXl+eNUVkH+TliER LwT/uTxL qasBLCrYoZZXlXjFy9IBCM4E82llrKG1lz+FXqq6/Kvl24CTMNPXX0ESf7QVWnD3E+m5RAVHDMzH8efzDl9bupb2HQm2zNiOLlYa5m2M61SbvnNZdJgHUfYxc6oJY5D/sjd3kMUvrhD1Yej0YrmrmrQFzb66TIVLrBSONaPyRPoVZHr1YhLuuVHYoKyw/CMsyGHZdvaHkM/EwAitoM0zIHV4OLSTvGn+xK3Z/vTvqQPMG3Qy4EFRdfzJv2vO9qsrg3B765zVUDM9A6ckFrgyQ6GeDxxuau0kQzOecLLUnPZlu1cIPWQ0hwhTJEfwBcddDoybv6ZqF2nY2ojdxqK9nUmYJSX1YFRLk7mNUocDiaqO7PFUuippeJc/Izm3kYMmueeIxbN1B23hel1NlsYfOo/ZQ3HHSIkNFZchz56IpFJwMK6M/FV2oCJT2dDr39VFB76L6cXtvBr/UOiEWh1EVnhsp3XipFQNqZcsqYpQDsaUinymIRLNnRFEqx/THMZmdaEpDvf8GBy1x7A6iZ5dzyWLTzcmHhYceZpGDbpnpwqCFLM9q4LOGNgVYTjOthbab6liSug+/aOUk+Oc= 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 */