From nobody Tue Feb 10 12:40:34 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 BE8F1C001B1 for ; Sun, 25 Jun 2023 12:18:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232084AbjFYMR7 (ORCPT ); Sun, 25 Jun 2023 08:17:59 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49420 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232133AbjFYMRr (ORCPT ); Sun, 25 Jun 2023 08:17:47 -0400 Received: from out0-219.mail.aliyun.com (out0-219.mail.aliyun.com [140.205.0.219]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 79E3210F6; Sun, 25 Jun 2023 05:17:33 -0700 (PDT) X-Alimail-AntiSpam: AC=PASS;BC=-1|-1;BR=01201311R201e4;CH=green;DM=||false|;DS=||;FP=0|-1|-1|-1|0|-1|-1|-1;HT=ay29a033018047205;MF=changxian.cqs@antgroup.com;NM=1;PH=DS;RN=11;SR=0;TI=SMTPD_---.TdJuHaw_1687695449; Received: from localhost(mailfrom:changxian.cqs@antgroup.com fp:SMTPD_---.TdJuHaw_1687695449) by smtp.aliyun-inc.com; Sun, 25 Jun 2023 20:17:29 +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: [RFC PATCH 5/8] rust: kernel: add underlying device related TargetOperations Date: Sun, 25 Jun 2023 20:16:54 +0800 Message-Id: <20230625121657.3631109-6-changxian.cqs@antgroup.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20230625121657.3631109-1-changxian.cqs@antgroup.com> References: <20230625121657.3631109-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" - Add `prepare_ioctl` to pass ioctls to underlying device. - Add `iterate_devices` to iterate underlying devices. - Add `io_hints` to setup target request queue limits. Signed-off-by: Qingsong Chen --- rust/kernel/device_mapper.rs | 101 +++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) diff --git a/rust/kernel/device_mapper.rs b/rust/kernel/device_mapper.rs index 9a62208fda56..ba13294f2d0b 100644 --- a/rust/kernel/device_mapper.rs +++ b/rust/kernel/device_mapper.rs @@ -118,6 +118,24 @@ fn message(t: &mut Target, args: Args) -> Result= { fn report_zones(t: &mut Target, args: &mut [ReportZonesArgs]) ->= Result { unimplemented!() } + + /// Pass on ioctl to the underlying device. + #[allow(unused)] + fn prepare_ioctl(t: &mut Target) -> (i32, Option>>) { + unimplemented!() + } + + /// Iterate the underlying devices. + #[allow(unused)] + fn iterate_devices(t: &mut Target) -> Result>>> { + unimplemented!() + } + + /// Setup target request queue limits. + #[allow(unused)] + fn io_hints(t: &mut Target, limits: &mut QueueLimits) { + unimplemented!() + } } =20 /// Wrap the kernel struct `target_type`. @@ -193,6 +211,9 @@ pub fn register( (HAS_STATUS, status, dm_status_fn), (HAS_MESSAGE, message, dm_message_fn), (HAS_REPORT_ZONES, report_zones, dm_report_zones_fn), + (HAS_PREPARE_IOCTL, prepare_ioctl, dm_prepare_ioctl_fn= ), + (HAS_ITERATE_DEVICES, iterate_devices, dm_iterate_devi= ces_fn), + (HAS_IO_HINTS, io_hints, dm_io_hints_fn), ); =20 to_result(bindings::dm_register_target(tt)) @@ -411,6 +432,68 @@ impl TargetType { }; T::report_zones(t, args).map_or_else(|e| e.to_errno(), |_| 0) } + unsafe extern "C" fn dm_prepare_ioctl_fn( + ti: *mut bindings::dm_target, + bdev: *mut *mut bindings::block_device, + ) -> core::ffi::c_int { + // SAFETY: the kernel should pass valid `dm_target` pointer. + let t =3D unsafe { Target::borrow_mut(ti) }; + + match T::prepare_ioctl(t) { + (err, None) =3D> err, + // SAFETY: `td` and `dev` is `NonNull`, both of them are valid. + (ret, Some(td)) =3D> unsafe { + let dm_dev =3D td.as_ref().dev.as_ptr(); + let block_dev =3D (*dm_dev).bdev; + *bdev =3D block_dev; + ret + }, + } + } + unsafe extern "C" fn dm_iterate_devices_fn( + ti: *mut bindings::dm_target, + fn_: bindings::iterate_devices_callout_fn, + data: *mut core::ffi::c_void, + ) -> core::ffi::c_int { + let Some(fn_) =3D fn_ else { + pr_warn!("Invalid iterate_devices_callout_fn, skipped!"); + return 0; + }; + + // SAFETY: the kernel should pass valid `dm_target` pointer. + let t =3D unsafe { Target::borrow_mut(ti) }; + let devices =3D match T::iterate_devices(t) { + Err(e) =3D> return e.to_errno(), + Ok(devices) =3D> devices, + }; + + let mut ret =3D 0; + for (target_device, start, len) in devices { + // SAFETY: `target_device` is `NonNull`, it is also valid. + // `fn_` is checked above, it is non-null, and the kernel + // should pass valid `iterate_devices_callout_fn`. + unsafe { + let dev =3D target_device.as_ref().dev.as_ptr(); + ret =3D fn_(ti, dev, start as _, len as _, data); + if ret !=3D 0 { + break; + } + } + } + ret + } + unsafe extern "C" fn dm_io_hints_fn( + ti: *mut bindings::dm_target, + limits: *mut bindings::queue_limits, + ) { + // SAFETY: the kernel should pass valid `dm_target` and `queue_lim= its` + // pointers. + unsafe { + let t =3D Target::borrow_mut(ti); + let limits =3D QueueLimits::borrow_mut(limits); + T::io_hints(t, limits); + } + } } =20 /// Wrap the kernel struct `dm_target`. @@ -549,6 +632,12 @@ fn drop(&mut self) { } } =20 +/// Gather info about underlying device of target. +/// +/// The first is the [`TargetDevice`], the second is the start sector of +/// the device, and the third is the length (in sectors) of the device. +pub type IterDevice =3D (NonNull>, usize, usize); + /// The return values of target map function, i.e., [`TargetOperations::ma= p`]. #[repr(u32)] pub enum MapState { @@ -802,3 +891,15 @@ fn from(value: u32) -> Self { } } } + +/// Wrap the kernel struct `queue_limits`. +/// +/// Dummy. +pub struct QueueLimits(Opaque); + +impl QueueLimits { + unsafe fn borrow_mut<'a>(ptr: *mut bindings::queue_limits) -> &'a mut = Self { + // SAFETY: the caller should pass a valid `ptr`. + unsafe { &mut *(ptr as *mut Self) } + } +} --=20 2.40.1