From nobody Sun Feb 8 18:16:49 2026 Received: from mail-wm1-f74.google.com (mail-wm1-f74.google.com [209.85.128.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2BB9F25BAB7 for ; Tue, 11 Mar 2025 14:26:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.74 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741703164; cv=none; b=khy2eCAC03aFwbHSXWr50ptstNkZTl9A38drNV4c99mQM/f1HzmeLetBhyWBkQ5jmGm2jAg8kcgrT597txod8X6NplvsZwAOSuOQ1n8zKVUuqkK247dmYnjyts5S4ewU/yyhMVzEhHqkm+k/+rQEukY6genPwaS97g6iSTgRPcE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741703164; c=relaxed/simple; bh=wrUCwsyJRmjP/dsv9Wg9msOH5X59Uyr1+r3sd7reY1c=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=FeXPRnKeSi+rByetBgalzEfl8BiSFisCCfDt7Jhn4DLM+KSqKDqrkPvrd4HbAJ3ecCWdNf5ysDzK1gAVUI/tw0Q80A/LM9jLUK/FQTrhkQA10rVsE8+r8m4ZT+59AQ5D+YFdmguMTLIwM7yDMxU1pLhdjaqB9nyUSmQUkLqE68I= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--aliceryhl.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=FZp307yP; arc=none smtp.client-ip=209.85.128.74 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--aliceryhl.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="FZp307yP" Received: by mail-wm1-f74.google.com with SMTP id 5b1f17b1804b1-43947979ce8so25470995e9.0 for ; Tue, 11 Mar 2025 07:26:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1741703160; x=1742307960; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=XAQ1FUliBVYkaAD+n9y8S+Mp9b1382qcZiMQ8LUAODU=; b=FZp307yPjMWkHDl1QCazn0FazdFTszJkCW7uytV+SertkCQTINQ981XxmyPJZCzByG NEEuDrrzB9uD1FyChDR0PYgB2cl9UDSYAClAfXoRHXcpm4PZc0UZg9Tc7E9hKl+H1oNz kis3Ak6sPEGH1DnHrjcbbLAOAVh6ifa4I4npXbLLlCY7vwzpgwm/lAQPfBbpDhINw7iH n3uI9ngH5N7Bd1EqwmF0sq0WGsrihpbHRIbVMUo80IFo6EgCvXPoQSZ+7ZXTkxnW9oMA PgduFFOMK8jh63c9hiELKVF34khupoH55SBbLiP5KzBuazcPLeWyzUmpZFdszAsz5ugP X30A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741703160; x=1742307960; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=XAQ1FUliBVYkaAD+n9y8S+Mp9b1382qcZiMQ8LUAODU=; b=ln7U18XPlfA2d8+3VFfGHf63kPRu3SG/kWEEatahmKDCdY+fjeeIRMGNXORAhTEO+k MEWL7hV0jxKK0xF3Z1wz71ThMQBnrSTfG7lILNyfMDV7aAr3EUTh84Idaa9SxF1DwyVq M/+VLV9SdYP9UgLzJ+9ELgGZ6U352pj82OFgUSuzZMQABHvB3ZYP+c+StgUm0MUr6W7m KanDvzpKF/wCyJaMXi+33nhCrRIo1qcRDzZx+WRm62hxNpFDEXxKukk5WMt+fLHqduxU Pta6+v3vk5ErN5dFoICtSk/UzjHP3dShxpXvSA0NcJI9Wt7C9cBuzjesSZrJ8/VYsEYY NIlA== X-Forwarded-Encrypted: i=1; AJvYcCWYDBE5aFi5RNAmBYfIuy1c4+SnuEKYxIEWdIEKOiYvaNB3ScVKCSeyXrbAVpamXN4X1o7zs5Pv9G1nfsE=@vger.kernel.org X-Gm-Message-State: AOJu0YwuAVKZVyPWAswQbyVIDvqu2SMFgg1vU3IeuRo2NASDVt37/T67 kp52zl8xe3k4xQ37zXS0cc/n1AsVXN6mGvGy+6McXltGvA9VT3k76fE7GjVmV2PRGM4qPhi4vdK ap+v82Tqos612Kw== X-Google-Smtp-Source: AGHT+IH8X7syBO/BR94wku7hfOlNXYhoSadQYVQ/hyX3LTlizGhCLEDVYfRSWty4zN9vf03B+L910ZT+M2/N6SM= X-Received: from wmbbe11.prod.google.com ([2002:a05:600c:1e8b:b0:43c:f482:222]) (user=aliceryhl job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:3143:b0:43c:fe90:1282 with SMTP id 5b1f17b1804b1-43d01bdbac8mr51871555e9.7.1741703160581; Tue, 11 Mar 2025 07:26:00 -0700 (PDT) Date: Tue, 11 Mar 2025 14:25:12 +0000 In-Reply-To: <20250311-iov-iter-v1-0-f6c9134ea824@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20250311-iov-iter-v1-0-f6c9134ea824@google.com> X-Developer-Key: i=aliceryhl@google.com; a=openpgp; fpr=49F6C1FAA74960F43A5B86A1EE7A392FDE96209F X-Developer-Signature: v=1; a=openpgp-sha256; l=8113; i=aliceryhl@google.com; h=from:subject:message-id; bh=wrUCwsyJRmjP/dsv9Wg9msOH5X59Uyr1+r3sd7reY1c=; b=owEBbQKS/ZANAwAKAQRYvu5YxjlGAcsmYgBn0EfxJH+IABQmDdLn38Mk4R76y27qEBjJKm65Y aG7qXtCIJqJAjMEAAEKAB0WIQSDkqKUTWQHCvFIvbIEWL7uWMY5RgUCZ9BH8QAKCRAEWL7uWMY5 Rn+oD/42n0z0SD+PdVC5NR+ZfVL4W3oeFFdAg7N2bnebrHCnrlLaQw4peRCitr6iJaMbiwLKAsw WSGE3kGs7xPtrn4SIGPI5y4xU32AJUYyRGi7wswlmreWq+4r68TmsfW8+JY3l5GsrFxRbA5T0H4 vp3hXn4uCSIj5pblg3c0lu7GLTbqn4/761ctDpz7G0qD0hDQ8RdpFu87nCiX5COiGZRNy7qOVuA eIwmNhOugYhtpboYxmMP+nijjoq8Zkpjpchc/8PboDqcvafM3HxndMcPwmS7XA+YDDExS8s+VHl dK7Ka23FoRqfGmTTr9sthJxtGU/2GiXKcbr+pQsa2az05OyvFyMOsQ2IK3bBCi2TEVmCTYNHCQn 0N20KYmmOAWcy3PUkMYR0sdhBZaa1Wodo2xXHbJPERruDdpXNKUeRLDJjy/RuIT1GngAvZNeJLA M7JdhaPEAzRArDqpqvhFTsGsikfH9KBA07va+kX8s3XFCNPInE8XkmCTkP34YY0ly0qPbIzBhdk pQrCq7/2767EOtxI1wYPXRuKeXeyljmdqqU1nSYWLK78zgnuxCkmvb4ZnhF7AON3R+AdtaOuHHn ZLf6hGQ6FGvjrxyO3I/7uE1qrjmoWqUbiXfcR1Hks0f36KyOk+70NnxDko4W6A6oFO8zVhKKs46 OBUsrNt/Y4Y4Sbw== X-Mailer: b4 0.14.2 Message-ID: <20250311-iov-iter-v1-1-f6c9134ea824@google.com> Subject: [PATCH 1/5] rust: iov: add iov_iter abstractions for ITER_SOURCE From: Alice Ryhl To: Greg Kroah-Hartman , Alexander Viro , Arnd Bergmann , Miguel Ojeda Cc: Boqun Feng , Gary Guo , "=?utf-8?q?Bj=C3=B6rn_Roy_Baron?=" , Benno Lossin , Andreas Hindborg , Trevor Gross , Danilo Krummrich , Matthew Maurer , Lee Jones , linux-kernel@vger.kernel.org, rust-for-linux@vger.kernel.org, Alice Ryhl Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable This adds abstractions for the iov_iter type in the case where data_source is ITER_SOURCE. This will make Rust implementations of fops->write_iter possible. This series only has support for using existing IO vectors created by C code. Additional abstractions will be needed to support the creation of IO vectors in Rust code. These abstractions make the assumption that `struct iov_iter` does not have internal self-references, which implies that it is valid to move it between different local variables, and that you can make a copy of it to get two IO vectors into the same buffers. Signed-off-by: Alice Ryhl --- rust/kernel/iov.rs | 170 +++++++++++++++++++++++++++++++++++++++++++++++++= ++++ rust/kernel/lib.rs | 1 + 2 files changed, 171 insertions(+) diff --git a/rust/kernel/iov.rs b/rust/kernel/iov.rs new file mode 100644 index 0000000000000000000000000000000000000000..4498f65e1f65bd964909810c020= db3a9f8fae389 --- /dev/null +++ b/rust/kernel/iov.rs @@ -0,0 +1,170 @@ +// SPDX-License-Identifier: GPL-2.0 + +// Copyright (C) 2025 Google LLC. + +//! IO vectors. +//! +//! C headers: [`include/linux/iov_iter.h`](srctree/include/linux/iov_iter= .h), +//! [`include/linux/uio.h`](srctree/include/linux/uio.h) + +use crate::{bindings, prelude::*, types::Opaque}; +use core::{marker::PhantomData, mem::MaybeUninit, slice}; + +const ITER_SOURCE: bool =3D bindings::ITER_SOURCE !=3D 0; +const ITER_DEST: bool =3D bindings::ITER_DEST !=3D 0; + +// Compile-time assertion for the above constants. +const _: () =3D { + if ITER_SOURCE =3D=3D ITER_DEST { + panic!("ITER_DEST and ITER_SOURCE should be different."); + } +}; + +/// An IO vector that acts as a source of data. +/// +/// # Invariants +/// +/// Must hold a valid `struct iov_iter` with `data_source` set to `ITER_SO= URCE`. The buffers +/// referenced by the IO vector must be valid for reading for the duration= of `'data`. +/// +/// Note that if the IO vector is backed by a userspace pointer, it is alw= ays considered valid for +/// reading. +#[repr(transparent)] +pub struct IovIterSource<'data> { + iov: Opaque, + /// Represent to the type system that this value contains a pointer to= readable data it does + /// not own. + _source: PhantomData<&'data [u8]>, +} + +// SAFETY: This struct is essentially just a fancy `std::io::Cursor<&[u8]>= `, and that type is safe +// to send across thread boundaries. +unsafe impl<'data> Send for IovIterSource<'data> {} +// SAFETY: This struct is essentially just a fancy `std::io::Cursor<&[u8]>= `, and that type is safe +// to share across thread boundaries. +unsafe impl<'data> Sync for IovIterSource<'data> {} + +impl<'data> IovIterSource<'data> { + /// Obtain an `IovIterSource` from a raw pointer. + /// + /// # Safety + /// + /// * For the duration of `'iov`, the `struct iov_iter` must remain va= lid and must not be + /// accessed except through the returned reference. + /// * For the duration of `'data`, the buffers backing this IO vector = must be valid for + /// reading. + #[track_caller] + #[inline] + pub unsafe fn from_raw<'iov>(ptr: *mut bindings::iov_iter) -> &'iov mu= t IovIterSource<'data> { + // SAFETY: The caller ensures that `ptr` is valid. + let data_source =3D unsafe { (*ptr).data_source }; + assert_eq!(data_source, ITER_SOURCE); + + // SAFETY: The caller ensures the struct invariants for the right = durations. + unsafe { &mut *ptr.cast::>() } + } + + /// Access this as a raw `struct iov_iter`. + #[inline] + pub fn as_raw(&mut self) -> *mut bindings::iov_iter { + self.iov.get() + } + + /// Returns the number of bytes available in this IO vector. + /// + /// Note that this may overestimate the number of bytes. For example, = reading from userspace + /// memory could fail with EFAULT, which will be treated as the end of= the IO vector. + #[inline] + pub fn len(&self) -> usize { + // SAFETY: It is safe to access the `count` field. + unsafe { + (*self.iov.get()) + .__bindgen_anon_1 + .__bindgen_anon_1 + .as_ref() + .count + } + } + + /// Returns whether there are any bytes left in this IO vector. + /// + /// This may return `true` even if there are no more bytes available. = For example, reading from + /// userspace memory could fail with EFAULT, which will be treated as = the end of the IO vector. + #[inline] + pub fn is_empty(&self) -> bool { + self.len() =3D=3D 0 + } + + /// Advance this IO vector by `bytes` bytes. + /// + /// If `bytes` is larger than the size of this IO vector, it is advanc= ed to the end. + #[inline] + pub fn advance(&mut self, bytes: usize) { + // SAFETY: `self.iov` is a valid IO vector. + unsafe { bindings::iov_iter_advance(self.as_raw(), bytes) }; + } + + /// Advance this IO vector backwards by `bytes` bytes. + /// + /// # Safety + /// + /// The IO vector must not be reverted to before its beginning. + #[inline] + pub unsafe fn revert(&mut self, bytes: usize) { + // SAFETY: `self.iov` is a valid IO vector, and `bytes` is in boun= ds. + unsafe { bindings::iov_iter_revert(self.as_raw(), bytes) }; + } + + /// Read data from this IO vector. + /// + /// Returns the number of bytes that have been copied. + #[inline] + pub fn copy_from_iter(&mut self, out: &mut [u8]) -> usize { + // SAFETY: We will not write uninitialized bytes to `out`. + let out =3D unsafe { &mut *(out as *mut [u8] as *mut [MaybeUninit<= u8>]) }; + + self.copy_from_iter_raw(out).len() + } + + /// Read data from this IO vector and append it to a vector. + /// + /// Returns the number of bytes that have been copied. + #[inline] + pub fn copy_from_iter_vec( + &mut self, + out: &mut Vec, + flags: Flags, + ) -> Result { + out.reserve(self.len(), flags)?; + let len =3D self.copy_from_iter_raw(out.spare_capacity_mut()).len(= ); + // SAFETY: The next `len` bytes of the vector have been initialize= d. + unsafe { out.set_len(out.len() + len) }; + Ok(len) + } + + /// Read data from this IO vector into potentially uninitialized memor= y. + /// + /// Returns the sub-slice of the output that has been initialized. If = the returned slice is + /// shorter than the input buffer, then the entire IO vector has been = read. + #[inline] + pub fn copy_from_iter_raw(&mut self, out: &mut [MaybeUninit]) -> &= mut [u8] { + // SAFETY: `out` is valid for `out.len()` bytes. + let len =3D + unsafe { bindings::_copy_from_iter(out.as_mut_ptr().cast(), ou= t.len(), self.as_raw()) }; + + // SAFETY: We just initialized the first `len` bytes of `out`. + unsafe { slice::from_raw_parts_mut(out.as_mut_ptr().cast(), len) } + } +} + +impl<'data> Clone for IovIterSource<'data> { + #[inline] + fn clone(&self) -> IovIterSource<'data> { + // SAFETY: This duplicates the bytes inside the `Opaque` value exa= ctly. Since `struct + // iov_iter` does not have any internal self references, that is o= kay. + // + // Since this IO vector only reads from the backing buffers, havin= g multiple IO vectors to + // the same source can't lead to data races on the backing buffers. + unsafe { core::ptr::read(self) } + } +} diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs index 398242f92a961c3a445d681c65449047a847968a..de9d6e797953cb69637eef12799= 7b1f357f3f90b 100644 --- a/rust/kernel/lib.rs +++ b/rust/kernel/lib.rs @@ -53,6 +53,7 @@ pub mod init; pub mod io; pub mod ioctl; +pub mod iov; pub mod jump_label; #[cfg(CONFIG_KUNIT)] pub mod kunit; --=20 2.49.0.rc0.332.g42c0ae87b1-goog From nobody Sun Feb 8 18:16:49 2026 Received: from mail-wr1-f74.google.com (mail-wr1-f74.google.com [209.85.221.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3ED2A25D52E for ; Tue, 11 Mar 2025 14:26:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.74 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741703166; cv=none; b=nNK9D4LhSVA8pzlb47ykaU09zIvNatdpFH1GU8r5qKBTYeR0pGxg+/pJNLGXg7pl91I61pFof2fGUdoyaGIlHSHDKIgZQ7P0MImbodLXSg37yELB3lnbmc3lzB4pxfosh8ExA8AwaGOwSENGaikGy4Ezrz7gEP89leJ8cBuQwYk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741703166; c=relaxed/simple; bh=YLDJfnUbMN1PwSSNtSoEcVZjewJZ9nhxstVqcUUfZU4=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=t/GpMsWsDjgD4RUGroOk2P2N89uePWSoMshuwRZkHTpopIu+6zvuPtq61OKJuPlNm4xzJlVuBceqwhRuXZRYezQ4D+2RwElhys13K/hAs22r+VgY6UQlWlleeYyuTB2MlifvZArc0L1B/55ACEP0h6bPX+yz9MFrj/aA2/vmHEs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--aliceryhl.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=BmlBXMoo; arc=none smtp.client-ip=209.85.221.74 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--aliceryhl.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="BmlBXMoo" Received: by mail-wr1-f74.google.com with SMTP id ffacd0b85a97d-3913b2d355fso1183841f8f.1 for ; Tue, 11 Mar 2025 07:26:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1741703162; x=1742307962; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=+J030Kyqth9TY6nINgFDo0/N/i2k+o/+joXPh9/zVi4=; b=BmlBXMoo823cAaVz81GY0ngfTN6JGtmTcJmLekB9/fbj2pZYH3/Y8e57ggEPWSfh5+ 7zrGPMDeD26io277z7eyuotCavjv03+DOuuLPShHs37G4e6gMnprJm4kz+xaWmon6jex i8aaRNZliQnGsx5KgvE5Nk0/agzdy8HqWxCrSban87R10l63Qy19EDZ0OfpF6irXUNNX XntolFDcebC5EOWXq292ZA1Hco/4q92OmLOEqELOdGMQ6xuPaFOiRb8l82Mjp01YvfZc fDiq7HEBt6hGUcmjFTN51G38mV9iblY8uwtSjEzTDPsgPL6l6g7gMqd3/SSsSxBxkJh/ S7yw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741703162; x=1742307962; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=+J030Kyqth9TY6nINgFDo0/N/i2k+o/+joXPh9/zVi4=; b=MLaEgW09c91ffMQRUOjGDJVpAROSlKMcVUd9eTM/jIjm9xTEYema+V00r52b9lj0SR 5qeAZiXmiyz9pmLOj/otKBLM/TGeDl4rK2o7MQIYHRL9ytwxapneNbobXXdMfOkl68ZL AYJC+uUNTO5R6/XKWpczIwzTlGbNESlL+D7KCLy9gNRQYVIifORzVbMilOXAGKBqz9Ej mBT0NDdV9QK3cc6D8R32mzcfgFBAh1TyyhzHJkRuFCFGjD+t7xYiUmz11KxltmdJErt2 04dUVtW0m6mrcKWyVBg5jw19G9Cqh/vPqsH4tnYJqVHt4t+Rl5EmrwPmBixqZCz/Ne1s PQ9w== X-Forwarded-Encrypted: i=1; AJvYcCU0rUsqQK43c4h4X7HMEJul6HwUd/5UP0239MX0dAdkc+LV7mUi6QVdD2iDVp35S6MPKzHHcR/OBnRXlKY=@vger.kernel.org X-Gm-Message-State: AOJu0YyXZR0joV6EE1HEvgdnWC86SIvgcywRmokVB06Q0LOUDQ53dot2 EhC/eQDboz0EkeVkW1QNAHX9QGafnydwdfYMKoy3pkvBn2VRTOkZ3mg3f8pJmpQDIcYZ5pjtpHx 6dWIqokG7Pdv56w== X-Google-Smtp-Source: AGHT+IHmbq82GGxty29vT8Uza98u35Lktry3y1xJZcFthZ7iY977TvqFf+tzaHDmXSDUdlpUsvzgA+97d1MfYXo= X-Received: from wmsp38.prod.google.com ([2002:a05:600c:1da6:b0:43c:ef7b:ffac]) (user=aliceryhl job=prod-delivery.src-stubby-dispatcher) by 2002:adf:8c09:0:b0:391:3915:cfea with SMTP id ffacd0b85a97d-3913915d3c9mr8648946f8f.38.1741703162695; Tue, 11 Mar 2025 07:26:02 -0700 (PDT) Date: Tue, 11 Mar 2025 14:25:13 +0000 In-Reply-To: <20250311-iov-iter-v1-0-f6c9134ea824@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20250311-iov-iter-v1-0-f6c9134ea824@google.com> X-Developer-Key: i=aliceryhl@google.com; a=openpgp; fpr=49F6C1FAA74960F43A5B86A1EE7A392FDE96209F X-Developer-Signature: v=1; a=openpgp-sha256; l=6910; i=aliceryhl@google.com; h=from:subject:message-id; bh=YLDJfnUbMN1PwSSNtSoEcVZjewJZ9nhxstVqcUUfZU4=; b=owEBbQKS/ZANAwAKAQRYvu5YxjlGAcsmYgBn0Efy8S2nLnvPlcyMYs0sRA9jDZb3mq3JHX0HW rjIbWRaB4mJAjMEAAEKAB0WIQSDkqKUTWQHCvFIvbIEWL7uWMY5RgUCZ9BH8gAKCRAEWL7uWMY5 RnlhEAC5oIsPkR6N6esg79N9/AScNuI3L0Qv59iOW4Jf7SxCmlMv/eWg1QNmZIHh9M0W+4UhRza GhwckskXL3mUJAmVCqdBT79xRNpRoqOZ+W2S4eUfLdUMnnT0srNcbzgwFt4Q8dWnLjp+Q3116NW m9Ux+vB9p2fNUi5ru+t32WlZ5zs9Prg74WtC23Le+6ombUpJf51M9iB4vNBjodRQjmn1v3UqAP9 M0jD10jA7bSoeBYPsiq8LsGB7mFAnYwwtrMclmU47XM/1R/Vn9ijrc/TjfDANwuvKnliO50YTBN JyVRj8dlHuRQrfZk9uoTzluIEms8QbRrjQMJcxUUOHzU1C3XyutFet48mbyeSL9FEyBwFXyPTq1 UAOSoeqitvD9UgfckOwItxEavPOhT70xfUQ85U2+kOWg/K6VJ0XczoAALU6QvJatAf1Qfh2ZyaV Cy+e5VanSqaV1svTKNiYptP7H24d4J/AtPXhSAbR5vqF4ellPVXlhNNE4RsRQ8eZTHvDAj0YJ72 l/LOCiwykl+7gRpfi9KvIhkiJZGtlYmD1An/SXHKhuNGL6uD1TvozyQKsf6cYYngTBJmFAbP1za eojmMsE2hBwfvL7ooVmLGT3vwfC1aViJ29hoiIVg2Jx+gpmWgiRlnSuou8WHrM8MoMCh29QK56L ht8Mwtcs6s+3lbw== X-Mailer: b4 0.14.2 Message-ID: <20250311-iov-iter-v1-2-f6c9134ea824@google.com> Subject: [PATCH 2/5] rust: iov: add iov_iter abstractions for ITER_DEST From: Alice Ryhl To: Greg Kroah-Hartman , Alexander Viro , Arnd Bergmann , Miguel Ojeda Cc: Boqun Feng , Gary Guo , "=?utf-8?q?Bj=C3=B6rn_Roy_Baron?=" , Benno Lossin , Andreas Hindborg , Trevor Gross , Danilo Krummrich , Matthew Maurer , Lee Jones , linux-kernel@vger.kernel.org, rust-for-linux@vger.kernel.org, Alice Ryhl Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable This adds abstractions for the iov_iter type in the case where data_source is ITER_DEST. This will make Rust implementations of fops->read_iter possible. This series only has support for using existing IO vectors created by C code. Additional abstractions will be needed to support the creation of IO vectors in Rust code. These abstractions make the assumption that `struct iov_iter` does not have internal self-references, which implies that it is valid to move it between different local variables, and that you can make a copy of it to get two IO vectors into the same buffers. Signed-off-by: Alice Ryhl --- rust/kernel/iov.rs | 140 +++++++++++++++++++++++++++++++++++++++++++++++++= +++- 1 file changed, 139 insertions(+), 1 deletion(-) diff --git a/rust/kernel/iov.rs b/rust/kernel/iov.rs index 4498f65e1f65bd964909810c020db3a9f8fae389..dc32c27c5c76d059562fd7c6b9d= 4b178a8ea7c81 100644 --- a/rust/kernel/iov.rs +++ b/rust/kernel/iov.rs @@ -7,7 +7,12 @@ //! C headers: [`include/linux/iov_iter.h`](srctree/include/linux/iov_iter= .h), //! [`include/linux/uio.h`](srctree/include/linux/uio.h) =20 -use crate::{bindings, prelude::*, types::Opaque}; +use crate::{ + alloc::{Allocator, Flags}, + bindings, + prelude::*, + types::Opaque, +}; use core::{marker::PhantomData, mem::MaybeUninit, slice}; =20 const ITER_SOURCE: bool =3D bindings::ITER_SOURCE !=3D 0; @@ -168,3 +173,136 @@ fn clone(&self) -> IovIterSource<'data> { unsafe { core::ptr::read(self) } } } + +/// An IO vector that acts as a destination for data. +/// +/// # Invariants +/// +/// Must hold a valid `struct iov_iter` with `data_source` set to `ITER_DE= ST`. The buffers +/// referenced by the IO vector must be valid for writing for the duration= of `'data`. +/// +/// Note that if the IO vector is backed by a userspace pointer, it is alw= ays considered valid for +/// writing. +#[repr(transparent)] +pub struct IovIterDest<'data> { + iov: Opaque, + /// Represent to the type system that this value contains a pointer to= writable data it does + /// not own. + _source: PhantomData<&'data mut [u8]>, +} + +// SAFETY: This struct is essentially just a fancy `std::io::Cursor<&mut [= u8]>`, and that type is +// safe to send across thread boundaries. +unsafe impl<'data> Send for IovIterDest<'data> {} +// SAFETY: This struct is essentially just a fancy `std::io::Cursor<&mut [= u8]>`, and that type is +// safe to share across thread boundaries. +unsafe impl<'data> Sync for IovIterDest<'data> {} + +impl<'data> IovIterDest<'data> { + /// Obtain an `IovIterDest` from a raw pointer. + /// + /// # Safety + /// + /// * For the duration of `'iov`, the `struct iov_iter` must remain va= lid and must not be + /// accessed except through the returned reference. + /// * For the duration of `'data`, the buffers backing this IO vector = must be valid for + /// writing. + #[track_caller] + #[inline] + pub unsafe fn from_raw<'iov>(ptr: *mut bindings::iov_iter) -> &'iov mu= t IovIterDest<'data> { + // SAFETY: The caller ensures that `ptr` is valid. + let data_source =3D unsafe { (*ptr).data_source }; + assert_eq!(data_source, ITER_DEST); + + // SAFETY: The caller ensures the struct invariants for the right = durations. + unsafe { &mut *ptr.cast::>() } + } + + /// Access this as a raw `struct iov_iter`. + #[inline] + pub fn as_raw(&mut self) -> *mut bindings::iov_iter { + self.iov.get() + } + + /// Returns the number of bytes available in this IO vector. + /// + /// Note that this may overestimate the number of bytes. For example, = reading from userspace + /// memory could fail with EFAULT, which will be treated as the end of= the IO vector. + #[inline] + pub fn len(&self) -> usize { + // SAFETY: It is safe to access the `count` field. + unsafe { + (*self.iov.get()) + .__bindgen_anon_1 + .__bindgen_anon_1 + .as_ref() + .count + } + } + + /// Returns whether there are any bytes left in this IO vector. + /// + /// This may return `true` even if there are no more bytes available. = For example, reading from + /// userspace memory could fail with EFAULT, which will be treated as = the end of the IO vector. + #[inline] + pub fn is_empty(&self) -> bool { + self.len() =3D=3D 0 + } + + /// Advance this IO vector by `bytes` bytes. + /// + /// If `bytes` is larger than the size of this IO vector, it is advanc= ed to the end. + #[inline] + pub fn advance(&mut self, bytes: usize) { + // SAFETY: `self.iov` is a valid IO vector. + unsafe { bindings::iov_iter_advance(self.as_raw(), bytes) }; + } + + /// Advance this IO vector backwards by `bytes` bytes. + /// + /// # Safety + /// + /// The IO vector must not be reverted to before its beginning. + #[inline] + pub unsafe fn revert(&mut self, bytes: usize) { + // SAFETY: `self.iov` is a valid IO vector, and `bytes` is in boun= ds. + unsafe { bindings::iov_iter_revert(self.as_raw(), bytes) }; + } + + /// Write data to this IO vector. + /// + /// Returns the number of bytes that were written. If this is shorter = than the provided slice, + /// then no more bytes can be written. + #[inline] + pub fn copy_to_iter(&mut self, input: &[u8]) -> usize { + // SAFETY: `input` is valid for `input.len()` bytes. + unsafe { bindings::_copy_to_iter(input.as_ptr().cast(), input.len(= ), self.as_raw()) } + } + + /// Utility for implementing `read_iter` given the full contents of th= e file. + /// + /// The full contents of the file being read from is represented by `c= ontents`. This call will + /// write the appropriate sub-slice of `contents` and update the file = position in `ppos` so + /// that the file will appear to contain `contents` even if takes mult= iple reads to read the + /// entire file. + #[inline] + pub fn simple_read_from_buffer(&mut self, ppos: &mut i64, contents: &[= u8]) -> Result { + if *ppos < 0 { + return Err(EINVAL); + } + let Ok(pos) =3D usize::try_from(*ppos) else { + return Ok(0); + }; + if pos >=3D contents.len() { + return Ok(0); + } + + // BOUNDS: We just checked that `pos < contents.len()` above. + let num_written =3D self.copy_to_iter(&contents[pos..]); + + // OVERFLOW: pos+num_written <=3D contents.len() <=3D isize::MAX <= =3D i64::MAX + *ppos =3D (pos + num_written) as i64; + + Ok(num_written) + } +} --=20 2.49.0.rc0.332.g42c0ae87b1-goog From nobody Sun Feb 8 18:16:49 2026 Received: from mail-wm1-f73.google.com (mail-wm1-f73.google.com [209.85.128.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7249425D553 for ; Tue, 11 Mar 2025 14:26:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741703168; cv=none; b=mgu9myB6pcd8it7MJ/XRh9aWDCJybXvrQkj+HyvtDR30zXv6X9N4hMLpFcutcJ+a5aLoEAk/WCnC4vCG8+foqO+ZSeEofy/4tr3xzv7aHzYqn6BVYmbIhNr3J1V0zy7nkEpqEZFNNsUO9WPYoPVWsibVvp5nutwLZV9PSDV0NJ0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741703168; c=relaxed/simple; bh=B/1td+VMQnZgliO2HAl2eR0VoV3jv+kTGfbUL+xc5zM=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=VGQbBJcXXpz57kNtoe/D2WbWkbWk+9u5T2yp14p/2bRd5KrzRk2Fosb4CNxhLEzi1bALUWUybqQ9EwzUEbO3vF3SZdCzNuu/vSuD4JBi+90Af7EENEbF13yuszf2DjbaVGa/5yXlpxwydW1bkJvSzMzMfGDYMQdVLTd1g0+tLoM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--aliceryhl.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=yst4CGoR; arc=none smtp.client-ip=209.85.128.73 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--aliceryhl.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="yst4CGoR" Received: by mail-wm1-f73.google.com with SMTP id 5b1f17b1804b1-438da39bb69so39341715e9.0 for ; Tue, 11 Mar 2025 07:26:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1741703165; x=1742307965; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=Wwl/IIHNARpgtRdEA9ewvhA5D9UXMrvwaaXp7LgTuiM=; b=yst4CGoR8XHMYCP7ByTARcMQAcsaxo11jJ97dbq15vl2OMj5FPJ1jVPQO3WjrsxLvX bb0Dd/k0VRRJEq5+3YaB6G2cGMruYo1QZUIcDrO8RvUPuZD8BnhU2uzFU86mc+l6Zq/A Tv8Nw9S98YiB3N33OkGM0OxZY6MwnNEzJL5iCsAwey4vRkNPzyB1Qf9Wjm7BjVSk0flj DQx1fyCt6XM8K6QUxkxvBuX4KCBTyvW74gF3tO3hxTFG73QUPHCJL3OOwWQcwoPFkjG/ cULwcuxxwJ5yV4wBK0yhGo/tNjIvQi7BsTlRgGhnqGEbgv6ZYvyFHOkLyulkt3DV+9HC AMUQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741703165; x=1742307965; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=Wwl/IIHNARpgtRdEA9ewvhA5D9UXMrvwaaXp7LgTuiM=; b=MgHLabtHTINW0HqJhqBk+JKOg3XvaB5BrGO7tZapcjnLFKya+nwwWqP+BfUZYggqDZ hm5h4TFblhXbJbeW95XsbCMt6AwXy5iAhaQKJ+/mhNWixkF66a6HJbdUzjkfBafLOCqr NCgYgvExx8UagVx4CYbRv2eIOTOcVU+SFHeLJLr7RCf4QXhjcx9STKtywgb+W/qmq8iU u3xcRaXNM8ghhQM6N3l9RjXI4kpY/xJ9/r8zsnu2t5/U3NXdHAO3Bp2adBe7qRXkDw+H 8SiZ9rH4S1+16f4WDSWZQ/UL4hO9TYb5XpFgzQmvLOk0cGTaJZfrBqSW9ixaKE+tVBeh wSuw== X-Forwarded-Encrypted: i=1; AJvYcCXUIiAJcxtpE8QPXA9aNUpepjIw2Aw7MHKesiaDk948zlTD9vAnBNpjN35oGcbTOzR2L0Z1mWudTPwW/F0=@vger.kernel.org X-Gm-Message-State: AOJu0YxiYhtHV8fVfyIYnNJkrXBLXh9GoieBtWuc2H7oJN84bsWL/itr CzDlfhT1BPPog2mtf3FvCjLUw3l6+8acxMjaGPusjgVJhxXYs9DZ5JFEjP6oKuMYreRc9Ohv76W iB8GPZaZd8PtpyQ== X-Google-Smtp-Source: AGHT+IHCHhtxEBMSk0zFJLJD1sCTwgXRkSzAoBtKJTTegGaH3YiBtG4mxjikWvm6uQn8V/KfJtSQzL2THiZAPOc= X-Received: from wmbg7.prod.google.com ([2002:a05:600c:a407:b0:43c:fad4:7595]) (user=aliceryhl job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:3ba1:b0:43c:fbbf:7bf1 with SMTP id 5b1f17b1804b1-43cfbbf7eb2mr82199255e9.30.1741703164884; Tue, 11 Mar 2025 07:26:04 -0700 (PDT) Date: Tue, 11 Mar 2025 14:25:14 +0000 In-Reply-To: <20250311-iov-iter-v1-0-f6c9134ea824@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20250311-iov-iter-v1-0-f6c9134ea824@google.com> X-Developer-Key: i=aliceryhl@google.com; a=openpgp; fpr=49F6C1FAA74960F43A5B86A1EE7A392FDE96209F X-Developer-Signature: v=1; a=openpgp-sha256; l=5629; i=aliceryhl@google.com; h=from:subject:message-id; bh=B/1td+VMQnZgliO2HAl2eR0VoV3jv+kTGfbUL+xc5zM=; b=owEBbQKS/ZANAwAKAQRYvu5YxjlGAcsmYgBn0EfycPAW1Ciir54AsE9E4XhJSOknSTnJQt/Ay rDG09KbMpyJAjMEAAEKAB0WIQSDkqKUTWQHCvFIvbIEWL7uWMY5RgUCZ9BH8gAKCRAEWL7uWMY5 RmUzD/9iB799ragOz+5kMIbj3Cw6MOII1qea5vqLoUyvv3RqSfsHmR4XYvMlZe18Bq3w1M+4SPr ZV4+ncb+6BLbjxkrqddt4OT6/0TZZYF7Q3c0HBv1xI5Ypw+N19+sp56l8hjGvZB905QYMK4k57z It7HAGPZ1zHW0RjgeGPrRYpV287ylzZMY25PzMOYz0ORh1WT8P9O3qGLWUcCYZpLmBJ5MrDmrv6 M++r1t6RAO6nvhtsBiylfCIzvB/4zys9xvGEKHJTbQuR/BWCb7qWgXDvTbwnOjd8GoK3oEJ5ALL JJdb7sHLQwGWmx6rzZ8tR92piqlwXEhDaDX/42dVqjrQX5+KtPfsEQABt8e0k3BYOjrLg2Kr/PS XJsvaae+SNYUB1US/Y9hg/cQ97jv9Notv4QJfulvsg+Q3SEuV1As/XQnut11E9ScomX7kLsmT0W aAK6BEA50S5w+kWCSAqwuD30Re2xtXAKYWgs2t4uq3oDKCbbF2bf+bNHt/Wk5U/Jw+P+aJ3YdCO Ws6wprfkkj7LccwDFrOWLuHRcYRqEQL99ILL6CuVA1avU4B6bIUU3Y0PtXTWTRKzWB3ZFA2GIKi hA3D+nevB+ja/cOnQAThmxu1b2/sRQria7nbTVuvz1S3ae9zdZ2YKo8pMXa3uKSHuf8k/Uk3Usa s0awEpUeZoXVQBg== X-Mailer: b4 0.14.2 Message-ID: <20250311-iov-iter-v1-3-f6c9134ea824@google.com> Subject: [PATCH 3/5] rust: miscdevice: Provide additional abstractions for iov_iter and kiocb structures From: Alice Ryhl To: Greg Kroah-Hartman , Alexander Viro , Arnd Bergmann , Miguel Ojeda Cc: Boqun Feng , Gary Guo , "=?utf-8?q?Bj=C3=B6rn_Roy_Baron?=" , Benno Lossin , Andreas Hindborg , Trevor Gross , Danilo Krummrich , Matthew Maurer , Lee Jones , linux-kernel@vger.kernel.org, rust-for-linux@vger.kernel.org, Alice Ryhl Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable These will be used for the read_iter() and write_iter() callbacks, which are now the preferred back-ends for when a user operates on a char device with read() and write() respectively. Co-developed-by: Lee Jones Signed-off-by: Lee Jones Signed-off-by: Alice Ryhl --- rust/kernel/miscdevice.rs | 97 +++++++++++++++++++++++++++++++++++++++++++= +++- 1 file changed, 96 insertions(+), 1 deletion(-) diff --git a/rust/kernel/miscdevice.rs b/rust/kernel/miscdevice.rs index fa9ecc42602a477328a25b5d357db90b59dc72ae..8daafdc7f3e47aef3c90507082d= 35ad6819598eb 100644 --- a/rust/kernel/miscdevice.rs +++ b/rust/kernel/miscdevice.rs @@ -14,12 +14,13 @@ error::{to_result, Error, Result, VTABLE_DEFAULT_ERROR}, ffi::{c_int, c_long, c_uint, c_ulong}, fs::File, + iov::{IovIterDest, IovIterSource}, prelude::*, seq_file::SeqFile, str::CStr, types::{ForeignOwnable, Opaque}, }; -use core::{marker::PhantomData, mem::MaybeUninit, pin::Pin}; +use core::{marker::PhantomData, mem::MaybeUninit, pin::Pin, ptr::NonNull}; =20 /// Options for creating a misc device. #[derive(Copy, Clone)] @@ -119,6 +120,16 @@ fn release(device: Self::Ptr, _file: &File) { drop(device); } =20 + /// Read from this miscdevice. + fn read_iter(_kiocb: Kiocb<'_, Self::Ptr>, _iov: &mut IovIterDest<'_>)= -> Result { + build_error!(VTABLE_DEFAULT_ERROR) + } + + /// Write to this miscdevice. + fn write_iter(_kiocb: Kiocb<'_, Self::Ptr>, _iov: &mut IovIterSource<'= _>) -> Result { + build_error!(VTABLE_DEFAULT_ERROR) + } + /// Handler for ioctls. /// /// The `cmd` argument is usually manipulated using the utilties in [`= kernel::ioctl`]. @@ -160,6 +171,36 @@ fn show_fdinfo( } } =20 +/// Wrapper for the kernel's `struct kiocb`. +/// +/// The type `T` represents the private data of the file. +pub struct Kiocb<'a, T> { + inner: NonNull, + _phantom: PhantomData<&'a T>, +} + +impl<'a, T: ForeignOwnable> Kiocb<'a, T> { + /// Get the private data in this kiocb. + pub fn private_data(&self) -> ::Borrowed<'a> { + // SAFETY: The `kiocb` lets us access the private data. + let private =3D unsafe { (*(*self.inner.as_ptr()).ki_filp).private= _data }; + // SAFETY: The kiocb has shared access to the private data. + unsafe { ::borrow(private) } + } + + /// Gets the current value of `ki_pos`. + pub fn ki_pos(&self) -> i64 { + // SAFETY: The `kiocb` can access `ki_pos`. + unsafe { (*self.inner.as_ptr()).ki_pos } + } + + /// Gets a mutable reference to the `ki_pos` field. + pub fn ki_pos_mut(&mut self) -> &mut i64 { + // SAFETY: The `kiocb` can access `ki_pos`. + unsafe { &mut (*self.inner.as_ptr()).ki_pos } + } +} + /// A vtable for the file operations of a Rust miscdevice. struct MiscdeviceVTable(PhantomData); =20 @@ -223,6 +264,50 @@ impl MiscdeviceVTable { 0 } =20 + /// # Safety + /// + /// `kiocb` must be correspond to a valid file that is associated with= a + /// `MiscDeviceRegistration`. `iter` must be a valid `struct iov_it= er` for writing. + unsafe extern "C" fn read_iter( + kiocb: *mut bindings::kiocb, + iter: *mut bindings::iov_iter, + ) -> isize { + let kiocb =3D Kiocb { + // SAFETY: The read_iter call of a file is given a kiocb for t= hat file. + inner: unsafe { NonNull::new_unchecked(kiocb) }, + _phantom: PhantomData, + }; + // SAFETY: This is a valid `struct iov_iter` for writing. + let iov =3D unsafe { IovIterDest::from_raw(iter) }; + + match T::read_iter(kiocb, iov) { + Ok(res) =3D> res as isize, + Err(err) =3D> err.to_errno() as isize, + } + } + + /// # Safety + /// + /// `kiocb` must be correspond to a valid file that is associated with= a + /// `MiscDeviceRegistration`. `iter` must be a valid `struct iov_it= er` for writing. + unsafe extern "C" fn write_iter( + kiocb: *mut bindings::kiocb, + iter: *mut bindings::iov_iter, + ) -> isize { + let kiocb =3D Kiocb { + // SAFETY: The read_iter call of a file is given a kiocb for t= hat file. + inner: unsafe { NonNull::new_unchecked(kiocb) }, + _phantom: PhantomData, + }; + // SAFETY: This is a valid `struct iov_iter` for reading. + let iov =3D unsafe { IovIterSource::from_raw(iter) }; + + match T::write_iter(kiocb, iov) { + Ok(res) =3D> res as isize, + Err(err) =3D> err.to_errno() as isize, + } + } + /// # Safety /// /// `file` must be a valid file that is associated with a `MiscDeviceR= egistration`. @@ -291,6 +376,16 @@ impl MiscdeviceVTable { const VTABLE: bindings::file_operations =3D bindings::file_operations { open: Some(Self::open), release: Some(Self::release), + read_iter: if T::HAS_READ_ITER { + Some(Self::read_iter) + } else { + None + }, + write_iter: if T::HAS_WRITE_ITER { + Some(Self::write_iter) + } else { + None + }, unlocked_ioctl: if T::HAS_IOCTL { Some(Self::ioctl) } else { --=20 2.49.0.rc0.332.g42c0ae87b1-goog From nobody Sun Feb 8 18:16:49 2026 Received: from mail-wm1-f73.google.com (mail-wm1-f73.google.com [209.85.128.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AE32725D908 for ; Tue, 11 Mar 2025 14:26:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741703170; cv=none; b=ba858Fx8bmmH05VcwavFGTyaDN6MAj8PDnZ3dcB9LeWjHALRmLILM3ZCz1j3fHJ+Qh2rewtfVAG9TsAWP/7SXAJCJ9qdPDHzoM94gTbLPkWMs8Cn4SOj2liBTsbm28gwWqPMtBq6mDbeIh/cioVrAC+8dkgNPM5gqnWWpvRGlmQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741703170; c=relaxed/simple; bh=/hojUynEPo4FjkJuts+wIohS5BMSkgWw4Set5Rdyf+E=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=Gm5OCOtoHi4/uJWkTYAWmp5o5SgN8/ppgeOo0y+sWMQ5+GoPacPbWSUFE27UfCdcNnd+S2ml+/cNNQrD5P7Xf9FIFPQ29SGj1gRgpVIQWrI3RSozAgehDzk+oMU4heFwqS7kaqfagDvQLwscpuc4XGlPzyaz4LEesUrebhw8qm4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--aliceryhl.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=weOuFqrT; arc=none smtp.client-ip=209.85.128.73 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--aliceryhl.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="weOuFqrT" Received: by mail-wm1-f73.google.com with SMTP id 5b1f17b1804b1-43bc97e6360so27857135e9.3 for ; Tue, 11 Mar 2025 07:26:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1741703167; x=1742307967; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=JadJK9y1sKZ4Keav9JLStvrnzzXru9HhnZNlAQYAikA=; b=weOuFqrTeC34wXs6oA3qlX7q4qizf7Bx1l4K0bgz/mJJDQyVUEaqD0maRJT31Wq1yS YcETGv+3WQgnE00l8wWEfJN5Wwhx8tYilN42d8S5HRyu0gd7rFxFJqLctWglUTSYmoPq 0i3GkQ6wOGsouF3AMKOY/lJNmlMHBHn67vQmWzxHZnRBvg2W5/o/H7OdUnuvyHZxDESq 4mbBvHRj9o/EC/nmzeM0DLwQ7JedZeZhCE7fGm/qso++Yi3DbCCeoyfXqUmpMV7qnXq3 +5tTA7z6oPcSfyjnv0zd7DRDtu9VapdAfejUFNMrjx3nmKxBlun3WnFdeRuDtY0z4ui2 9jeA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741703167; x=1742307967; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=JadJK9y1sKZ4Keav9JLStvrnzzXru9HhnZNlAQYAikA=; b=DS7BJKFjLrZm8zqTn+Ly9nGjxhNv3hPiPYU3G4hWu8q/h/McsW4nXvldHGHiMlEziq QPivYce0b4Q6wiMnTR0C2i2QTdJ/HvPZXJLOLT+85APqI8gp0qwzoSBS7hNS25dJHEi/ 7vXVXbh2TVmQl7BDhI7EXpPOl4YFKGsmtXuQVgQpw+ho/IzM6nBJnUghYaGC189XiWb2 EiTvm0LjO5kFrVT8/jckYfKOr3I9d93GUMjy1cQzOQH/Py7dDbPdPgmK3dG/SRoeRYNq NbKttCXq7Tat1BMvk0WNroc6L6VizJAokDaiyoakolEssgyalgk8sNIMDbBJSAOjZFhM iovw== X-Forwarded-Encrypted: i=1; AJvYcCWZXHZ7qEy0WG/BaqJGM/BiuusVyKMjuxY5qu0WjkYkslu2UJgIxx6gujGegZZpJCzSPk5zmQggExcYlE0=@vger.kernel.org X-Gm-Message-State: AOJu0YxNcnD06MkcTTVUOl3gW9H2frdGpPfeqs9mQaVvtgBjPwcH5yRu x/sTZoUy/sSeBXoW5AOmqZFKDUXhpy8zvlAr8vvznpW8R/aJQVHqKaMk/5yMMerA6mR4MkNmmtT 7sPBLXO0dXOxKwg== X-Google-Smtp-Source: AGHT+IEFdrFYuu+2Cx2wC79RGudaUW6+8mAmayjW6nCjBT5GMW6ijX527iMMMKlgRA6YRV2vSayTGsD9nLZ7ls8= X-Received: from wmbg5.prod.google.com ([2002:a05:600c:a405:b0:43b:c967:2f53]) (user=aliceryhl job=prod-delivery.src-stubby-dispatcher) by 2002:a7b:cc88:0:b0:43c:f75a:eb38 with SMTP id 5b1f17b1804b1-43cf75aed80mr86147505e9.2.1741703167192; Tue, 11 Mar 2025 07:26:07 -0700 (PDT) Date: Tue, 11 Mar 2025 14:25:15 +0000 In-Reply-To: <20250311-iov-iter-v1-0-f6c9134ea824@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20250311-iov-iter-v1-0-f6c9134ea824@google.com> X-Developer-Key: i=aliceryhl@google.com; a=openpgp; fpr=49F6C1FAA74960F43A5B86A1EE7A392FDE96209F X-Developer-Signature: v=1; a=openpgp-sha256; l=1605; i=aliceryhl@google.com; h=from:subject:message-id; bh=/hojUynEPo4FjkJuts+wIohS5BMSkgWw4Set5Rdyf+E=; b=owEBbQKS/ZANAwAKAQRYvu5YxjlGAcsmYgBn0EfzNLsGvU0BxvVQd1R1R0pNczpN3OAh70ew/ FlfpBkguBiJAjMEAAEKAB0WIQSDkqKUTWQHCvFIvbIEWL7uWMY5RgUCZ9BH8wAKCRAEWL7uWMY5 RhHtEACTIxhdK0JRLjf9ZkXGGZKEQowA1mOYI7Lhx5Nf1GkE0CIsnU13Dif9X1Kt0I91ihBH6rf lJYj/QbzWpcH0BTfVxG7bFBAL29tgLS38EjpInkzI9hvHc8+5PyLEpI+DGp6vbKr/sgaDiy5RQ3 UWJdY9iNAqrFMckgEJHKnyNZ1ZJjuqBoAo0ivgAsmUxpsxwliEd/aUoE9YQjzhBYYYDtUu3cn9N AAp2bDka8NuMF0wA8rqrymj3XngX+57jAWkjGPQZk3XHjYIpUWzXxX85nvgAcrXn6+MQKeWffI3 aa/wKbWYKL+JwSe5rRg97aRE864RXK8H6taL0CjIsjcePVa/fqOxlzFeSrKjfNhtgQSWnL9Kcfw fQwdoWdxCXyOqwUWWm5znFkOKTzJmq5i/EkBb7uJrPyiIEH77dGP3YLc6HLQ9EqdHVfjBSc8jkc 10ctJ5wvbzxs7vhJhOvas0tDcg1wWKZngr2i5kgY/sqag8+1rZSlUD6+RHRyKECqY/SjrAsVbnd /5PCH2hdwZDLGNEb5ORgZfoeKrty7xZ6zpBjU5AtNKTxzZML6l3R+pP6G8qoMyXH+eEbEqopb51 H/VCCqpccNu6eRxvvSC2ESDORMWKAM3QEEQG2/VTjq5Mp9qnbZtwk4HECyN/YiJzbXwQZYYMHlT r3s2J3t4PtKGQ8g== X-Mailer: b4 0.14.2 Message-ID: <20250311-iov-iter-v1-4-f6c9134ea824@google.com> Subject: [PATCH 4/5] rust: alloc: add Vec::clear From: Alice Ryhl To: Greg Kroah-Hartman , Alexander Viro , Arnd Bergmann , Miguel Ojeda Cc: Boqun Feng , Gary Guo , "=?utf-8?q?Bj=C3=B6rn_Roy_Baron?=" , Benno Lossin , Andreas Hindborg , Trevor Gross , Danilo Krummrich , Matthew Maurer , Lee Jones , linux-kernel@vger.kernel.org, rust-for-linux@vger.kernel.org, Alice Ryhl Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Our custom Vec type is missing the stdlib method `clear`, thus add it. It will be used in the miscdevice sample. Signed-off-by: Alice Ryhl Reviewed-by: Andreas Hindborg --- rust/kernel/alloc/kvec.rs | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/rust/kernel/alloc/kvec.rs b/rust/kernel/alloc/kvec.rs index ae9d072741cedbb34bed0be0c20cc75472aa53be..2d213ede2873cef87116a5527e8= e24008c970a58 100644 --- a/rust/kernel/alloc/kvec.rs +++ b/rust/kernel/alloc/kvec.rs @@ -395,6 +395,33 @@ pub fn into_raw_parts(self) -> (*mut T, usize, usize) { (ptr, len, capacity) } =20 + /// Clears the vector, removing all values. + /// + /// Note that this method has no effect on the allocated capacity + /// of the vector. + /// + /// # Examples + /// + /// ``` + /// let mut v =3D kernel::kvec![1, 2, 3]?; + /// + /// v.clear(); + /// + /// assert!(v.is_empty()); + /// # Ok::<(), Error>(()) + /// ``` + #[inline] + pub fn clear(&mut self) { + let elems: *mut [T] =3D self.as_mut_slice(); + + // INVARIANT: This call changes the number of elements to zero. + self.len =3D 0; + + // SAFETY: The values being dropped are valid values of type `T` b= y the type invariants. + // It's okay to invalidate them as we just changed the length to z= ero. + unsafe { ptr::drop_in_place(elems) }; + } + /// Ensures that the capacity exceeds the length by at least `addition= al` elements. /// /// # Examples --=20 2.49.0.rc0.332.g42c0ae87b1-goog From nobody Sun Feb 8 18:16:49 2026 Received: from mail-wm1-f74.google.com (mail-wm1-f74.google.com [209.85.128.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AF5A525DAEB for ; Tue, 11 Mar 2025 14:26:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.74 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741703172; cv=none; b=NVXM+ToWSmiNXKUnPRKt7drB7NJfkdCck3ote8BuC9j3HQcL3T6Uacl80XIxJgnUz1NQ3AkkHKmbVcH/1OY1eGxjh/TvywX6MUcttw2jUvpdUM9gSF/9LJFGsfBrRUfs/GBj1nRajvsKjApi44IDCcLLIJppouxJ1t198MEJ/JM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741703172; c=relaxed/simple; bh=XKU9cRKvgp0kixzFl7aIj/zQ08YPYBtJF12+lpAONHA=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=t3r08L2k7gu2BOMOH/kCsTivnJJxp2xe1zo9C621UVz/K2eNHI9ymnsQ1RbkGxIaPq1LQiWoXNUqSMSPTexlqlh4HKsAxWiWrBzhCDfynw3p8AQw8KZLeCe+5OJ1fcidtPyPGq1NSHCOtBjDNgGVjxOMQqYa1MCmbR6Hh15JTKQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--aliceryhl.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=4f6FNPus; arc=none smtp.client-ip=209.85.128.74 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--aliceryhl.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="4f6FNPus" Received: by mail-wm1-f74.google.com with SMTP id 5b1f17b1804b1-43ab5baf62cso38607715e9.0 for ; Tue, 11 Mar 2025 07:26:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1741703169; x=1742307969; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=DQkOm0HuLjqgJ/hyLLb+0wyoHUwdib0o04dd3QzbZVE=; b=4f6FNPusmUKksfcApkEJM5V/VifHAifeFXamG8VD5ereZTP2WafqRHGzTXAljwA873 TjoVpkxojd6iXoXcm1O4bxse3p37aeJ9PqpeOXjpQDU74ZiDamEn5lITUZAQFB0YKb+h IJoAAaWs0F/pItdji0bgnjwphkNmwND3eLgCQm//pKW5YW8B58I8YQyfUX35o2hXMBq0 gBOT7mr0bNPDgojXwjqLY4zRe9/rsR2BCK6BDqxvA80sDnVok+AIpbPp4fTRpvXil5Vv 1gkTd8PkYG4X6cnU4cw0mZPPZzmCR2cEwOPJ4o8Xpofi17Oe9kRAZ21NUABZklP3ej5M HsOg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741703169; x=1742307969; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=DQkOm0HuLjqgJ/hyLLb+0wyoHUwdib0o04dd3QzbZVE=; b=JHc5V7sga+wOZDEhA3AoOyjLWK2fH6NY6YLHDnjW9Z378SkTU/L2lFvoJ2koQLToQF TntvMnUml5NbfhMHPluc+cUBWHbNqo8QLYpGZGMJtCJjoygwxvTVxmh/KEps3Msb+9q/ aGpntnBMw0E5cesl2gsJxyFf2jG6leIhDUh8bP3XeZ+hA0dqvaU2TObn5NKTpqmZm0z7 8BDq8k4DjTSesAzGsi1ibv7ZnpYCdtdyb8nZodMa0yC9yXIhR3zXkz0hFDO/PMIOF9xP J6SNd+gjt44HhdPiW7sb3nS2+UvtQzhBJRo61zVCapJcBYaCPSzC7l8a4AqbeFaaHlXU XHWQ== X-Forwarded-Encrypted: i=1; AJvYcCUmzGRIcHJ9OUP6i5xOtRe4stOc+lATm8ek4Sn45cm4611Kt3Gb8WJjOtBaATkZFcwLrH2nvWOeg/vg3os=@vger.kernel.org X-Gm-Message-State: AOJu0YzokiKYf0uK6BfGF2DVzGPLuJj8H+fLbCvvVzLxQqgWMIGrU2yS W2ZR35DPA3r7QKuqtMK3D4hRuJnCF+vH9esuV5kUD6j0ECf6tZKt5s7zN9u+CVtmHqZewTb90av mpRrUDYXTv8acKQ== X-Google-Smtp-Source: AGHT+IEKcctCw7ZE8Dhz7OmLcHjMnkf+lSBoaUGhJ5HarQK2WExcbUIVOji5s7/eIioXjPE5fNGcYR4TJw8MjYw= X-Received: from wmbeq13.prod.google.com ([2002:a05:600c:848d:b0:43c:eb09:3790]) (user=aliceryhl job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:45d1:b0:439:6118:c188 with SMTP id 5b1f17b1804b1-43c5a62a276mr121343725e9.19.1741703169365; Tue, 11 Mar 2025 07:26:09 -0700 (PDT) Date: Tue, 11 Mar 2025 14:25:16 +0000 In-Reply-To: <20250311-iov-iter-v1-0-f6c9134ea824@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20250311-iov-iter-v1-0-f6c9134ea824@google.com> X-Developer-Key: i=aliceryhl@google.com; a=openpgp; fpr=49F6C1FAA74960F43A5B86A1EE7A392FDE96209F X-Developer-Signature: v=1; a=openpgp-sha256; l=3169; i=aliceryhl@google.com; h=from:subject:message-id; bh=njR+x/nscsCHeUCgj3YO2aDLhcwxUN+kX/SqnNjxafY=; b=owEBbQKS/ZANAwAKAQRYvu5YxjlGAcsmYgBn0Ef0QAFWkXYX3kchm9jUoi8bW0gXnTRM5w+9N ik63DSHu1qJAjMEAAEKAB0WIQSDkqKUTWQHCvFIvbIEWL7uWMY5RgUCZ9BH9AAKCRAEWL7uWMY5 RptKD/9PcaUl3LQFRl7WMAEGoq02tV5SSw12s5SdnBTHJOb9SR4peV7vPWrl0pNjX/ViKyTUuvG s0Wr8dNK+ufhYjhCIeE4YYPPLOjUVMvHBiLgr5kDY6N70SX5EUBsaLcYvm0wo0I8hi6UUzAZ+Nd g0tGzOrxETkPiRvEDVAOvQ8szLJ8szou4Xkcr+9WDn0bmtBlpgxzqw+HIhBZAvC3hY8TGsq32DI NLfY5XuQbuEErBJCyMj8TrgZQMSLbpEGmRF3lkwJfsX8ilxuWvqvSIjJG7vxfPLpd+1aGZYK+EM YyHy8/SAS/Q0Y26SfLdvcS8SB/veQxc83xwNhEs/uFPzS355E8Cv4U9OPK+jkSZm3Zwlhtj5cvP Q/BYVk/L6hD4KXT1cjalpO+pLeaTy3rWQ6sK0db4n0UI29UoM821M9ZZk67/FIp0hOulNbr2u2g ynJaG4MyIyXkjeiuXBhJfbMiCgTcQTSyjhS0mGmr9gWAybPHQK/lWhWRDiNzvkk8VMAnAR8eavf BwkryPISFR9W0uRT13z349A7ho7F1I6Lif4GdjQXUBlEyldBJOoRH7/rQ/SX48M503PRZShN6Hf vPHBKdU1Sea0+jf8v33Eyum5KoE+pfA3pK2+UE2F867ES3qQk7Sc9GGysYvZ+QE0Jef5NGwZ916 JykYp+2ruMMGwTA== X-Mailer: b4 0.14.2 Message-ID: <20250311-iov-iter-v1-5-f6c9134ea824@google.com> Subject: [PATCH 5/5] samples: rust_misc_device: Expand the sample to support read()ing from userspace From: Alice Ryhl To: Greg Kroah-Hartman , Alexander Viro , Arnd Bergmann , Miguel Ojeda Cc: Boqun Feng , Gary Guo , "=?utf-8?q?Bj=C3=B6rn_Roy_Baron?=" , Benno Lossin , Andreas Hindborg , Trevor Gross , Danilo Krummrich , Matthew Maurer , Lee Jones , linux-kernel@vger.kernel.org, rust-for-linux@vger.kernel.org, Alice Ryhl Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable From: Lee Jones A userland application can now operate on the char device with read() in order to consume a locally held buffer. Memory for the buffer is to be provisioned and the buffer populated in its subsequently provided write() counterpart. Signed-off-by: Lee Jones Co-developed-by: Alice Ryhl Signed-off-by: Alice Ryhl Reviewed-by: Andreas Hindborg --- samples/rust/rust_misc_device.rs | 37 +++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/samples/rust/rust_misc_device.rs b/samples/rust/rust_misc_devi= ce.rs index 40ad7266c2252e5c0b4e91e501ef9ada2eda3b16..6405713fc8ff69659799f307100= 74487ea3bb14e 100644 --- a/samples/rust/rust_misc_device.rs +++ b/samples/rust/rust_misc_device.rs @@ -101,7 +101,9 @@ device::Device, fs::File, ioctl::{_IO, _IOC_SIZE, _IOR, _IOW}, - miscdevice::{MiscDevice, MiscDeviceOptions, MiscDeviceRegistration}, + iov::{IovIterDest, IovIterSource}, + kvec, + miscdevice::{Kiocb, MiscDevice, MiscDeviceOptions, MiscDeviceRegistrat= ion}, new_mutex, prelude::*, sync::Mutex, @@ -143,6 +145,7 @@ fn init(_module: &'static ThisModule) -> impl PinInit { =20 struct Inner { value: i32, + buffer: KVec, } =20 #[pin_data(PinnedDrop)] @@ -164,7 +167,10 @@ fn open(_file: &File, misc: &MiscDeviceRegistration) -> Result) -> Result, iov: &mut IovIterDest<'_= >) -> Result { + let me =3D kiocb.private_data(); + dev_info!(me.dev, "Reading from Rust Misc Device Sample\n"); + + let inner =3D me.inner.lock(); + // Read the buffer contents, taking the file position into account. + let read =3D iov.simple_read_from_buffer(kiocb.ki_pos_mut(), &inne= r.buffer)?; + + Ok(read) + } + + fn write_iter(mut kiocb: Kiocb<'_, Self::Ptr>, iov: &mut IovIterSource= <'_>) -> Result { + let me =3D kiocb.private_data(); + dev_info!(me.dev, "Writing to Rust Misc Device Sample\n"); + + let mut inner =3D me.inner.lock(); + + // Replace buffer contents. + inner.buffer.clear(); + let len =3D iov.copy_from_iter_vec(&mut inner.buffer, GFP_KERNEL)?; + + // Set position to zero so that future `read` calls will see the n= ew contents. + *kiocb.ki_pos_mut() =3D 0; + + Ok(len) + } + fn ioctl(me: Pin<&RustMiscDevice>, _file: &File, cmd: u32, arg: usize)= -> Result { dev_info!(me.dev, "IOCTLing Rust Misc Device Sample\n"); =20 --=20 2.49.0.rc0.332.g42c0ae87b1-goog