From nobody Mon Feb 9 17:35:36 2026 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 147EDC77B7A for ; Sat, 10 Jun 2023 10:49:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234292AbjFJKtl (ORCPT ); Sat, 10 Jun 2023 06:49:41 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48930 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234222AbjFJKtf (ORCPT ); Sat, 10 Jun 2023 06:49:35 -0400 Received: from out0-206.mail.aliyun.com (out0-206.mail.aliyun.com [140.205.0.206]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 72B8E35BC; Sat, 10 Jun 2023 03:49:31 -0700 (PDT) X-Alimail-AntiSpam: AC=PASS;BC=-1|-1;BR=01201311R131e4;CH=green;DM=||false|;DS=||;FP=0|-1|-1|-1|0|-1|-1|-1;HT=ay29a033018047209;MF=changxian.cqs@antgroup.com;NM=1;PH=DS;RN=11;SR=0;TI=SMTPD_---.TQGLBah_1686394167; Received: from localhost(mailfrom:changxian.cqs@antgroup.com fp:SMTPD_---.TQGLBah_1686394167) by smtp.aliyun-inc.com; Sat, 10 Jun 2023 18:49:28 +0800 From: "Qingsong Chen" To: linux-kernel@vger.kernel.org Cc: "=?UTF-8?B?55Sw5rSq5Lqu?=" , "Qingsong Chen" , "Miguel Ojeda" , "Alex Gaynor" , "Wedson Almeida Filho" , "Boqun Feng" , "Gary Guo" , "=?UTF-8?q?Bj=C3=B6rn=20Roy=20Baron?=" , "Benno Lossin" , Subject: [PATCH v3 2/3] rust: kernel: implement iterators for ScatterList Date: Sat, 10 Jun 2023 18:49:08 +0800 Message-Id: <20230610104909.3202958-3-changxian.cqs@antgroup.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20230610104909.3202958-1-changxian.cqs@antgroup.com> References: <20230610104909.3202958-1-changxian.cqs@antgroup.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" ScatterList could be transmuted from raw pointers of a valid `sg_table`. Then we can use those iterators to access the following normal entries. Signed-off-by: Qingsong Chen Reviewed-by: Martin Rodriguez Reboredo --- rust/kernel/scatterlist.rs | 58 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/rust/kernel/scatterlist.rs b/rust/kernel/scatterlist.rs index 7fb8f3326ff3..41e268b93c9e 100644 --- a/rust/kernel/scatterlist.rs +++ b/rust/kernel/scatterlist.rs @@ -290,4 +290,62 @@ impl ScatterList<'_> { // SAFETY: By the type invariant, we know that `self.opaque` is va= lid. unsafe { bindings::sg_nents(self.opaque.get()) as _ } } + + /// Get an iterator for immutable references. + pub fn iter(&self) -> Iter<'_> { + // SAFETY: By the type invariant, we know that `self.opaque` is va= lid. + unsafe { Iter(ScatterList::as_ref(self.opaque.get())) } + } + + /// Get an iterator for mutable references. + pub fn iter_mut(&mut self) -> IterMut<'_> { + // SAFETY: By the type invariant, we know that `self.opaque` is va= lid. + unsafe { IterMut(ScatterList::as_mut(self.opaque.get())) } + } +} + +/// An iterator that yields [`Pin<&ScatterList>`]. +/// +/// Only iterate normal scatterlist entries, chainable entry will be skipp= ed. +pub struct Iter<'a>(Option>>); + +impl<'a> Iterator for Iter<'a> { + type Item =3D Pin<&'a ScatterList<'a>>; + + fn next(&mut self) -> Option { + let ptr =3D match &self.0 { + None =3D> return None, + Some(sgl) =3D> sgl.opaque.get(), + }; + // SAFETY: `ptr` is from `self.opaque`, it is valid by the type in= variant. + // And `next` is null, or the next valid scatterlist entry. + unsafe { + let next =3D bindings::sg_next(ptr); + self.0 =3D ScatterList::as_ref(next); + ScatterList::as_ref(ptr) + } + } +} + +/// An iterator that yields [`Pin<&mut ScatterList>`]. +/// +/// Only iterate normal scatterlist entries, chainable entry will be skipp= ed. +pub struct IterMut<'a>(Option>>); + +impl<'a> Iterator for IterMut<'a> { + type Item =3D Pin<&'a mut ScatterList<'a>>; + + fn next(&mut self) -> Option { + let ptr =3D match &self.0 { + None =3D> return None, + Some(sgl) =3D> sgl.opaque.get(), + }; + // SAFETY: `ptr` is from `self.opaque`, it is valid by the type in= variant. + // And `next` is null, or the next valid scatterlist entry. + unsafe { + let next =3D bindings::sg_next(ptr); + self.0 =3D ScatterList::as_mut(next); + ScatterList::as_mut(ptr) + } + } } --=20 2.40.1