From nobody Mon Feb 9 19:06:02 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 38CB1C7EE24 for ; Fri, 2 Jun 2023 10:18:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234410AbjFBKS4 (ORCPT ); Fri, 2 Jun 2023 06:18:56 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42828 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235289AbjFBKSp (ORCPT ); Fri, 2 Jun 2023 06:18:45 -0400 Received: from out0-199.mail.aliyun.com (out0-199.mail.aliyun.com [140.205.0.199]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9BBF4198; Fri, 2 Jun 2023 03:18:43 -0700 (PDT) X-Alimail-AntiSpam: AC=PASS;BC=-1|-1;BR=01201311R931e4;CH=green;DM=||false|;DS=||;FP=0|-1|-1|-1|0|-1|-1|-1;HT=ay29a033018047213;MF=changxian.cqs@antgroup.com;NM=1;PH=DS;RN=11;SR=0;TI=SMTPD_---.TJMsjA9_1685701117; Received: from localhost(mailfrom:changxian.cqs@antgroup.com fp:SMTPD_---.TJMsjA9_1685701117) by smtp.aliyun-inc.com; Fri, 02 Jun 2023 18:18:38 +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 v2 2/3] rust: kernel: implement iterators for ScatterList Date: Fri, 02 Jun 2023 18:18:18 +0800 Message-Id: <20230602101819.2134194-3-changxian.cqs@antgroup.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20230602101819.2134194-1-changxian.cqs@antgroup.com> References: <20230602101819.2134194-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 --- rust/kernel/scatterlist.rs | 50 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/rust/kernel/scatterlist.rs b/rust/kernel/scatterlist.rs index 8d6a34afb191..292fcb63a329 100644 --- a/rust/kernel/scatterlist.rs +++ b/rust/kernel/scatterlist.rs @@ -277,4 +277,54 @@ 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<'_> { + Iter(ScatterList::as_ref(self.opaque.get())) + } + + /// Get an iterator for mutable references. + pub fn iter_mut(&mut self) -> IterMut<'_> { + 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 { + if self.0.is_none() { + return None; + } + let ptr =3D self.0.as_ref().unwrap().opaque.get(); + // SAFETY: `ptr` is from `self.opaque`, it is valid by the type in= variant. + let next =3D unsafe { 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 { + if self.0.is_none() { + return None; + } + let ptr =3D self.0.as_ref().unwrap().opaque.get(); + // SAFETY: `ptr` is from `self.opaque`, it is valid by the type in= variant. + let next =3D unsafe { bindings::sg_next(ptr) }; + self.0 =3D ScatterList::as_mut(next); + ScatterList::as_mut(ptr) + } } --=20 2.40.1