Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at master 191 lines 5.3 kB view raw
1// SPDX-License-Identifier: GPL-2.0 2 3//! Rust configfs sample. 4 5use kernel::alloc::flags; 6use kernel::configfs; 7use kernel::configfs::configfs_attrs; 8use kernel::new_mutex; 9use kernel::page::PAGE_SIZE; 10use kernel::prelude::*; 11use kernel::sync::Mutex; 12 13module! { 14 type: RustConfigfs, 15 name: "rust_configfs", 16 authors: ["Rust for Linux Contributors"], 17 description: "Rust configfs sample", 18 license: "GPL", 19} 20 21#[pin_data] 22struct RustConfigfs { 23 #[pin] 24 config: configfs::Subsystem<Configuration>, 25} 26 27#[pin_data] 28struct Configuration { 29 message: &'static CStr, 30 #[pin] 31 bar: Mutex<(KBox<[u8; PAGE_SIZE]>, usize)>, 32} 33 34impl Configuration { 35 fn new() -> impl PinInit<Self, Error> { 36 try_pin_init!(Self { 37 message: c"Hello World\n", 38 bar <- new_mutex!((KBox::new([0; PAGE_SIZE], flags::GFP_KERNEL)?, 0)), 39 }) 40 } 41} 42 43impl kernel::InPlaceModule for RustConfigfs { 44 fn init(_module: &'static ThisModule) -> impl PinInit<Self, Error> { 45 pr_info!("Rust configfs sample (init)\n"); 46 47 // Define a subsystem with the data type `Configuration`, two 48 // attributes, `message` and `bar` and child group type `Child`. `mkdir` 49 // in the directory representing this subsystem will create directories 50 // backed by the `Child` type. 51 let item_type = configfs_attrs! { 52 container: configfs::Subsystem<Configuration>, 53 data: Configuration, 54 child: Child, 55 attributes: [ 56 message: 0, 57 bar: 1, 58 ], 59 }; 60 61 try_pin_init!(Self { 62 config <- configfs::Subsystem::new( 63 c"rust_configfs", item_type, Configuration::new() 64 ), 65 }) 66 } 67} 68 69#[vtable] 70impl configfs::GroupOperations for Configuration { 71 type Child = Child; 72 73 fn make_group(&self, name: &CStr) -> Result<impl PinInit<configfs::Group<Child>, Error>> { 74 // Define a group with data type `Child`, one attribute `baz` and child 75 // group type `GrandChild`. `mkdir` in the directory representing this 76 // group will create directories backed by the `GrandChild` type. 77 let tpe = configfs_attrs! { 78 container: configfs::Group<Child>, 79 data: Child, 80 child: GrandChild, 81 attributes: [ 82 baz: 0, 83 ], 84 }; 85 86 Ok(configfs::Group::new(name.try_into()?, tpe, Child::new())) 87 } 88} 89 90#[vtable] 91impl configfs::AttributeOperations<0> for Configuration { 92 type Data = Configuration; 93 94 fn show(container: &Configuration, page: &mut [u8; PAGE_SIZE]) -> Result<usize> { 95 pr_info!("Show message\n"); 96 let data = container.message.to_bytes(); 97 page[0..data.len()].copy_from_slice(data); 98 Ok(data.len()) 99 } 100} 101 102#[vtable] 103impl configfs::AttributeOperations<1> for Configuration { 104 type Data = Configuration; 105 106 fn show(container: &Configuration, page: &mut [u8; PAGE_SIZE]) -> Result<usize> { 107 pr_info!("Show bar\n"); 108 let guard = container.bar.lock(); 109 let data = guard.0.as_slice(); 110 let len = guard.1; 111 page[0..len].copy_from_slice(&data[0..len]); 112 Ok(len) 113 } 114 115 fn store(container: &Configuration, page: &[u8]) -> Result { 116 pr_info!("Store bar\n"); 117 let mut guard = container.bar.lock(); 118 guard.0[0..page.len()].copy_from_slice(page); 119 guard.1 = page.len(); 120 Ok(()) 121 } 122} 123 124// `pin_data` cannot handle structs without braces. 125#[pin_data] 126struct Child {} 127 128impl Child { 129 fn new() -> impl PinInit<Self, Error> { 130 try_pin_init!(Self {}) 131 } 132} 133 134#[vtable] 135impl configfs::GroupOperations for Child { 136 type Child = GrandChild; 137 138 fn make_group(&self, name: &CStr) -> Result<impl PinInit<configfs::Group<GrandChild>, Error>> { 139 // Define a group with data type `GrandChild`, one attribute `gc`. As no 140 // child type is specified, it will not be possible to create subgroups 141 // in this group, and `mkdir`in the directory representing this group 142 // will return an error. 143 let tpe = configfs_attrs! { 144 container: configfs::Group<GrandChild>, 145 data: GrandChild, 146 attributes: [ 147 gc: 0, 148 ], 149 }; 150 151 Ok(configfs::Group::new( 152 name.try_into()?, 153 tpe, 154 GrandChild::new(), 155 )) 156 } 157} 158 159#[vtable] 160impl configfs::AttributeOperations<0> for Child { 161 type Data = Child; 162 163 fn show(_container: &Child, page: &mut [u8; PAGE_SIZE]) -> Result<usize> { 164 pr_info!("Show baz\n"); 165 let data = c"Hello Baz\n".to_bytes(); 166 page[0..data.len()].copy_from_slice(data); 167 Ok(data.len()) 168 } 169} 170 171// `pin_data` cannot handle structs without braces. 172#[pin_data] 173struct GrandChild {} 174 175impl GrandChild { 176 fn new() -> impl PinInit<Self, Error> { 177 try_pin_init!(Self {}) 178 } 179} 180 181#[vtable] 182impl configfs::AttributeOperations<0> for GrandChild { 183 type Data = GrandChild; 184 185 fn show(_container: &GrandChild, page: &mut [u8; PAGE_SIZE]) -> Result<usize> { 186 pr_info!("Show grand child\n"); 187 let data = c"Hello GC\n".to_bytes(); 188 page[0..data.len()].copy_from_slice(data); 189 Ok(data.len()) 190 } 191}