Procházet zdrojové kódy

Core refactor of Map API

Build completing tests passing

Refactor the Map API to better align
with the aya programs API.  Specifically
remove all internal locking mechanisms
and custom Deref/DerefMut implementations.
They are replaced with a Map enum
and AsRef/AsMut implementations.

All Try_From implementations have been moved
to standardized enums, with a slightly
special one for PerfEventArray's.

Also cleanup/fix all associated tests and
documentation.

Signed-off-by: Andrew Stoycos <astoycos@redhat.com>
Andrew Stoycos před 2 roky
rodič
revize
1aefa2e5e6

+ 1 - 1
aya-log/src/lib.rs

@@ -90,7 +90,7 @@ impl BpfLogger {
         logger: T,
         logger: T,
     ) -> Result<BpfLogger, Error> {
     ) -> Result<BpfLogger, Error> {
         let logger = Arc::new(logger);
         let logger = Arc::new(logger);
-        let mut logs: AsyncPerfEventArray<_> = bpf.map_mut("AYA_LOGS")?.try_into()?;
+        let mut logs: AsyncPerfEventArray<_> = bpf.take_map("AYA_LOGS")?.try_into()?;
 
 
         for cpu_id in online_cpus().map_err(Error::InvalidOnlineCpu)? {
         for cpu_id in online_cpus().map_err(Error::InvalidOnlineCpu)? {
             let mut buf = logs.open(cpu_id, None)?;
             let mut buf = logs.open(cpu_id, None)?;

+ 67 - 43
aya/src/bpf.rs

@@ -13,10 +13,10 @@ use thiserror::Error;
 
 
 use crate::{
 use crate::{
     generated::{
     generated::{
-        bpf_map_type::BPF_MAP_TYPE_PERF_EVENT_ARRAY, AYA_PERF_EVENT_IOC_DISABLE,
-        AYA_PERF_EVENT_IOC_ENABLE, AYA_PERF_EVENT_IOC_SET_BPF,
+        bpf_map_type::*, AYA_PERF_EVENT_IOC_DISABLE, AYA_PERF_EVENT_IOC_ENABLE,
+        AYA_PERF_EVENT_IOC_SET_BPF,
     },
     },
-    maps::{Map, MapError, MapLock, MapRef, MapRefMut},
+    maps::{Map, MapData, MapError},
     obj::{
     obj::{
         btf::{Btf, BtfError},
         btf::{Btf, BtfError},
         MapKind, Object, ParseError, ProgramSection,
         MapKind, Object, ParseError, ProgramSection,
@@ -451,7 +451,7 @@ impl<'a> BpfLoader<'a> {
                     }
                     }
                 }
                 }
             }
             }
-            let mut map = Map {
+            let mut map = MapData {
                 obj,
                 obj,
                 fd: None,
                 fd: None,
                 pinned: false,
                 pinned: false,
@@ -638,14 +638,41 @@ impl<'a> BpfLoader<'a> {
                 (name, program)
                 (name, program)
             })
             })
             .collect();
             .collect();
-        let maps = maps
-            .drain()
-            .map(|(name, map)| (name, MapLock::new(map)))
-            .collect();
-        Ok(Bpf { maps, programs })
+        let maps: Result<HashMap<String, Map>, BpfError> = maps.drain().map(parse_map).collect();
+
+        Ok(Bpf {
+            maps: maps?,
+            programs,
+        })
     }
     }
 }
 }
 
 
+fn parse_map(data: (String, MapData)) -> Result<(String, Map), BpfError> {
+    let name = data.0;
+    let map = data.1;
+    let map_type = map.map_type().map_err(BpfError::MapError)?;
+    let map = match map_type {
+        BPF_MAP_TYPE_ARRAY => Ok(Map::Array(map)),
+        BPF_MAP_TYPE_PERCPU_ARRAY => Ok(Map::PerCpuArray(map)),
+        BPF_MAP_TYPE_PROG_ARRAY => Ok(Map::ProgramArray(map)),
+        BPF_MAP_TYPE_HASH => Ok(Map::HashMap(map)),
+        BPF_MAP_TYPE_PERCPU_HASH => Ok(Map::PerCpuHashMap(map)),
+        BPF_MAP_TYPE_PERF_EVENT_ARRAY => Ok(Map::PerfEventArray(map)),
+        BPF_MAP_TYPE_SOCKHASH => Ok(Map::SockHash(map)),
+        BPF_MAP_TYPE_SOCKMAP => Ok(Map::SockMap(map)),
+        BPF_MAP_TYPE_BLOOM_FILTER => Ok(Map::BloomFilter(map)),
+        BPF_MAP_TYPE_LPM_TRIE => Ok(Map::LpmTrie(map)),
+        BPF_MAP_TYPE_STACK => Ok(Map::Stack(map)),
+        BPF_MAP_TYPE_STACK_TRACE => Ok(Map::StackTraceMap(map)),
+        BPF_MAP_TYPE_QUEUE => Ok(Map::Queue(map)),
+        m => Err(BpfError::MapError(MapError::InvalidMapType {
+            map_type: m as u32,
+        })),
+    }?;
+
+    Ok((name, map))
+}
+
 impl<'a> Default for BpfLoader<'a> {
 impl<'a> Default for BpfLoader<'a> {
     fn default() -> Self {
     fn default() -> Self {
         BpfLoader::new()
         BpfLoader::new()
@@ -655,7 +682,7 @@ impl<'a> Default for BpfLoader<'a> {
 /// The main entry point into the library, used to work with eBPF programs and maps.
 /// The main entry point into the library, used to work with eBPF programs and maps.
 #[derive(Debug)]
 #[derive(Debug)]
 pub struct Bpf {
 pub struct Bpf {
-    maps: HashMap<String, MapLock>,
+    maps: HashMap<String, Map>,
     programs: HashMap<String, Program>,
     programs: HashMap<String, Program>,
 }
 }
 
 
@@ -717,19 +744,11 @@ impl Bpf {
     ///
     ///
     /// # Errors
     /// # Errors
     ///
     ///
-    /// Returns [`MapError::MapNotFound`] if the map does not exist. If the map is already borrowed
-    /// mutably with [map_mut](Self::map_mut) then [`MapError::BorrowError`] is returned.
-    pub fn map(&self, name: &str) -> Result<MapRef, MapError> {
-        self.maps
-            .get(name)
-            .ok_or_else(|| MapError::MapNotFound {
-                name: name.to_owned(),
-            })
-            .and_then(|lock| {
-                lock.try_read().map_err(|_| MapError::BorrowError {
-                    name: name.to_owned(),
-                })
-            })
+    /// Returns [`MapError::MapNotFound`] if the map does not exist.
+    pub fn map(&self, name: &str) -> Result<&Map, MapError> {
+        self.maps.get(name).ok_or_else(|| MapError::MapNotFound {
+            name: name.to_owned(),
+        })
     }
     }
 
 
     /// Returns a mutable reference to the map with the given name.
     /// Returns a mutable reference to the map with the given name.
@@ -742,19 +761,32 @@ impl Bpf {
     ///
     ///
     /// # Errors
     /// # Errors
     ///
     ///
-    /// Returns [`MapError::MapNotFound`] if the map does not exist. If the map is already borrowed
-    /// mutably with [map_mut](Self::map_mut) then [`MapError::BorrowError`] is returned.
-    pub fn map_mut(&self, name: &str) -> Result<MapRefMut, MapError> {
+    /// Returns [`MapError::MapNotFound`] if the map does not exist.
+    pub fn map_mut(&mut self, name: &str) -> Result<&mut Map, MapError> {
         self.maps
         self.maps
-            .get(name)
+            .get_mut(name)
             .ok_or_else(|| MapError::MapNotFound {
             .ok_or_else(|| MapError::MapNotFound {
                 name: name.to_owned(),
                 name: name.to_owned(),
             })
             })
-            .and_then(|lock| {
-                lock.try_write().map_err(|_| MapError::BorrowError {
-                    name: name.to_owned(),
-                })
-            })
+    }
+
+    /// Returns a map with the given name.
+    ///
+    /// WARNING: This transfers ownership of the map to the user.
+    ///
+    /// The returned type is mostly opaque. In order to do anything useful with it you need to
+    /// convert it to a [typed map](crate::maps).
+    ///
+    /// For more details and examples on maps and their usage, see the [maps module
+    /// documentation][crate::maps].
+    ///
+    /// # Errors
+    ///
+    /// Returns [`MapError::MapNotFound`] if the map does not exist.
+    pub fn take_map(&mut self, name: &str) -> Result<Map, MapError> {
+        self.maps.remove(name).ok_or_else(|| MapError::MapNotFound {
+            name: name.to_owned(),
+        })
     }
     }
 
 
     /// An iterator over all the maps.
     /// An iterator over all the maps.
@@ -764,22 +796,14 @@ impl Bpf {
     /// # let mut bpf = aya::Bpf::load(&[])?;
     /// # let mut bpf = aya::Bpf::load(&[])?;
     /// for (name, map) in bpf.maps() {
     /// for (name, map) in bpf.maps() {
     ///     println!(
     ///     println!(
-    ///         "found map `{}` of type `{:?}`",
+    ///         "found map `{}`",
     ///         name,
     ///         name,
-    ///         map?.map_type().unwrap()
     ///     );
     ///     );
     /// }
     /// }
     /// # Ok::<(), aya::BpfError>(())
     /// # Ok::<(), aya::BpfError>(())
     /// ```
     /// ```
-    pub fn maps(&self) -> impl Iterator<Item = (&str, Result<MapRef, MapError>)> {
-        let ret = self.maps.iter().map(|(name, lock)| {
-            (
-                name.as_str(),
-                lock.try_read()
-                    .map_err(|_| MapError::BorrowError { name: name.clone() }),
-            )
-        });
-        ret
+    pub fn maps(&self) -> impl Iterator<Item = (&str, Result<&Map, MapError>)> {
+        self.maps.iter().map(|(name, map)| (name.as_str(), Ok(map)))
     }
     }
 
 
     /// Returns a reference to the program with the given name.
     /// Returns a reference to the program with the given name.

+ 22 - 49
aya/src/maps/array/array.rs

@@ -1,12 +1,11 @@
 use std::{
 use std::{
+    convert::{AsMut, AsRef},
     marker::PhantomData,
     marker::PhantomData,
     mem,
     mem,
-    ops::{Deref, DerefMut},
 };
 };
 
 
 use crate::{
 use crate::{
-    generated::bpf_map_type::BPF_MAP_TYPE_ARRAY,
-    maps::{IterableMap, Map, MapError, MapRef, MapRefMut},
+    maps::{array, IterableMap, MapData, MapError},
     sys::{bpf_map_lookup_elem, bpf_map_update_elem},
     sys::{bpf_map_lookup_elem, bpf_map_update_elem},
     Pod,
     Pod,
 };
 };
@@ -22,38 +21,35 @@ use crate::{
 ///
 ///
 /// # Examples
 /// # Examples
 /// ```no_run
 /// ```no_run
-/// # let bpf = aya::Bpf::load(&[])?;
+/// # let mut bpf = aya::Bpf::load(&[])?;
 /// use aya::maps::Array;
 /// use aya::maps::Array;
 ///
 ///
-/// let mut array = Array::try_from(bpf.map_mut("ARRAY")?)?;
+/// let mut array: Array<_, u32> = bpf.map_mut("ARRAY")?.try_into()?;
 /// array.set(1, 42, 0)?;
 /// array.set(1, 42, 0)?;
 /// assert_eq!(array.get(&1, 0)?, 42);
 /// assert_eq!(array.get(&1, 0)?, 42);
 /// # Ok::<(), aya::BpfError>(())
 /// # Ok::<(), aya::BpfError>(())
 /// ```
 /// ```
 #[doc(alias = "BPF_MAP_TYPE_ARRAY")]
 #[doc(alias = "BPF_MAP_TYPE_ARRAY")]
-pub struct Array<T: Deref<Target = Map>, V: Pod> {
+pub struct Array<T, V: Pod> {
     inner: T,
     inner: T,
     _v: PhantomData<V>,
     _v: PhantomData<V>,
 }
 }
 
 
-impl<T: Deref<Target = Map>, V: Pod> Array<T, V> {
-    fn new(map: T) -> Result<Array<T, V>, MapError> {
-        let map_type = map.obj.map_type();
-        if map_type != BPF_MAP_TYPE_ARRAY as u32 {
-            return Err(MapError::InvalidMapType { map_type });
-        }
+impl<T: AsRef<MapData>, V: Pod> Array<T, V> {
+    pub(crate) fn new(map: T) -> Result<Array<T, V>, MapError> {
+        let data = map.as_ref();
         let expected = mem::size_of::<u32>();
         let expected = mem::size_of::<u32>();
-        let size = map.obj.key_size() as usize;
+        let size = data.obj.key_size() as usize;
         if size != expected {
         if size != expected {
             return Err(MapError::InvalidKeySize { size, expected });
             return Err(MapError::InvalidKeySize { size, expected });
         }
         }
 
 
         let expected = mem::size_of::<V>();
         let expected = mem::size_of::<V>();
-        let size = map.obj.value_size() as usize;
+        let size = data.obj.value_size() as usize;
         if size != expected {
         if size != expected {
             return Err(MapError::InvalidValueSize { size, expected });
             return Err(MapError::InvalidValueSize { size, expected });
         }
         }
-        let _fd = map.fd_or_err()?;
+        let _fd = data.fd_or_err()?;
 
 
         Ok(Array {
         Ok(Array {
             inner: map,
             inner: map,
@@ -65,7 +61,7 @@ impl<T: Deref<Target = Map>, V: Pod> Array<T, V> {
     ///
     ///
     /// This corresponds to the value of `bpf_map_def::max_entries` on the eBPF side.
     /// This corresponds to the value of `bpf_map_def::max_entries` on the eBPF side.
     pub fn len(&self) -> u32 {
     pub fn len(&self) -> u32 {
-        self.inner.obj.max_entries()
+        self.inner.as_ref().obj.max_entries()
     }
     }
 
 
     /// Returns the value stored at the given index.
     /// Returns the value stored at the given index.
@@ -75,8 +71,9 @@ impl<T: Deref<Target = Map>, V: Pod> Array<T, V> {
     /// Returns [`MapError::OutOfBounds`] if `index` is out of bounds, [`MapError::SyscallError`]
     /// Returns [`MapError::OutOfBounds`] if `index` is out of bounds, [`MapError::SyscallError`]
     /// if `bpf_map_lookup_elem` fails.
     /// if `bpf_map_lookup_elem` fails.
     pub fn get(&self, index: &u32, flags: u64) -> Result<V, MapError> {
     pub fn get(&self, index: &u32, flags: u64) -> Result<V, MapError> {
-        self.check_bounds(*index)?;
-        let fd = self.inner.fd_or_err()?;
+        let data = self.inner.as_ref();
+        array::check_bounds(data, *index)?;
+        let fd = data.fd_or_err()?;
 
 
         let value = bpf_map_lookup_elem(fd, index, flags).map_err(|(_, io_error)| {
         let value = bpf_map_lookup_elem(fd, index, flags).map_err(|(_, io_error)| {
             MapError::SyscallError {
             MapError::SyscallError {
@@ -92,18 +89,9 @@ impl<T: Deref<Target = Map>, V: Pod> Array<T, V> {
     pub fn iter(&self) -> impl Iterator<Item = Result<V, MapError>> + '_ {
     pub fn iter(&self) -> impl Iterator<Item = Result<V, MapError>> + '_ {
         (0..self.len()).map(move |i| self.get(&i, 0))
         (0..self.len()).map(move |i| self.get(&i, 0))
     }
     }
-
-    fn check_bounds(&self, index: u32) -> Result<(), MapError> {
-        let max_entries = self.inner.obj.max_entries();
-        if index >= self.inner.obj.max_entries() {
-            Err(MapError::OutOfBounds { index, max_entries })
-        } else {
-            Ok(())
-        }
-    }
 }
 }
 
 
-impl<T: Deref<Target = Map> + DerefMut<Target = Map>, V: Pod> Array<T, V> {
+impl<T: AsMut<MapData>, V: Pod> Array<T, V> {
     /// Sets the value of the element at the given index.
     /// Sets the value of the element at the given index.
     ///
     ///
     /// # Errors
     /// # Errors
@@ -111,8 +99,9 @@ impl<T: Deref<Target = Map> + DerefMut<Target = Map>, V: Pod> Array<T, V> {
     /// Returns [`MapError::OutOfBounds`] if `index` is out of bounds, [`MapError::SyscallError`]
     /// Returns [`MapError::OutOfBounds`] if `index` is out of bounds, [`MapError::SyscallError`]
     /// if `bpf_map_update_elem` fails.
     /// if `bpf_map_update_elem` fails.
     pub fn set(&mut self, index: u32, value: V, flags: u64) -> Result<(), MapError> {
     pub fn set(&mut self, index: u32, value: V, flags: u64) -> Result<(), MapError> {
-        let fd = self.inner.fd_or_err()?;
-        self.check_bounds(index)?;
+        let data = self.inner.as_mut();
+        array::check_bounds(data, index)?;
+        let fd = data.fd_or_err()?;
         bpf_map_update_elem(fd, Some(&index), &value, flags).map_err(|(_, io_error)| {
         bpf_map_update_elem(fd, Some(&index), &value, flags).map_err(|(_, io_error)| {
             MapError::SyscallError {
             MapError::SyscallError {
                 call: "bpf_map_update_elem".to_owned(),
                 call: "bpf_map_update_elem".to_owned(),
@@ -123,28 +112,12 @@ impl<T: Deref<Target = Map> + DerefMut<Target = Map>, V: Pod> Array<T, V> {
     }
     }
 }
 }
 
 
-impl<T: Deref<Target = Map>, V: Pod> IterableMap<u32, V> for Array<T, V> {
-    fn map(&self) -> &Map {
-        &self.inner
+impl<T: AsRef<MapData>, V: Pod> IterableMap<u32, V> for Array<T, V> {
+    fn map(&self) -> &MapData {
+        self.inner.as_ref()
     }
     }
 
 
     fn get(&self, index: &u32) -> Result<V, MapError> {
     fn get(&self, index: &u32) -> Result<V, MapError> {
         self.get(index, 0)
         self.get(index, 0)
     }
     }
 }
 }
-
-impl<V: Pod> TryFrom<MapRef> for Array<MapRef, V> {
-    type Error = MapError;
-
-    fn try_from(a: MapRef) -> Result<Array<MapRef, V>, MapError> {
-        Array::new(a)
-    }
-}
-
-impl<V: Pod> TryFrom<MapRefMut> for Array<MapRefMut, V> {
-    type Error = MapError;
-
-    fn try_from(a: MapRefMut) -> Result<Array<MapRefMut, V>, MapError> {
-        Array::new(a)
-    }
-}

+ 12 - 1
aya/src/maps/array/mod.rs

@@ -4,6 +4,17 @@ mod array;
 mod per_cpu_array;
 mod per_cpu_array;
 mod program_array;
 mod program_array;
 
 
-pub use array::Array;
+pub use array::*;
 pub use per_cpu_array::PerCpuArray;
 pub use per_cpu_array::PerCpuArray;
 pub use program_array::ProgramArray;
 pub use program_array::ProgramArray;
+
+use crate::maps::{MapData, MapError};
+
+pub(crate) fn check_bounds(map: &MapData, index: u32) -> Result<(), MapError> {
+    let max_entries = map.obj.max_entries();
+    if index >= map.obj.max_entries() {
+        Err(MapError::OutOfBounds { index, max_entries })
+    } else {
+        Ok(())
+    }
+}

+ 23 - 49
aya/src/maps/array/per_cpu_array.rs

@@ -1,12 +1,11 @@
 use std::{
 use std::{
+    convert::{AsMut, AsRef},
     marker::PhantomData,
     marker::PhantomData,
     mem,
     mem,
-    ops::{Deref, DerefMut},
 };
 };
 
 
 use crate::{
 use crate::{
-    generated::bpf_map_type::BPF_MAP_TYPE_PERCPU_ARRAY,
-    maps::{IterableMap, Map, MapError, MapRef, MapRefMut, PerCpuValues},
+    maps::{array, IterableMap, MapData, MapError, PerCpuValues},
     sys::{bpf_map_lookup_elem_per_cpu, bpf_map_update_elem_per_cpu},
     sys::{bpf_map_lookup_elem_per_cpu, bpf_map_update_elem_per_cpu},
     Pod,
     Pod,
 };
 };
@@ -31,11 +30,11 @@ use crate::{
 /// #     #[error(transparent)]
 /// #     #[error(transparent)]
 /// #     Bpf(#[from] aya::BpfError)
 /// #     Bpf(#[from] aya::BpfError)
 /// # }
 /// # }
-/// # let bpf = aya::Bpf::load(&[])?;
+/// # let mut bpf = aya::Bpf::load(&[])?;
 /// use aya::maps::{PerCpuArray, PerCpuValues};
 /// use aya::maps::{PerCpuArray, PerCpuValues};
 /// use aya::util::nr_cpus;
 /// use aya::util::nr_cpus;
 ///
 ///
-/// let mut array = PerCpuArray::try_from(bpf.map_mut("ARRAY")?)?;
+/// let mut array: PerCpuArray<_,u32> = bpf.map_mut("ARRAY")?.try_into()?;
 ///
 ///
 /// // set array[1] = 42 for all cpus
 /// // set array[1] = 42 for all cpus
 /// let nr_cpus = nr_cpus()?;
 /// let nr_cpus = nr_cpus()?;
@@ -50,29 +49,26 @@ use crate::{
 /// # Ok::<(), Error>(())
 /// # Ok::<(), Error>(())
 /// ```
 /// ```
 #[doc(alias = "BPF_MAP_TYPE_PERCPU_ARRAY")]
 #[doc(alias = "BPF_MAP_TYPE_PERCPU_ARRAY")]
-pub struct PerCpuArray<T: Deref<Target = Map>, V: Pod> {
+pub struct PerCpuArray<T, V: Pod> {
     inner: T,
     inner: T,
     _v: PhantomData<V>,
     _v: PhantomData<V>,
 }
 }
 
 
-impl<T: Deref<Target = Map>, V: Pod> PerCpuArray<T, V> {
-    fn new(map: T) -> Result<PerCpuArray<T, V>, MapError> {
-        let map_type = map.obj.map_type();
-        if map_type != BPF_MAP_TYPE_PERCPU_ARRAY as u32 {
-            return Err(MapError::InvalidMapType { map_type });
-        }
+impl<T: AsRef<MapData>, V: Pod> PerCpuArray<T, V> {
+    pub(crate) fn new(map: T) -> Result<PerCpuArray<T, V>, MapError> {
+        let data = map.as_ref();
         let expected = mem::size_of::<u32>();
         let expected = mem::size_of::<u32>();
-        let size = map.obj.key_size() as usize;
+        let size = data.obj.key_size() as usize;
         if size != expected {
         if size != expected {
             return Err(MapError::InvalidKeySize { size, expected });
             return Err(MapError::InvalidKeySize { size, expected });
         }
         }
 
 
         let expected = mem::size_of::<V>();
         let expected = mem::size_of::<V>();
-        let size = map.obj.value_size() as usize;
+        let size = data.obj.value_size() as usize;
         if size != expected {
         if size != expected {
             return Err(MapError::InvalidValueSize { size, expected });
             return Err(MapError::InvalidValueSize { size, expected });
         }
         }
-        let _fd = map.fd_or_err()?;
+        let _fd = data.fd_or_err()?;
 
 
         Ok(PerCpuArray {
         Ok(PerCpuArray {
             inner: map,
             inner: map,
@@ -84,7 +80,7 @@ impl<T: Deref<Target = Map>, V: Pod> PerCpuArray<T, V> {
     ///
     ///
     /// This corresponds to the value of `bpf_map_def::max_entries` on the eBPF side.
     /// This corresponds to the value of `bpf_map_def::max_entries` on the eBPF side.
     pub fn len(&self) -> u32 {
     pub fn len(&self) -> u32 {
-        self.inner.obj.max_entries()
+        self.inner.as_ref().obj.max_entries()
     }
     }
 
 
     /// Returns a slice of values - one for each CPU - stored at the given index.
     /// Returns a slice of values - one for each CPU - stored at the given index.
@@ -94,8 +90,9 @@ impl<T: Deref<Target = Map>, V: Pod> PerCpuArray<T, V> {
     /// Returns [`MapError::OutOfBounds`] if `index` is out of bounds, [`MapError::SyscallError`]
     /// Returns [`MapError::OutOfBounds`] if `index` is out of bounds, [`MapError::SyscallError`]
     /// if `bpf_map_lookup_elem` fails.
     /// if `bpf_map_lookup_elem` fails.
     pub fn get(&self, index: &u32, flags: u64) -> Result<PerCpuValues<V>, MapError> {
     pub fn get(&self, index: &u32, flags: u64) -> Result<PerCpuValues<V>, MapError> {
-        self.check_bounds(*index)?;
-        let fd = self.inner.fd_or_err()?;
+        let data = self.inner.as_ref();
+        array::check_bounds(data, *index)?;
+        let fd = data.fd_or_err()?;
 
 
         let value = bpf_map_lookup_elem_per_cpu(fd, index, flags).map_err(|(_, io_error)| {
         let value = bpf_map_lookup_elem_per_cpu(fd, index, flags).map_err(|(_, io_error)| {
             MapError::SyscallError {
             MapError::SyscallError {
@@ -111,18 +108,9 @@ impl<T: Deref<Target = Map>, V: Pod> PerCpuArray<T, V> {
     pub fn iter(&self) -> impl Iterator<Item = Result<PerCpuValues<V>, MapError>> + '_ {
     pub fn iter(&self) -> impl Iterator<Item = Result<PerCpuValues<V>, MapError>> + '_ {
         (0..self.len()).map(move |i| self.get(&i, 0))
         (0..self.len()).map(move |i| self.get(&i, 0))
     }
     }
-
-    fn check_bounds(&self, index: u32) -> Result<(), MapError> {
-        let max_entries = self.inner.obj.max_entries();
-        if index >= self.inner.obj.max_entries() {
-            Err(MapError::OutOfBounds { index, max_entries })
-        } else {
-            Ok(())
-        }
-    }
 }
 }
 
 
-impl<T: Deref<Target = Map> + DerefMut<Target = Map>, V: Pod> PerCpuArray<T, V> {
+impl<T: AsMut<MapData>, V: Pod> PerCpuArray<T, V> {
     /// Sets the values - one for each CPU - at the given index.
     /// Sets the values - one for each CPU - at the given index.
     ///
     ///
     /// # Errors
     /// # Errors
@@ -130,8 +118,10 @@ impl<T: Deref<Target = Map> + DerefMut<Target = Map>, V: Pod> PerCpuArray<T, V>
     /// Returns [`MapError::OutOfBounds`] if `index` is out of bounds, [`MapError::SyscallError`]
     /// Returns [`MapError::OutOfBounds`] if `index` is out of bounds, [`MapError::SyscallError`]
     /// if `bpf_map_update_elem` fails.
     /// if `bpf_map_update_elem` fails.
     pub fn set(&mut self, index: u32, values: PerCpuValues<V>, flags: u64) -> Result<(), MapError> {
     pub fn set(&mut self, index: u32, values: PerCpuValues<V>, flags: u64) -> Result<(), MapError> {
-        let fd = self.inner.fd_or_err()?;
-        self.check_bounds(index)?;
+        let data = self.inner.as_mut();
+        array::check_bounds(data, index)?;
+        let fd = data.fd_or_err()?;
+
         bpf_map_update_elem_per_cpu(fd, &index, &values, flags).map_err(|(_, io_error)| {
         bpf_map_update_elem_per_cpu(fd, &index, &values, flags).map_err(|(_, io_error)| {
             MapError::SyscallError {
             MapError::SyscallError {
                 call: "bpf_map_update_elem".to_owned(),
                 call: "bpf_map_update_elem".to_owned(),
@@ -142,28 +132,12 @@ impl<T: Deref<Target = Map> + DerefMut<Target = Map>, V: Pod> PerCpuArray<T, V>
     }
     }
 }
 }
 
 
-impl<T: Deref<Target = Map>, V: Pod> IterableMap<u32, PerCpuValues<V>> for PerCpuArray<T, V> {
-    fn map(&self) -> &Map {
-        &self.inner
+impl<T: AsRef<MapData>, V: Pod> IterableMap<u32, PerCpuValues<V>> for PerCpuArray<T, V> {
+    fn map(&self) -> &MapData {
+        self.inner.as_ref()
     }
     }
 
 
     fn get(&self, index: &u32) -> Result<PerCpuValues<V>, MapError> {
     fn get(&self, index: &u32) -> Result<PerCpuValues<V>, MapError> {
         self.get(index, 0)
         self.get(index, 0)
     }
     }
 }
 }
-
-impl<V: Pod> TryFrom<MapRef> for PerCpuArray<MapRef, V> {
-    type Error = MapError;
-
-    fn try_from(a: MapRef) -> Result<PerCpuArray<MapRef, V>, MapError> {
-        PerCpuArray::new(a)
-    }
-}
-
-impl<V: Pod> TryFrom<MapRefMut> for PerCpuArray<MapRefMut, V> {
-    type Error = MapError;
-
-    fn try_from(a: MapRefMut) -> Result<PerCpuArray<MapRefMut, V>, MapError> {
-        PerCpuArray::new(a)
-    }
-}

+ 19 - 45
aya/src/maps/array/program_array.rs

@@ -1,14 +1,13 @@
 //! An array of eBPF program file descriptors used as a jump table.
 //! An array of eBPF program file descriptors used as a jump table.
 
 
 use std::{
 use std::{
+    convert::{AsMut, AsRef},
     mem,
     mem,
-    ops::{Deref, DerefMut},
     os::unix::prelude::{AsRawFd, RawFd},
     os::unix::prelude::{AsRawFd, RawFd},
 };
 };
 
 
 use crate::{
 use crate::{
-    generated::bpf_map_type::BPF_MAP_TYPE_PROG_ARRAY,
-    maps::{Map, MapError, MapKeys, MapRef, MapRefMut},
+    maps::{array, MapData, MapError, MapKeys},
     programs::ProgramFd,
     programs::ProgramFd,
     sys::{bpf_map_delete_elem, bpf_map_update_elem},
     sys::{bpf_map_delete_elem, bpf_map_update_elem},
 };
 };
@@ -29,7 +28,7 @@ use crate::{
 /// use aya::maps::ProgramArray;
 /// use aya::maps::ProgramArray;
 /// use aya::programs::CgroupSkb;
 /// use aya::programs::CgroupSkb;
 ///
 ///
-/// let mut prog_array = ProgramArray::try_from(bpf.map_mut("JUMP_TABLE")?)?;
+/// let mut prog_array: ProgramArray<_> = bpf.take_map("JUMP_TABLE")?.try_into()?;
 /// let prog_0: &CgroupSkb = bpf.program("example_prog_0").unwrap().try_into()?;
 /// let prog_0: &CgroupSkb = bpf.program("example_prog_0").unwrap().try_into()?;
 /// let prog_0_fd =  prog_0.fd().unwrap();
 /// let prog_0_fd =  prog_0.fd().unwrap();
 /// let prog_1: &CgroupSkb = bpf.program("example_prog_1").unwrap().try_into()?;
 /// let prog_1: &CgroupSkb = bpf.program("example_prog_1").unwrap().try_into()?;
@@ -49,28 +48,25 @@ use crate::{
 /// # Ok::<(), aya::BpfError>(())
 /// # Ok::<(), aya::BpfError>(())
 /// ```
 /// ```
 #[doc(alias = "BPF_MAP_TYPE_PROG_ARRAY")]
 #[doc(alias = "BPF_MAP_TYPE_PROG_ARRAY")]
-pub struct ProgramArray<T: Deref<Target = Map>> {
+pub struct ProgramArray<T> {
     inner: T,
     inner: T,
 }
 }
 
 
-impl<T: Deref<Target = Map>> ProgramArray<T> {
-    fn new(map: T) -> Result<ProgramArray<T>, MapError> {
-        let map_type = map.obj.map_type();
-        if map_type != BPF_MAP_TYPE_PROG_ARRAY as u32 {
-            return Err(MapError::InvalidMapType { map_type });
-        }
+impl<T: AsRef<MapData>> ProgramArray<T> {
+    pub(crate) fn new(map: T) -> Result<ProgramArray<T>, MapError> {
+        let data = map.as_ref();
         let expected = mem::size_of::<u32>();
         let expected = mem::size_of::<u32>();
-        let size = map.obj.key_size() as usize;
+        let size = data.obj.key_size() as usize;
         if size != expected {
         if size != expected {
             return Err(MapError::InvalidKeySize { size, expected });
             return Err(MapError::InvalidKeySize { size, expected });
         }
         }
 
 
         let expected = mem::size_of::<RawFd>();
         let expected = mem::size_of::<RawFd>();
-        let size = map.obj.value_size() as usize;
+        let size = data.obj.value_size() as usize;
         if size != expected {
         if size != expected {
             return Err(MapError::InvalidValueSize { size, expected });
             return Err(MapError::InvalidValueSize { size, expected });
         }
         }
-        let _fd = map.fd_or_err()?;
+        let _fd = data.fd_or_err()?;
 
 
         Ok(ProgramArray { inner: map })
         Ok(ProgramArray { inner: map })
     }
     }
@@ -78,27 +74,19 @@ impl<T: Deref<Target = Map>> ProgramArray<T> {
     /// An iterator over the indices of the array that point to a program. The iterator item type
     /// An iterator over the indices of the array that point to a program. The iterator item type
     /// is `Result<u32, MapError>`.
     /// is `Result<u32, MapError>`.
     pub fn indices(&self) -> MapKeys<'_, u32> {
     pub fn indices(&self) -> MapKeys<'_, u32> {
-        MapKeys::new(&self.inner)
-    }
-
-    fn check_bounds(&self, index: u32) -> Result<(), MapError> {
-        let max_entries = self.inner.obj.max_entries();
-        if index >= self.inner.obj.max_entries() {
-            Err(MapError::OutOfBounds { index, max_entries })
-        } else {
-            Ok(())
-        }
+        MapKeys::new(self.inner.as_ref())
     }
     }
 }
 }
 
 
-impl<T: Deref<Target = Map> + DerefMut<Target = Map>> ProgramArray<T> {
+impl<T: AsMut<MapData>> ProgramArray<T> {
     /// Sets the target program file descriptor for the given index in the jump table.
     /// Sets the target program file descriptor for the given index in the jump table.
     ///
     ///
     /// When an eBPF program calls `bpf_tail_call(ctx, prog_array, index)`, control
     /// When an eBPF program calls `bpf_tail_call(ctx, prog_array, index)`, control
     /// flow will jump to `program`.
     /// flow will jump to `program`.
     pub fn set(&mut self, index: u32, program: ProgramFd, flags: u64) -> Result<(), MapError> {
     pub fn set(&mut self, index: u32, program: ProgramFd, flags: u64) -> Result<(), MapError> {
-        let fd = self.inner.fd_or_err()?;
-        self.check_bounds(index)?;
+        let data = self.inner.as_mut();
+        array::check_bounds(data, index)?;
+        let fd = data.fd_or_err()?;
         let prog_fd = program.as_raw_fd();
         let prog_fd = program.as_raw_fd();
 
 
         bpf_map_update_elem(fd, Some(&index), &prog_fd, flags).map_err(|(_, io_error)| {
         bpf_map_update_elem(fd, Some(&index), &prog_fd, flags).map_err(|(_, io_error)| {
@@ -115,8 +103,10 @@ impl<T: Deref<Target = Map> + DerefMut<Target = Map>> ProgramArray<T> {
     /// Calling `bpf_tail_call(ctx, prog_array, index)` on an index that has been cleared returns an
     /// Calling `bpf_tail_call(ctx, prog_array, index)` on an index that has been cleared returns an
     /// error.
     /// error.
     pub fn clear_index(&mut self, index: &u32) -> Result<(), MapError> {
     pub fn clear_index(&mut self, index: &u32) -> Result<(), MapError> {
-        let fd = self.inner.fd_or_err()?;
-        self.check_bounds(*index)?;
+        let data = self.inner.as_mut();
+        array::check_bounds(data, *index)?;
+        let fd = self.inner.as_mut().fd_or_err()?;
+
         bpf_map_delete_elem(fd, index)
         bpf_map_delete_elem(fd, index)
             .map(|_| ())
             .map(|_| ())
             .map_err(|(_, io_error)| MapError::SyscallError {
             .map_err(|(_, io_error)| MapError::SyscallError {
@@ -125,19 +115,3 @@ impl<T: Deref<Target = Map> + DerefMut<Target = Map>> ProgramArray<T> {
             })
             })
     }
     }
 }
 }
-
-impl TryFrom<MapRef> for ProgramArray<MapRef> {
-    type Error = MapError;
-
-    fn try_from(a: MapRef) -> Result<ProgramArray<MapRef>, MapError> {
-        ProgramArray::new(a)
-    }
-}
-
-impl TryFrom<MapRefMut> for ProgramArray<MapRefMut> {
-    type Error = MapError;
-
-    fn try_from(a: MapRefMut) -> Result<ProgramArray<MapRefMut>, MapError> {
-        ProgramArray::new(a)
-    }
-}

+ 26 - 60
aya/src/maps/bloom_filter.rs

@@ -1,11 +1,10 @@
 //! A Bloom Filter.
 //! A Bloom Filter.
-use std::{marker::PhantomData, ops::Deref};
+use std::{convert::AsRef, marker::PhantomData};
 
 
 use core::mem;
 use core::mem;
 
 
 use crate::{
 use crate::{
-    generated::bpf_map_type::BPF_MAP_TYPE_BLOOM_FILTER,
-    maps::{Map, MapError, MapRef, MapRefMut},
+    maps::{MapData, MapError},
     sys::{bpf_map_lookup_elem_ptr, bpf_map_push_elem},
     sys::{bpf_map_lookup_elem_ptr, bpf_map_push_elem},
     Pod,
     Pod,
 };
 };
@@ -19,10 +18,10 @@ use crate::{
 /// # Examples
 /// # Examples
 ///
 ///
 /// ```no_run
 /// ```no_run
-/// # let bpf = aya::Bpf::load(&[])?;
+/// # let mut bpf = aya::Bpf::load(&[])?;
 /// use aya::maps::bloom_filter::BloomFilter;
 /// use aya::maps::bloom_filter::BloomFilter;
 ///
 ///
-/// let mut bloom_filter = BloomFilter::try_from(bpf.map_mut("BLOOM_FILTER")?)?;
+/// let mut bloom_filter: BloomFilter<_,u32> = bpf.map_mut("BLOOM_FILTER")?.try_into()?;
 ///
 ///
 /// bloom_filter.insert(1, 0)?;
 /// bloom_filter.insert(1, 0)?;
 ///
 ///
@@ -33,27 +32,21 @@ use crate::{
 /// ```
 /// ```
 
 
 #[doc(alias = "BPF_MAP_TYPE_BLOOM_FILTER")]
 #[doc(alias = "BPF_MAP_TYPE_BLOOM_FILTER")]
-pub struct BloomFilter<T: Deref<Target = Map>, V: Pod> {
+pub struct BloomFilter<T, V: Pod> {
     inner: T,
     inner: T,
     _v: PhantomData<V>,
     _v: PhantomData<V>,
 }
 }
 
 
-impl<T: Deref<Target = Map>, V: Pod> BloomFilter<T, V> {
+impl<T: AsRef<MapData>, V: Pod> BloomFilter<T, V> {
     pub(crate) fn new(map: T) -> Result<BloomFilter<T, V>, MapError> {
     pub(crate) fn new(map: T) -> Result<BloomFilter<T, V>, MapError> {
-        let map_type = map.obj.map_type();
-
-        // validate the map definition
-        if map_type != BPF_MAP_TYPE_BLOOM_FILTER as u32 {
-            return Err(MapError::InvalidMapType { map_type });
-        }
-
+        let data = map.as_ref();
         let size = mem::size_of::<V>();
         let size = mem::size_of::<V>();
-        let expected = map.obj.value_size() as usize;
+        let expected = data.obj.value_size() as usize;
         if size != expected {
         if size != expected {
             return Err(MapError::InvalidValueSize { size, expected });
             return Err(MapError::InvalidValueSize { size, expected });
         };
         };
 
 
-        let _ = map.fd_or_err()?;
+        let _ = data.fd_or_err()?;
 
 
         Ok(BloomFilter {
         Ok(BloomFilter {
             inner: map,
             inner: map,
@@ -63,7 +56,7 @@ impl<T: Deref<Target = Map>, V: Pod> BloomFilter<T, V> {
 
 
     /// Query the existence of the element.
     /// Query the existence of the element.
     pub fn contains(&self, mut value: &V, flags: u64) -> Result<(), MapError> {
     pub fn contains(&self, mut value: &V, flags: u64) -> Result<(), MapError> {
-        let fd = self.inner.deref().fd_or_err()?;
+        let fd = self.inner.as_ref().fd_or_err()?;
 
 
         bpf_map_lookup_elem_ptr::<u32, _>(fd, None, &mut value, flags)
         bpf_map_lookup_elem_ptr::<u32, _>(fd, None, &mut value, flags)
             .map_err(|(_, io_error)| MapError::SyscallError {
             .map_err(|(_, io_error)| MapError::SyscallError {
@@ -76,7 +69,7 @@ impl<T: Deref<Target = Map>, V: Pod> BloomFilter<T, V> {
 
 
     /// Inserts a value into the map.
     /// Inserts a value into the map.
     pub fn insert(&self, value: V, flags: u64) -> Result<(), MapError> {
     pub fn insert(&self, value: V, flags: u64) -> Result<(), MapError> {
-        let fd = self.inner.deref().fd_or_err()?;
+        let fd = self.inner.as_ref().fd_or_err()?;
         bpf_map_push_elem(fd, &value, flags).map_err(|(_, io_error)| MapError::SyscallError {
         bpf_map_push_elem(fd, &value, flags).map_err(|(_, io_error)| MapError::SyscallError {
             call: "bpf_map_push_elem".to_owned(),
             call: "bpf_map_push_elem".to_owned(),
             io_error,
             io_error,
@@ -85,38 +78,6 @@ impl<T: Deref<Target = Map>, V: Pod> BloomFilter<T, V> {
     }
     }
 }
 }
 
 
-impl<V: Pod> TryFrom<MapRef> for BloomFilter<MapRef, V> {
-    type Error = MapError;
-
-    fn try_from(a: MapRef) -> Result<BloomFilter<MapRef, V>, MapError> {
-        BloomFilter::new(a)
-    }
-}
-
-impl<V: Pod> TryFrom<MapRefMut> for BloomFilter<MapRefMut, V> {
-    type Error = MapError;
-
-    fn try_from(a: MapRefMut) -> Result<BloomFilter<MapRefMut, V>, MapError> {
-        BloomFilter::new(a)
-    }
-}
-
-impl<'a, V: Pod> TryFrom<&'a Map> for BloomFilter<&'a Map, V> {
-    type Error = MapError;
-
-    fn try_from(a: &'a Map) -> Result<BloomFilter<&'a Map, V>, MapError> {
-        BloomFilter::new(a)
-    }
-}
-
-impl<'a, V: Pod> TryFrom<&'a mut Map> for BloomFilter<&'a mut Map, V> {
-    type Error = MapError;
-
-    fn try_from(a: &'a mut Map) -> Result<BloomFilter<&'a mut Map, V>, MapError> {
-        BloomFilter::new(a)
-    }
-}
-
 #[cfg(test)]
 #[cfg(test)]
 mod tests {
 mod tests {
     use super::*;
     use super::*;
@@ -126,6 +87,7 @@ mod tests {
             bpf_cmd,
             bpf_cmd,
             bpf_map_type::{BPF_MAP_TYPE_BLOOM_FILTER, BPF_MAP_TYPE_PERF_EVENT_ARRAY},
             bpf_map_type::{BPF_MAP_TYPE_BLOOM_FILTER, BPF_MAP_TYPE_PERF_EVENT_ARRAY},
         },
         },
+        maps::{Map, MapData},
         obj,
         obj,
         sys::{override_syscall, SysResult, Syscall},
         sys::{override_syscall, SysResult, Syscall},
     };
     };
@@ -154,7 +116,7 @@ mod tests {
 
 
     #[test]
     #[test]
     fn test_wrong_value_size() {
     fn test_wrong_value_size() {
-        let map = Map {
+        let map = MapData {
             obj: new_obj_map(),
             obj: new_obj_map(),
             fd: None,
             fd: None,
             pinned: false,
             pinned: false,
@@ -171,7 +133,7 @@ mod tests {
 
 
     #[test]
     #[test]
     fn test_try_from_wrong_map() {
     fn test_try_from_wrong_map() {
-        let map = Map {
+        let map_data = MapData {
             obj: obj::Map::Legacy(obj::LegacyMap {
             obj: obj::Map::Legacy(obj::LegacyMap {
                 def: bpf_map_def {
                 def: bpf_map_def {
                     map_type: BPF_MAP_TYPE_PERF_EVENT_ARRAY as u32,
                     map_type: BPF_MAP_TYPE_PERF_EVENT_ARRAY as u32,
@@ -190,15 +152,17 @@ mod tests {
             btf_fd: None,
             btf_fd: None,
         };
         };
 
 
+        let map = Map::PerfEventArray(map_data);
+
         assert!(matches!(
         assert!(matches!(
             BloomFilter::<_, u32>::try_from(&map),
             BloomFilter::<_, u32>::try_from(&map),
-            Err(MapError::InvalidMapType { .. })
+            Err(MapError::UnexpectedMapType)
         ));
         ));
     }
     }
 
 
     #[test]
     #[test]
     fn test_new_not_created() {
     fn test_new_not_created() {
-        let mut map = Map {
+        let mut map = MapData {
             obj: new_obj_map(),
             obj: new_obj_map(),
             fd: None,
             fd: None,
             pinned: false,
             pinned: false,
@@ -213,7 +177,7 @@ mod tests {
 
 
     #[test]
     #[test]
     fn test_new_ok() {
     fn test_new_ok() {
-        let mut map = Map {
+        let mut map = MapData {
             obj: new_obj_map(),
             obj: new_obj_map(),
             fd: Some(42),
             fd: Some(42),
             pinned: false,
             pinned: false,
@@ -225,12 +189,14 @@ mod tests {
 
 
     #[test]
     #[test]
     fn test_try_from_ok() {
     fn test_try_from_ok() {
-        let map = Map {
+        let map_data = MapData {
             obj: new_obj_map(),
             obj: new_obj_map(),
             fd: Some(42),
             fd: Some(42),
             pinned: false,
             pinned: false,
             btf_fd: None,
             btf_fd: None,
         };
         };
+
+        let map = Map::BloomFilter(map_data);
         assert!(BloomFilter::<_, u32>::try_from(&map).is_ok())
         assert!(BloomFilter::<_, u32>::try_from(&map).is_ok())
     }
     }
 
 
@@ -238,7 +204,7 @@ mod tests {
     fn test_insert_syscall_error() {
     fn test_insert_syscall_error() {
         override_syscall(|_| sys_error(EFAULT));
         override_syscall(|_| sys_error(EFAULT));
 
 
-        let mut map = Map {
+        let mut map = MapData {
             obj: new_obj_map(),
             obj: new_obj_map(),
             fd: Some(42),
             fd: Some(42),
             pinned: false,
             pinned: false,
@@ -262,7 +228,7 @@ mod tests {
             _ => sys_error(EFAULT),
             _ => sys_error(EFAULT),
         });
         });
 
 
-        let mut map = Map {
+        let mut map = MapData {
             obj: new_obj_map(),
             obj: new_obj_map(),
             fd: Some(42),
             fd: Some(42),
             pinned: false,
             pinned: false,
@@ -276,7 +242,7 @@ mod tests {
     #[test]
     #[test]
     fn test_contains_syscall_error() {
     fn test_contains_syscall_error() {
         override_syscall(|_| sys_error(EFAULT));
         override_syscall(|_| sys_error(EFAULT));
-        let map = Map {
+        let map = MapData {
             obj: new_obj_map(),
             obj: new_obj_map(),
             fd: Some(42),
             fd: Some(42),
             pinned: false,
             pinned: false,
@@ -299,7 +265,7 @@ mod tests {
             } => sys_error(ENOENT),
             } => sys_error(ENOENT),
             _ => sys_error(EFAULT),
             _ => sys_error(EFAULT),
         });
         });
-        let map = Map {
+        let map = MapData {
             obj: new_obj_map(),
             obj: new_obj_map(),
             fd: Some(42),
             fd: Some(42),
             pinned: false,
             pinned: false,

+ 67 - 91
aya/src/maps/hash_map/hash_map.rs

@@ -1,11 +1,10 @@
 use std::{
 use std::{
+    convert::{AsMut, AsRef},
     marker::PhantomData,
     marker::PhantomData,
-    ops::{Deref, DerefMut},
 };
 };
 
 
 use crate::{
 use crate::{
-    generated::bpf_map_type::{BPF_MAP_TYPE_HASH, BPF_MAP_TYPE_LRU_HASH},
-    maps::{hash_map, IterableMap, Map, MapError, MapIter, MapKeys, MapRef, MapRefMut},
+    maps::{hash_map, IterableMap, MapData, MapError, MapIter, MapKeys},
     sys::bpf_map_lookup_elem,
     sys::bpf_map_lookup_elem,
     Pod,
     Pod,
 };
 };
@@ -19,10 +18,10 @@ use crate::{
 /// # Examples
 /// # Examples
 ///
 ///
 /// ```no_run
 /// ```no_run
-/// # let bpf = aya::Bpf::load(&[])?;
+/// # let mut bpf = aya::Bpf::load(&[])?;
 /// use aya::maps::HashMap;
 /// use aya::maps::HashMap;
 ///
 ///
-/// let mut redirect_ports = HashMap::try_from(bpf.map_mut("REDIRECT_PORTS")?)?;
+/// let mut redirect_ports: HashMap<_, u32, u32> = bpf.map_mut("REDIRECT_PORTS")?.try_into()?;
 ///
 ///
 /// // redirect port 80 to 8080
 /// // redirect port 80 to 8080
 /// redirect_ports.insert(80, 8080, 0);
 /// redirect_ports.insert(80, 8080, 0);
@@ -32,22 +31,18 @@ use crate::{
 /// ```
 /// ```
 #[doc(alias = "BPF_MAP_TYPE_HASH")]
 #[doc(alias = "BPF_MAP_TYPE_HASH")]
 #[doc(alias = "BPF_MAP_TYPE_LRU_HASH")]
 #[doc(alias = "BPF_MAP_TYPE_LRU_HASH")]
-pub struct HashMap<T: Deref<Target = Map>, K, V> {
+#[derive(Debug)]
+pub struct HashMap<T, K, V> {
     inner: T,
     inner: T,
     _k: PhantomData<K>,
     _k: PhantomData<K>,
     _v: PhantomData<V>,
     _v: PhantomData<V>,
 }
 }
 
 
-impl<T: Deref<Target = Map>, K: Pod, V: Pod> HashMap<T, K, V> {
+impl<T: AsRef<MapData>, K: Pod, V: Pod> HashMap<T, K, V> {
     pub(crate) fn new(map: T) -> Result<HashMap<T, K, V>, MapError> {
     pub(crate) fn new(map: T) -> Result<HashMap<T, K, V>, MapError> {
-        let map_type = map.obj.map_type();
-
-        // validate the map definition
-        if map_type != BPF_MAP_TYPE_HASH as u32 && map_type != BPF_MAP_TYPE_LRU_HASH as u32 {
-            return Err(MapError::InvalidMapType { map_type });
-        }
-        hash_map::check_kv_size::<K, V>(&map)?;
-        let _ = map.fd_or_err()?;
+        let data = map.as_ref();
+        hash_map::check_kv_size::<K, V>(data)?;
+        let _ = data.fd_or_err()?;
 
 
         Ok(HashMap {
         Ok(HashMap {
             inner: map,
             inner: map,
@@ -58,7 +53,7 @@ impl<T: Deref<Target = Map>, K: Pod, V: Pod> HashMap<T, K, V> {
 
 
     /// Returns a copy of the value associated with the key.
     /// Returns a copy of the value associated with the key.
     pub fn get(&self, key: &K, flags: u64) -> Result<V, MapError> {
     pub fn get(&self, key: &K, flags: u64) -> Result<V, MapError> {
-        let fd = self.inner.deref().fd_or_err()?;
+        let fd = self.inner.as_ref().fd_or_err()?;
         let value = bpf_map_lookup_elem(fd, key, flags).map_err(|(_, io_error)| {
         let value = bpf_map_lookup_elem(fd, key, flags).map_err(|(_, io_error)| {
             MapError::SyscallError {
             MapError::SyscallError {
                 call: "bpf_map_lookup_elem".to_owned(),
                 call: "bpf_map_lookup_elem".to_owned(),
@@ -77,25 +72,25 @@ impl<T: Deref<Target = Map>, K: Pod, V: Pod> HashMap<T, K, V> {
     /// An iterator visiting all keys in arbitrary order. The iterator element
     /// An iterator visiting all keys in arbitrary order. The iterator element
     /// type is `Result<K, MapError>`.
     /// type is `Result<K, MapError>`.
     pub fn keys(&self) -> MapKeys<'_, K> {
     pub fn keys(&self) -> MapKeys<'_, K> {
-        MapKeys::new(&self.inner)
+        MapKeys::new(self.inner.as_ref())
     }
     }
 }
 }
 
 
-impl<T: DerefMut<Target = Map>, K: Pod, V: Pod> HashMap<T, K, V> {
+impl<T: AsMut<MapData>, K: Pod, V: Pod> HashMap<T, K, V> {
     /// Inserts a key-value pair into the map.
     /// Inserts a key-value pair into the map.
     pub fn insert(&mut self, key: K, value: V, flags: u64) -> Result<(), MapError> {
     pub fn insert(&mut self, key: K, value: V, flags: u64) -> Result<(), MapError> {
-        hash_map::insert(&mut self.inner, key, value, flags)
+        hash_map::insert(self.inner.as_mut(), key, value, flags)
     }
     }
 
 
     /// Removes a key from the map.
     /// Removes a key from the map.
     pub fn remove(&mut self, key: &K) -> Result<(), MapError> {
     pub fn remove(&mut self, key: &K) -> Result<(), MapError> {
-        hash_map::remove(&mut self.inner, key)
+        hash_map::remove(self.inner.as_mut(), key)
     }
     }
 }
 }
 
 
-impl<T: Deref<Target = Map>, K: Pod, V: Pod> IterableMap<K, V> for HashMap<T, K, V> {
-    fn map(&self) -> &Map {
-        &self.inner
+impl<T: AsRef<MapData>, K: Pod, V: Pod> IterableMap<K, V> for HashMap<T, K, V> {
+    fn map(&self) -> &MapData {
+        self.inner.as_ref()
     }
     }
 
 
     fn get(&self, key: &K) -> Result<V, MapError> {
     fn get(&self, key: &K) -> Result<V, MapError> {
@@ -103,38 +98,6 @@ impl<T: Deref<Target = Map>, K: Pod, V: Pod> IterableMap<K, V> for HashMap<T, K,
     }
     }
 }
 }
 
 
-impl<K: Pod, V: Pod> TryFrom<MapRef> for HashMap<MapRef, K, V> {
-    type Error = MapError;
-
-    fn try_from(a: MapRef) -> Result<HashMap<MapRef, K, V>, MapError> {
-        HashMap::new(a)
-    }
-}
-
-impl<K: Pod, V: Pod> TryFrom<MapRefMut> for HashMap<MapRefMut, K, V> {
-    type Error = MapError;
-
-    fn try_from(a: MapRefMut) -> Result<HashMap<MapRefMut, K, V>, MapError> {
-        HashMap::new(a)
-    }
-}
-
-impl<'a, K: Pod, V: Pod> TryFrom<&'a Map> for HashMap<&'a Map, K, V> {
-    type Error = MapError;
-
-    fn try_from(a: &'a Map) -> Result<HashMap<&'a Map, K, V>, MapError> {
-        HashMap::new(a)
-    }
-}
-
-impl<'a, K: Pod, V: Pod> TryFrom<&'a mut Map> for HashMap<&'a mut Map, K, V> {
-    type Error = MapError;
-
-    fn try_from(a: &'a mut Map) -> Result<HashMap<&'a mut Map, K, V>, MapError> {
-        HashMap::new(a)
-    }
-}
-
 #[cfg(test)]
 #[cfg(test)]
 mod tests {
 mod tests {
     use std::io;
     use std::io;
@@ -145,8 +108,9 @@ mod tests {
         bpf_map_def,
         bpf_map_def,
         generated::{
         generated::{
             bpf_attr, bpf_cmd,
             bpf_attr, bpf_cmd,
-            bpf_map_type::{BPF_MAP_TYPE_HASH, BPF_MAP_TYPE_PERF_EVENT_ARRAY},
+            bpf_map_type::{BPF_MAP_TYPE_HASH, BPF_MAP_TYPE_LRU_HASH},
         },
         },
+        maps::{Map, MapData},
         obj,
         obj,
         sys::{override_syscall, SysResult, Syscall},
         sys::{override_syscall, SysResult, Syscall},
     };
     };
@@ -175,7 +139,7 @@ mod tests {
 
 
     #[test]
     #[test]
     fn test_wrong_key_size() {
     fn test_wrong_key_size() {
-        let map = Map {
+        let map = MapData {
             obj: new_obj_map(),
             obj: new_obj_map(),
             fd: None,
             fd: None,
             pinned: false,
             pinned: false,
@@ -192,7 +156,7 @@ mod tests {
 
 
     #[test]
     #[test]
     fn test_wrong_value_size() {
     fn test_wrong_value_size() {
-        let map = Map {
+        let map = MapData {
             obj: new_obj_map(),
             obj: new_obj_map(),
             fd: None,
             fd: None,
             pinned: false,
             pinned: false,
@@ -209,34 +173,42 @@ mod tests {
 
 
     #[test]
     #[test]
     fn test_try_from_wrong_map() {
     fn test_try_from_wrong_map() {
-        let map = Map {
-            obj: obj::Map::Legacy(obj::LegacyMap {
-                def: bpf_map_def {
-                    map_type: BPF_MAP_TYPE_PERF_EVENT_ARRAY as u32,
-                    key_size: 4,
-                    value_size: 4,
-                    max_entries: 1024,
-                    ..Default::default()
-                },
-                section_index: 0,
-                symbol_index: 0,
-                data: Vec::new(),
-                kind: obj::MapKind::Other,
-            }),
+        let map_data = MapData {
+            obj: new_obj_map(),
+            fd: None,
+            pinned: false,
+            btf_fd: None,
+        };
+
+        let map = Map::Array(map_data);
+        assert!(matches!(
+            HashMap::<_, u8, u32>::try_from(&map),
+            Err(MapError::UnexpectedMapType)
+        ));
+    }
+
+    #[test]
+    fn test_try_from_wrong_map_values() {
+        let map_data = MapData {
+            obj: new_obj_map(),
             fd: None,
             fd: None,
             pinned: false,
             pinned: false,
             btf_fd: None,
             btf_fd: None,
         };
         };
 
 
+        let map = Map::HashMap(map_data);
         assert!(matches!(
         assert!(matches!(
-            HashMap::<_, u32, u32>::try_from(&map),
-            Err(MapError::InvalidMapType { .. })
+            HashMap::<_, u32, u16>::try_from(&map),
+            Err(MapError::InvalidValueSize {
+                size: 2,
+                expected: 4
+            })
         ));
         ));
     }
     }
 
 
     #[test]
     #[test]
     fn test_new_not_created() {
     fn test_new_not_created() {
-        let mut map = Map {
+        let mut map = MapData {
             obj: new_obj_map(),
             obj: new_obj_map(),
             fd: None,
             fd: None,
             pinned: false,
             pinned: false,
@@ -251,7 +223,7 @@ mod tests {
 
 
     #[test]
     #[test]
     fn test_new_ok() {
     fn test_new_ok() {
-        let mut map = Map {
+        let mut map = MapData {
             obj: new_obj_map(),
             obj: new_obj_map(),
             fd: Some(42),
             fd: Some(42),
             pinned: false,
             pinned: false,
@@ -263,18 +235,20 @@ mod tests {
 
 
     #[test]
     #[test]
     fn test_try_from_ok() {
     fn test_try_from_ok() {
-        let map = Map {
+        let map_data = MapData {
             obj: new_obj_map(),
             obj: new_obj_map(),
             fd: Some(42),
             fd: Some(42),
             pinned: false,
             pinned: false,
             btf_fd: None,
             btf_fd: None,
         };
         };
+
+        let map = Map::HashMap(map_data);
         assert!(HashMap::<_, u32, u32>::try_from(&map).is_ok())
         assert!(HashMap::<_, u32, u32>::try_from(&map).is_ok())
     }
     }
 
 
     #[test]
     #[test]
     fn test_try_from_ok_lru() {
     fn test_try_from_ok_lru() {
-        let map = Map {
+        let map_data = MapData {
             obj: obj::Map::Legacy(obj::LegacyMap {
             obj: obj::Map::Legacy(obj::LegacyMap {
                 def: bpf_map_def {
                 def: bpf_map_def {
                     map_type: BPF_MAP_TYPE_LRU_HASH as u32,
                     map_type: BPF_MAP_TYPE_LRU_HASH as u32,
@@ -293,6 +267,8 @@ mod tests {
             btf_fd: None,
             btf_fd: None,
         };
         };
 
 
+        let map = Map::HashMap(map_data);
+
         assert!(HashMap::<_, u32, u32>::try_from(&map).is_ok())
         assert!(HashMap::<_, u32, u32>::try_from(&map).is_ok())
     }
     }
 
 
@@ -300,7 +276,7 @@ mod tests {
     fn test_insert_syscall_error() {
     fn test_insert_syscall_error() {
         override_syscall(|_| sys_error(EFAULT));
         override_syscall(|_| sys_error(EFAULT));
 
 
-        let mut map = Map {
+        let mut map = MapData {
             obj: new_obj_map(),
             obj: new_obj_map(),
             fd: Some(42),
             fd: Some(42),
             pinned: false,
             pinned: false,
@@ -324,7 +300,7 @@ mod tests {
             _ => sys_error(EFAULT),
             _ => sys_error(EFAULT),
         });
         });
 
 
-        let mut map = Map {
+        let mut map = MapData {
             obj: new_obj_map(),
             obj: new_obj_map(),
             fd: Some(42),
             fd: Some(42),
             pinned: false,
             pinned: false,
@@ -339,7 +315,7 @@ mod tests {
     fn test_remove_syscall_error() {
     fn test_remove_syscall_error() {
         override_syscall(|_| sys_error(EFAULT));
         override_syscall(|_| sys_error(EFAULT));
 
 
-        let mut map = Map {
+        let mut map = MapData {
             obj: new_obj_map(),
             obj: new_obj_map(),
             fd: Some(42),
             fd: Some(42),
             pinned: false,
             pinned: false,
@@ -363,7 +339,7 @@ mod tests {
             _ => sys_error(EFAULT),
             _ => sys_error(EFAULT),
         });
         });
 
 
-        let mut map = Map {
+        let mut map = MapData {
             obj: new_obj_map(),
             obj: new_obj_map(),
             fd: Some(42),
             fd: Some(42),
             pinned: false,
             pinned: false,
@@ -377,7 +353,7 @@ mod tests {
     #[test]
     #[test]
     fn test_get_syscall_error() {
     fn test_get_syscall_error() {
         override_syscall(|_| sys_error(EFAULT));
         override_syscall(|_| sys_error(EFAULT));
-        let map = Map {
+        let map = MapData {
             obj: new_obj_map(),
             obj: new_obj_map(),
             fd: Some(42),
             fd: Some(42),
             pinned: false,
             pinned: false,
@@ -400,7 +376,7 @@ mod tests {
             } => sys_error(ENOENT),
             } => sys_error(ENOENT),
             _ => sys_error(EFAULT),
             _ => sys_error(EFAULT),
         });
         });
-        let map = Map {
+        let map = MapData {
             obj: new_obj_map(),
             obj: new_obj_map(),
             fd: Some(42),
             fd: Some(42),
             pinned: false,
             pinned: false,
@@ -437,7 +413,7 @@ mod tests {
             } => sys_error(ENOENT),
             } => sys_error(ENOENT),
             _ => sys_error(EFAULT),
             _ => sys_error(EFAULT),
         });
         });
-        let map = Map {
+        let map = MapData {
             obj: new_obj_map(),
             obj: new_obj_map(),
             fd: Some(42),
             fd: Some(42),
             pinned: false,
             pinned: false,
@@ -486,7 +462,7 @@ mod tests {
             _ => sys_error(EFAULT),
             _ => sys_error(EFAULT),
         });
         });
 
 
-        let map = Map {
+        let map = MapData {
             obj: new_obj_map(),
             obj: new_obj_map(),
             fd: Some(42),
             fd: Some(42),
             pinned: false,
             pinned: false,
@@ -519,7 +495,7 @@ mod tests {
             }
             }
             _ => sys_error(EFAULT),
             _ => sys_error(EFAULT),
         });
         });
-        let map = Map {
+        let map = MapData {
             obj: new_obj_map(),
             obj: new_obj_map(),
             fd: Some(42),
             fd: Some(42),
             pinned: false,
             pinned: false,
@@ -554,7 +530,7 @@ mod tests {
             } => lookup_elem(attr),
             } => lookup_elem(attr),
             _ => sys_error(EFAULT),
             _ => sys_error(EFAULT),
         });
         });
-        let map = Map {
+        let map = MapData {
             obj: new_obj_map(),
             obj: new_obj_map(),
             fd: Some(42),
             fd: Some(42),
             pinned: false,
             pinned: false,
@@ -592,7 +568,7 @@ mod tests {
             }
             }
             _ => sys_error(EFAULT),
             _ => sys_error(EFAULT),
         });
         });
-        let map = Map {
+        let map = MapData {
             obj: new_obj_map(),
             obj: new_obj_map(),
             fd: Some(42),
             fd: Some(42),
             pinned: false,
             pinned: false,
@@ -631,7 +607,7 @@ mod tests {
             } => lookup_elem(attr),
             } => lookup_elem(attr),
             _ => sys_error(EFAULT),
             _ => sys_error(EFAULT),
         });
         });
-        let map = Map {
+        let map = MapData {
             obj: new_obj_map(),
             obj: new_obj_map(),
             fd: Some(42),
             fd: Some(42),
             pinned: false,
             pinned: false,
@@ -676,7 +652,7 @@ mod tests {
             }
             }
             _ => sys_error(EFAULT),
             _ => sys_error(EFAULT),
         });
         });
-        let map = Map {
+        let map = MapData {
             obj: new_obj_map(),
             obj: new_obj_map(),
             fd: Some(42),
             fd: Some(42),
             pinned: false,
             pinned: false,

+ 11 - 4
aya/src/maps/hash_map/mod.rs

@@ -2,7 +2,7 @@
 use std::mem;
 use std::mem;
 
 
 use crate::{
 use crate::{
-    maps::{Map, MapError},
+    maps::MapError,
     sys::{bpf_map_delete_elem, bpf_map_update_elem},
     sys::{bpf_map_delete_elem, bpf_map_update_elem},
 };
 };
 
 
@@ -13,7 +13,9 @@ mod per_cpu_hash_map;
 pub use hash_map::*;
 pub use hash_map::*;
 pub use per_cpu_hash_map::*;
 pub use per_cpu_hash_map::*;
 
 
-pub(crate) fn check_kv_size<K, V>(map: &Map) -> Result<(), MapError> {
+use super::MapData;
+
+pub(crate) fn check_kv_size<K, V>(map: &MapData) -> Result<(), MapError> {
     let size = mem::size_of::<K>();
     let size = mem::size_of::<K>();
     let expected = map.obj.key_size() as usize;
     let expected = map.obj.key_size() as usize;
     if size != expected {
     if size != expected {
@@ -27,7 +29,12 @@ pub(crate) fn check_kv_size<K, V>(map: &Map) -> Result<(), MapError> {
     Ok(())
     Ok(())
 }
 }
 
 
-pub(crate) fn insert<K, V>(map: &mut Map, key: K, value: V, flags: u64) -> Result<(), MapError> {
+pub(crate) fn insert<K, V>(
+    map: &mut MapData,
+    key: K,
+    value: V,
+    flags: u64,
+) -> Result<(), MapError> {
     let fd = map.fd_or_err()?;
     let fd = map.fd_or_err()?;
     bpf_map_update_elem(fd, Some(&key), &value, flags).map_err(|(_, io_error)| {
     bpf_map_update_elem(fd, Some(&key), &value, flags).map_err(|(_, io_error)| {
         MapError::SyscallError {
         MapError::SyscallError {
@@ -39,7 +46,7 @@ pub(crate) fn insert<K, V>(map: &mut Map, key: K, value: V, flags: u64) -> Resul
     Ok(())
     Ok(())
 }
 }
 
 
-pub(crate) fn remove<K>(map: &mut Map, key: &K) -> Result<(), MapError> {
+pub(crate) fn remove<K>(map: &mut MapData, key: &K) -> Result<(), MapError> {
     let fd = map.fd_or_err()?;
     let fd = map.fd_or_err()?;
     bpf_map_delete_elem(fd, key)
     bpf_map_delete_elem(fd, key)
         .map(|_| ())
         .map(|_| ())

+ 18 - 53
aya/src/maps/hash_map/per_cpu_hash_map.rs

@@ -1,14 +1,12 @@
 //! Per-CPU hash map.
 //! Per-CPU hash map.
 use std::{
 use std::{
+    convert::{AsMut, AsRef},
     marker::PhantomData,
     marker::PhantomData,
-    ops::{Deref, DerefMut},
 };
 };
 
 
 use crate::{
 use crate::{
     generated::bpf_map_type::{BPF_MAP_TYPE_LRU_PERCPU_HASH, BPF_MAP_TYPE_PERCPU_HASH},
     generated::bpf_map_type::{BPF_MAP_TYPE_LRU_PERCPU_HASH, BPF_MAP_TYPE_PERCPU_HASH},
-    maps::{
-        hash_map, IterableMap, Map, MapError, MapIter, MapKeys, MapRef, MapRefMut, PerCpuValues,
-    },
+    maps::{hash_map, IterableMap, MapData, MapError, MapIter, MapKeys, PerCpuValues},
     sys::{bpf_map_lookup_elem_per_cpu, bpf_map_update_elem_per_cpu},
     sys::{bpf_map_lookup_elem_per_cpu, bpf_map_update_elem_per_cpu},
     Pod,
     Pod,
 };
 };
@@ -42,15 +40,16 @@ use crate::{
 /// ```
 /// ```
 #[doc(alias = "BPF_MAP_TYPE_LRU_PERCPU_HASH")]
 #[doc(alias = "BPF_MAP_TYPE_LRU_PERCPU_HASH")]
 #[doc(alias = "BPF_MAP_TYPE_PERCPU_HASH")]
 #[doc(alias = "BPF_MAP_TYPE_PERCPU_HASH")]
-pub struct PerCpuHashMap<T: Deref<Target = Map>, K: Pod, V: Pod> {
+pub struct PerCpuHashMap<T, K: Pod, V: Pod> {
     inner: T,
     inner: T,
     _k: PhantomData<K>,
     _k: PhantomData<K>,
     _v: PhantomData<V>,
     _v: PhantomData<V>,
 }
 }
 
 
-impl<T: Deref<Target = Map>, K: Pod, V: Pod> PerCpuHashMap<T, K, V> {
+impl<T: AsRef<MapData>, K: Pod, V: Pod> PerCpuHashMap<T, K, V> {
     pub(crate) fn new(map: T) -> Result<PerCpuHashMap<T, K, V>, MapError> {
     pub(crate) fn new(map: T) -> Result<PerCpuHashMap<T, K, V>, MapError> {
-        let map_type = map.obj.map_type();
+        let data = map.as_ref();
+        let map_type = data.obj.map_type();
 
 
         // validate the map definition
         // validate the map definition
         if map_type != BPF_MAP_TYPE_PERCPU_HASH as u32
         if map_type != BPF_MAP_TYPE_PERCPU_HASH as u32
@@ -58,8 +57,8 @@ impl<T: Deref<Target = Map>, K: Pod, V: Pod> PerCpuHashMap<T, K, V> {
         {
         {
             return Err(MapError::InvalidMapType { map_type });
             return Err(MapError::InvalidMapType { map_type });
         }
         }
-        hash_map::check_kv_size::<K, V>(&map)?;
-        let _ = map.fd_or_err()?;
+        hash_map::check_kv_size::<K, V>(data)?;
+        let _ = data.fd_or_err()?;
 
 
         Ok(PerCpuHashMap {
         Ok(PerCpuHashMap {
             inner: map,
             inner: map,
@@ -70,7 +69,7 @@ impl<T: Deref<Target = Map>, K: Pod, V: Pod> PerCpuHashMap<T, K, V> {
 
 
     /// Returns a slice of values - one for each CPU - associated with the key.
     /// Returns a slice of values - one for each CPU - associated with the key.
     pub fn get(&self, key: &K, flags: u64) -> Result<PerCpuValues<V>, MapError> {
     pub fn get(&self, key: &K, flags: u64) -> Result<PerCpuValues<V>, MapError> {
-        let fd = self.inner.deref().fd_or_err()?;
+        let fd = self.inner.as_ref().fd_or_err()?;
         let values = bpf_map_lookup_elem_per_cpu(fd, key, flags).map_err(|(_, io_error)| {
         let values = bpf_map_lookup_elem_per_cpu(fd, key, flags).map_err(|(_, io_error)| {
             MapError::SyscallError {
             MapError::SyscallError {
                 call: "bpf_map_lookup_elem".to_owned(),
                 call: "bpf_map_lookup_elem".to_owned(),
@@ -89,11 +88,11 @@ impl<T: Deref<Target = Map>, K: Pod, V: Pod> PerCpuHashMap<T, K, V> {
     /// An iterator visiting all keys in arbitrary order. The iterator element
     /// An iterator visiting all keys in arbitrary order. The iterator element
     /// type is `Result<K, MapError>`.
     /// type is `Result<K, MapError>`.
     pub fn keys(&self) -> MapKeys<'_, K> {
     pub fn keys(&self) -> MapKeys<'_, K> {
-        MapKeys::new(&self.inner)
+        MapKeys::new(self.inner.as_ref())
     }
     }
 }
 }
 
 
-impl<T: DerefMut<Target = Map>, K: Pod, V: Pod> PerCpuHashMap<T, K, V> {
+impl<T: AsMut<MapData>, K: Pod, V: Pod> PerCpuHashMap<T, K, V> {
     /// Inserts a slice of values - one for each CPU - for the given key.
     /// Inserts a slice of values - one for each CPU - for the given key.
     ///
     ///
     /// # Examples
     /// # Examples
@@ -108,13 +107,13 @@ impl<T: DerefMut<Target = Map>, K: Pod, V: Pod> PerCpuHashMap<T, K, V> {
     /// #     #[error(transparent)]
     /// #     #[error(transparent)]
     /// #     Bpf(#[from] aya::BpfError)
     /// #     Bpf(#[from] aya::BpfError)
     /// # }
     /// # }
-    /// # let bpf = aya::Bpf::load(&[])?;
+    /// # let mut bpf = aya::Bpf::load(&[])?;
     /// use aya::maps::{PerCpuHashMap, PerCpuValues};
     /// use aya::maps::{PerCpuHashMap, PerCpuValues};
     /// use aya::util::nr_cpus;
     /// use aya::util::nr_cpus;
     ///
     ///
     /// const RETRIES: u8 = 1;
     /// const RETRIES: u8 = 1;
     ///
     ///
-    /// let mut hm = PerCpuHashMap::<_, u8, u32>::try_from(bpf.map_mut("PER_CPU_STORAGE")?)?;
+    /// let mut hm: PerCpuHashMap::<_, u8, u32> = bpf.map_mut("PER_CPU_STORAGE")?.try_into()?;
     /// hm.insert(
     /// hm.insert(
     ///     RETRIES,
     ///     RETRIES,
     ///     PerCpuValues::try_from(vec![3u32; nr_cpus()?])?,
     ///     PerCpuValues::try_from(vec![3u32; nr_cpus()?])?,
@@ -123,7 +122,7 @@ impl<T: DerefMut<Target = Map>, K: Pod, V: Pod> PerCpuHashMap<T, K, V> {
     /// # Ok::<(), Error>(())
     /// # Ok::<(), Error>(())
     /// ```
     /// ```
     pub fn insert(&mut self, key: K, values: PerCpuValues<V>, flags: u64) -> Result<(), MapError> {
     pub fn insert(&mut self, key: K, values: PerCpuValues<V>, flags: u64) -> Result<(), MapError> {
-        let fd = self.inner.fd_or_err()?;
+        let fd = self.inner.as_mut().fd_or_err()?;
         bpf_map_update_elem_per_cpu(fd, &key, &values, flags).map_err(|(_, io_error)| {
         bpf_map_update_elem_per_cpu(fd, &key, &values, flags).map_err(|(_, io_error)| {
             MapError::SyscallError {
             MapError::SyscallError {
                 call: "bpf_map_update_elem".to_owned(),
                 call: "bpf_map_update_elem".to_owned(),
@@ -136,50 +135,16 @@ impl<T: DerefMut<Target = Map>, K: Pod, V: Pod> PerCpuHashMap<T, K, V> {
 
 
     /// Removes a key from the map.
     /// Removes a key from the map.
     pub fn remove(&mut self, key: &K) -> Result<(), MapError> {
     pub fn remove(&mut self, key: &K) -> Result<(), MapError> {
-        hash_map::remove(&mut self.inner, key)
+        hash_map::remove(self.inner.as_mut(), key)
     }
     }
 }
 }
 
 
-impl<T: Deref<Target = Map>, K: Pod, V: Pod> IterableMap<K, PerCpuValues<V>>
-    for PerCpuHashMap<T, K, V>
-{
-    fn map(&self) -> &Map {
-        &self.inner
+impl<T: AsRef<MapData>, K: Pod, V: Pod> IterableMap<K, PerCpuValues<V>> for PerCpuHashMap<T, K, V> {
+    fn map(&self) -> &MapData {
+        self.inner.as_ref()
     }
     }
 
 
     fn get(&self, key: &K) -> Result<PerCpuValues<V>, MapError> {
     fn get(&self, key: &K) -> Result<PerCpuValues<V>, MapError> {
         PerCpuHashMap::get(self, key, 0)
         PerCpuHashMap::get(self, key, 0)
     }
     }
 }
 }
-
-impl<K: Pod, V: Pod> TryFrom<MapRef> for PerCpuHashMap<MapRef, K, V> {
-    type Error = MapError;
-
-    fn try_from(a: MapRef) -> Result<PerCpuHashMap<MapRef, K, V>, MapError> {
-        PerCpuHashMap::new(a)
-    }
-}
-
-impl<K: Pod, V: Pod> TryFrom<MapRefMut> for PerCpuHashMap<MapRefMut, K, V> {
-    type Error = MapError;
-
-    fn try_from(a: MapRefMut) -> Result<PerCpuHashMap<MapRefMut, K, V>, MapError> {
-        PerCpuHashMap::new(a)
-    }
-}
-
-impl<'a, K: Pod, V: Pod> TryFrom<&'a Map> for PerCpuHashMap<&'a Map, K, V> {
-    type Error = MapError;
-
-    fn try_from(a: &'a Map) -> Result<PerCpuHashMap<&'a Map, K, V>, MapError> {
-        PerCpuHashMap::new(a)
-    }
-}
-
-impl<'a, K: Pod, V: Pod> TryFrom<&'a mut Map> for PerCpuHashMap<&'a mut Map, K, V> {
-    type Error = MapError;
-
-    fn try_from(a: &'a mut Map) -> Result<PerCpuHashMap<&'a mut Map, K, V>, MapError> {
-        PerCpuHashMap::new(a)
-    }
-}

+ 46 - 73
aya/src/maps/lpm_trie.rs

@@ -1,9 +1,12 @@
 //! A LPM Trie.
 //! A LPM Trie.
-use std::{marker::PhantomData, mem, ops::Deref};
+use std::{
+    convert::{AsMut, AsRef},
+    marker::PhantomData,
+    mem,
+};
 
 
 use crate::{
 use crate::{
-    generated::bpf_map_type::BPF_MAP_TYPE_LPM_TRIE,
-    maps::{IterableMap, Map, MapError, MapRef, MapRefMut},
+    maps::{IterableMap, MapData, MapError},
     sys::{bpf_map_delete_elem, bpf_map_lookup_elem, bpf_map_update_elem},
     sys::{bpf_map_delete_elem, bpf_map_lookup_elem, bpf_map_update_elem},
     Pod,
     Pod,
 };
 };
@@ -17,11 +20,11 @@ use crate::{
 /// # Examples
 /// # Examples
 ///
 ///
 /// ```no_run
 /// ```no_run
-/// # let bpf = aya::Bpf::load(&[])?;
+/// # let mut bpf = aya::Bpf::load(&[])?;
 /// use aya::maps::lpm_trie::{LpmTrie, Key};
 /// use aya::maps::lpm_trie::{LpmTrie, Key};
 /// use std::net::Ipv4Addr;
 /// use std::net::Ipv4Addr;
 ///
 ///
-/// let mut trie = LpmTrie::try_from(bpf.map_mut("LPM_TRIE")?)?;
+/// let mut trie: LpmTrie<_,u32,u32> = bpf.map_mut("LPM_TRIE")?.try_into()?;
 /// let ipaddr = Ipv4Addr::new(8, 8, 8, 8);
 /// let ipaddr = Ipv4Addr::new(8, 8, 8, 8);
 /// // The following represents a key for the "8.8.8.8/16" subnet.
 /// // The following represents a key for the "8.8.8.8/16" subnet.
 /// // The first argument - the prefix length - represents how many bytes should be matched against. The second argument is the actual data to be matched.
 /// // The first argument - the prefix length - represents how many bytes should be matched against. The second argument is the actual data to be matched.
@@ -43,7 +46,7 @@ use crate::{
 /// ```
 /// ```
 
 
 #[doc(alias = "BPF_MAP_TYPE_LPM_TRIE")]
 #[doc(alias = "BPF_MAP_TYPE_LPM_TRIE")]
-pub struct LpmTrie<T: Deref<Target = Map>, K, V> {
+pub struct LpmTrie<T, K, V> {
     inner: T,
     inner: T,
     _k: PhantomData<K>,
     _k: PhantomData<K>,
     _v: PhantomData<V>,
     _v: PhantomData<V>,
@@ -96,26 +99,21 @@ impl<K: Pod> Clone for Key<K> {
 // A Pod impl is required as Key struct is a key for a map.
 // A Pod impl is required as Key struct is a key for a map.
 unsafe impl<K: Pod> Pod for Key<K> {}
 unsafe impl<K: Pod> Pod for Key<K> {}
 
 
-impl<T: Deref<Target = Map>, K: Pod, V: Pod> LpmTrie<T, K, V> {
+impl<T: AsRef<MapData>, K: Pod, V: Pod> LpmTrie<T, K, V> {
     pub(crate) fn new(map: T) -> Result<LpmTrie<T, K, V>, MapError> {
     pub(crate) fn new(map: T) -> Result<LpmTrie<T, K, V>, MapError> {
-        let map_type = map.obj.map_type();
-
-        // validate the map definition
-        if map_type != BPF_MAP_TYPE_LPM_TRIE as u32 {
-            return Err(MapError::InvalidMapType { map_type });
-        }
+        let data = map.as_ref();
         let size = mem::size_of::<Key<K>>();
         let size = mem::size_of::<Key<K>>();
-        let expected = map.obj.key_size() as usize;
+        let expected = data.obj.key_size() as usize;
         if size != expected {
         if size != expected {
             return Err(MapError::InvalidKeySize { size, expected });
             return Err(MapError::InvalidKeySize { size, expected });
         }
         }
         let size = mem::size_of::<V>();
         let size = mem::size_of::<V>();
-        let expected = map.obj.value_size() as usize;
+        let expected = data.obj.value_size() as usize;
         if size != expected {
         if size != expected {
             return Err(MapError::InvalidValueSize { size, expected });
             return Err(MapError::InvalidValueSize { size, expected });
         };
         };
 
 
-        let _ = map.fd_or_err()?;
+        let _ = data.fd_or_err()?;
 
 
         Ok(LpmTrie {
         Ok(LpmTrie {
             inner: map,
             inner: map,
@@ -126,7 +124,7 @@ impl<T: Deref<Target = Map>, K: Pod, V: Pod> LpmTrie<T, K, V> {
 
 
     /// Returns a copy of the value associated with the longest prefix matching key in the LpmTrie.
     /// Returns a copy of the value associated with the longest prefix matching key in the LpmTrie.
     pub fn get(&self, key: &Key<K>, flags: u64) -> Result<V, MapError> {
     pub fn get(&self, key: &Key<K>, flags: u64) -> Result<V, MapError> {
-        let fd = self.inner.deref().fd_or_err()?;
+        let fd = self.inner.as_ref().fd_or_err()?;
         let value = bpf_map_lookup_elem(fd, key, flags).map_err(|(_, io_error)| {
         let value = bpf_map_lookup_elem(fd, key, flags).map_err(|(_, io_error)| {
             MapError::SyscallError {
             MapError::SyscallError {
                 call: "bpf_map_lookup_elem".to_owned(),
                 call: "bpf_map_lookup_elem".to_owned(),
@@ -135,10 +133,12 @@ impl<T: Deref<Target = Map>, K: Pod, V: Pod> LpmTrie<T, K, V> {
         })?;
         })?;
         value.ok_or(MapError::KeyNotFound)
         value.ok_or(MapError::KeyNotFound)
     }
     }
+}
 
 
+impl<T: AsMut<MapData>, K: Pod, V: Pod> LpmTrie<T, K, V> {
     /// Inserts a key value pair into the map.
     /// Inserts a key value pair into the map.
-    pub fn insert(&self, key: &Key<K>, value: V, flags: u64) -> Result<(), MapError> {
-        let fd = self.inner.deref().fd_or_err()?;
+    pub fn insert(&mut self, key: &Key<K>, value: V, flags: u64) -> Result<(), MapError> {
+        let fd = self.inner.as_mut().fd_or_err()?;
         bpf_map_update_elem(fd, Some(key), &value, flags).map_err(|(_, io_error)| {
         bpf_map_update_elem(fd, Some(key), &value, flags).map_err(|(_, io_error)| {
             MapError::SyscallError {
             MapError::SyscallError {
                 call: "bpf_map_update_elem".to_owned(),
                 call: "bpf_map_update_elem".to_owned(),
@@ -152,8 +152,8 @@ impl<T: Deref<Target = Map>, K: Pod, V: Pod> LpmTrie<T, K, V> {
     /// Removes an element from the map.
     /// Removes an element from the map.
     ///
     ///
     /// Both the prefix and data must match exactly - this method does not do a longest prefix match.
     /// Both the prefix and data must match exactly - this method does not do a longest prefix match.
-    pub fn remove(&self, key: &Key<K>) -> Result<(), MapError> {
-        let fd = self.inner.deref().fd_or_err()?;
+    pub fn remove(&mut self, key: &Key<K>) -> Result<(), MapError> {
+        let fd = self.inner.as_mut().fd_or_err()?;
         bpf_map_delete_elem(fd, key)
         bpf_map_delete_elem(fd, key)
             .map(|_| ())
             .map(|_| ())
             .map_err(|(_, io_error)| MapError::SyscallError {
             .map_err(|(_, io_error)| MapError::SyscallError {
@@ -163,9 +163,9 @@ impl<T: Deref<Target = Map>, K: Pod, V: Pod> LpmTrie<T, K, V> {
     }
     }
 }
 }
 
 
-impl<T: Deref<Target = Map>, K: Pod, V: Pod> IterableMap<K, V> for LpmTrie<T, K, V> {
-    fn map(&self) -> &Map {
-        &self.inner
+impl<T: AsRef<MapData>, K: Pod, V: Pod> IterableMap<K, V> for LpmTrie<T, K, V> {
+    fn map(&self) -> &MapData {
+        self.inner.as_ref()
     }
     }
 
 
     fn get(&self, key: &K) -> Result<V, MapError> {
     fn get(&self, key: &K) -> Result<V, MapError> {
@@ -174,38 +174,6 @@ impl<T: Deref<Target = Map>, K: Pod, V: Pod> IterableMap<K, V> for LpmTrie<T, K,
     }
     }
 }
 }
 
 
-impl<K: Pod, V: Pod> TryFrom<MapRef> for LpmTrie<MapRef, K, V> {
-    type Error = MapError;
-
-    fn try_from(a: MapRef) -> Result<LpmTrie<MapRef, K, V>, MapError> {
-        LpmTrie::new(a)
-    }
-}
-
-impl<K: Pod, V: Pod> TryFrom<MapRefMut> for LpmTrie<MapRefMut, K, V> {
-    type Error = MapError;
-
-    fn try_from(a: MapRefMut) -> Result<LpmTrie<MapRefMut, K, V>, MapError> {
-        LpmTrie::new(a)
-    }
-}
-
-impl<'a, K: Pod, V: Pod> TryFrom<&'a Map> for LpmTrie<&'a Map, K, V> {
-    type Error = MapError;
-
-    fn try_from(a: &'a Map) -> Result<LpmTrie<&'a Map, K, V>, MapError> {
-        LpmTrie::new(a)
-    }
-}
-
-impl<'a, K: Pod, V: Pod> TryFrom<&'a mut Map> for LpmTrie<&'a mut Map, K, V> {
-    type Error = MapError;
-
-    fn try_from(a: &'a mut Map) -> Result<LpmTrie<&'a mut Map, K, V>, MapError> {
-        LpmTrie::new(a)
-    }
-}
-
 #[cfg(test)]
 #[cfg(test)]
 mod tests {
 mod tests {
     use super::*;
     use super::*;
@@ -215,6 +183,7 @@ mod tests {
             bpf_cmd,
             bpf_cmd,
             bpf_map_type::{BPF_MAP_TYPE_LPM_TRIE, BPF_MAP_TYPE_PERF_EVENT_ARRAY},
             bpf_map_type::{BPF_MAP_TYPE_LPM_TRIE, BPF_MAP_TYPE_PERF_EVENT_ARRAY},
         },
         },
+        maps::{Map, MapData},
         obj,
         obj,
         sys::{override_syscall, SysResult, Syscall},
         sys::{override_syscall, SysResult, Syscall},
     };
     };
@@ -243,7 +212,7 @@ mod tests {
 
 
     #[test]
     #[test]
     fn test_wrong_key_size() {
     fn test_wrong_key_size() {
-        let map = Map {
+        let map = MapData {
             obj: new_obj_map(),
             obj: new_obj_map(),
             fd: None,
             fd: None,
             pinned: false,
             pinned: false,
@@ -260,7 +229,7 @@ mod tests {
 
 
     #[test]
     #[test]
     fn test_wrong_value_size() {
     fn test_wrong_value_size() {
-        let map = Map {
+        let map = MapData {
             obj: new_obj_map(),
             obj: new_obj_map(),
             fd: None,
             fd: None,
             pinned: false,
             pinned: false,
@@ -277,7 +246,7 @@ mod tests {
 
 
     #[test]
     #[test]
     fn test_try_from_wrong_map() {
     fn test_try_from_wrong_map() {
-        let map = Map {
+        let map_data = MapData {
             obj: obj::Map::Legacy(obj::LegacyMap {
             obj: obj::Map::Legacy(obj::LegacyMap {
                 def: bpf_map_def {
                 def: bpf_map_def {
                     map_type: BPF_MAP_TYPE_PERF_EVENT_ARRAY as u32,
                     map_type: BPF_MAP_TYPE_PERF_EVENT_ARRAY as u32,
@@ -296,15 +265,17 @@ mod tests {
             pinned: false,
             pinned: false,
         };
         };
 
 
+        let map = Map::PerfEventArray(map_data);
+
         assert!(matches!(
         assert!(matches!(
             LpmTrie::<_, u32, u32>::try_from(&map),
             LpmTrie::<_, u32, u32>::try_from(&map),
-            Err(MapError::InvalidMapType { .. })
+            Err(MapError::UnexpectedMapType)
         ));
         ));
     }
     }
 
 
     #[test]
     #[test]
     fn test_new_not_created() {
     fn test_new_not_created() {
-        let mut map = Map {
+        let mut map = MapData {
             obj: new_obj_map(),
             obj: new_obj_map(),
             fd: None,
             fd: None,
             pinned: false,
             pinned: false,
@@ -319,7 +290,7 @@ mod tests {
 
 
     #[test]
     #[test]
     fn test_new_ok() {
     fn test_new_ok() {
-        let mut map = Map {
+        let mut map = MapData {
             obj: new_obj_map(),
             obj: new_obj_map(),
             fd: Some(42),
             fd: Some(42),
             pinned: false,
             pinned: false,
@@ -331,12 +302,14 @@ mod tests {
 
 
     #[test]
     #[test]
     fn test_try_from_ok() {
     fn test_try_from_ok() {
-        let map = Map {
+        let map_data = MapData {
             obj: new_obj_map(),
             obj: new_obj_map(),
             fd: Some(42),
             fd: Some(42),
             pinned: false,
             pinned: false,
             btf_fd: None,
             btf_fd: None,
         };
         };
+
+        let map = Map::LpmTrie(map_data);
         assert!(LpmTrie::<_, u32, u32>::try_from(&map).is_ok())
         assert!(LpmTrie::<_, u32, u32>::try_from(&map).is_ok())
     }
     }
 
 
@@ -344,13 +317,13 @@ mod tests {
     fn test_insert_syscall_error() {
     fn test_insert_syscall_error() {
         override_syscall(|_| sys_error(EFAULT));
         override_syscall(|_| sys_error(EFAULT));
 
 
-        let mut map = Map {
+        let mut map = MapData {
             obj: new_obj_map(),
             obj: new_obj_map(),
             fd: Some(42),
             fd: Some(42),
             pinned: false,
             pinned: false,
             btf_fd: None,
             btf_fd: None,
         };
         };
-        let trie = LpmTrie::<_, u32, u32>::new(&mut map).unwrap();
+        let mut trie = LpmTrie::<_, u32, u32>::new(&mut map).unwrap();
         let ipaddr = Ipv4Addr::new(8, 8, 8, 8);
         let ipaddr = Ipv4Addr::new(8, 8, 8, 8);
         let key = Key::new(16, u32::from(ipaddr).to_be());
         let key = Key::new(16, u32::from(ipaddr).to_be());
         assert!(matches!(
         assert!(matches!(
@@ -369,14 +342,14 @@ mod tests {
             _ => sys_error(EFAULT),
             _ => sys_error(EFAULT),
         });
         });
 
 
-        let mut map = Map {
+        let mut map = MapData {
             obj: new_obj_map(),
             obj: new_obj_map(),
             fd: Some(42),
             fd: Some(42),
             pinned: false,
             pinned: false,
             btf_fd: None,
             btf_fd: None,
         };
         };
 
 
-        let trie = LpmTrie::<_, u32, u32>::new(&mut map).unwrap();
+        let mut trie = LpmTrie::<_, u32, u32>::new(&mut map).unwrap();
         let ipaddr = Ipv4Addr::new(8, 8, 8, 8);
         let ipaddr = Ipv4Addr::new(8, 8, 8, 8);
         let key = Key::new(16, u32::from(ipaddr).to_be());
         let key = Key::new(16, u32::from(ipaddr).to_be());
         assert!(trie.insert(&key, 1, 0).is_ok());
         assert!(trie.insert(&key, 1, 0).is_ok());
@@ -386,13 +359,13 @@ mod tests {
     fn test_remove_syscall_error() {
     fn test_remove_syscall_error() {
         override_syscall(|_| sys_error(EFAULT));
         override_syscall(|_| sys_error(EFAULT));
 
 
-        let mut map = Map {
+        let mut map = MapData {
             obj: new_obj_map(),
             obj: new_obj_map(),
             fd: Some(42),
             fd: Some(42),
             pinned: false,
             pinned: false,
             btf_fd: None,
             btf_fd: None,
         };
         };
-        let trie = LpmTrie::<_, u32, u32>::new(&mut map).unwrap();
+        let mut trie = LpmTrie::<_, u32, u32>::new(&mut map).unwrap();
         let ipaddr = Ipv4Addr::new(8, 8, 8, 8);
         let ipaddr = Ipv4Addr::new(8, 8, 8, 8);
         let key = Key::new(16, u32::from(ipaddr).to_be());
         let key = Key::new(16, u32::from(ipaddr).to_be());
         assert!(matches!(
         assert!(matches!(
@@ -411,13 +384,13 @@ mod tests {
             _ => sys_error(EFAULT),
             _ => sys_error(EFAULT),
         });
         });
 
 
-        let mut map = Map {
+        let mut map = MapData {
             obj: new_obj_map(),
             obj: new_obj_map(),
             fd: Some(42),
             fd: Some(42),
             pinned: false,
             pinned: false,
             btf_fd: None,
             btf_fd: None,
         };
         };
-        let trie = LpmTrie::<_, u32, u32>::new(&mut map).unwrap();
+        let mut trie = LpmTrie::<_, u32, u32>::new(&mut map).unwrap();
         let ipaddr = Ipv4Addr::new(8, 8, 8, 8);
         let ipaddr = Ipv4Addr::new(8, 8, 8, 8);
         let key = Key::new(16, u32::from(ipaddr).to_be());
         let key = Key::new(16, u32::from(ipaddr).to_be());
         assert!(trie.remove(&key).is_ok());
         assert!(trie.remove(&key).is_ok());
@@ -426,7 +399,7 @@ mod tests {
     #[test]
     #[test]
     fn test_get_syscall_error() {
     fn test_get_syscall_error() {
         override_syscall(|_| sys_error(EFAULT));
         override_syscall(|_| sys_error(EFAULT));
-        let map = Map {
+        let map = MapData {
             obj: new_obj_map(),
             obj: new_obj_map(),
             fd: Some(42),
             fd: Some(42),
             pinned: false,
             pinned: false,
@@ -451,7 +424,7 @@ mod tests {
             } => sys_error(ENOENT),
             } => sys_error(ENOENT),
             _ => sys_error(EFAULT),
             _ => sys_error(EFAULT),
         });
         });
-        let map = Map {
+        let map = MapData {
             obj: new_obj_map(),
             obj: new_obj_map(),
             fd: Some(42),
             fd: Some(42),
             pinned: false,
             pinned: false,

+ 0 - 81
aya/src/maps/map_lock.rs

@@ -1,81 +0,0 @@
-use parking_lot::{RwLock, RwLockReadGuard, RwLockWriteGuard};
-use std::{
-    mem,
-    ops::{Deref, DerefMut},
-    sync::Arc,
-};
-
-use crate::maps::Map;
-
-pub(crate) struct MapLockError;
-
-/* FIXME: write a full RwLock implementation that doesn't use borrowing guards
- * so that try_read() and try_write() don't have to use the ugly lifetime
- * extension hack */
-
-#[derive(Debug)]
-pub(crate) struct MapLock {
-    inner: Arc<RwLock<Map>>,
-}
-
-impl MapLock {
-    pub(crate) fn new(map: Map) -> MapLock {
-        MapLock {
-            inner: Arc::new(RwLock::new(map)),
-        }
-    }
-
-    pub(crate) fn try_read(&self) -> Result<MapRef, MapLockError> {
-        let lock: Option<RwLockReadGuard<'static, Map>> =
-            unsafe { mem::transmute(self.inner.try_read()) };
-        lock.map(|guard| MapRef {
-            _lock: self.inner.clone(),
-            guard,
-        })
-        .ok_or(MapLockError)
-    }
-
-    pub(crate) fn try_write(&self) -> Result<MapRefMut, MapLockError> {
-        let lock: Option<RwLockWriteGuard<'static, Map>> =
-            unsafe { mem::transmute(self.inner.try_write()) };
-        lock.map(|guard| MapRefMut {
-            _lock: self.inner.clone(),
-            guard,
-        })
-        .ok_or(MapLockError)
-    }
-}
-
-/// A borrowed reference to a BPF map.
-pub struct MapRef {
-    _lock: Arc<RwLock<Map>>,
-    guard: RwLockReadGuard<'static, Map>,
-}
-
-/// A mutable borrowed reference to a BPF map.
-pub struct MapRefMut {
-    _lock: Arc<RwLock<Map>>,
-    guard: RwLockWriteGuard<'static, Map>,
-}
-
-impl Deref for MapRef {
-    type Target = Map;
-
-    fn deref(&self) -> &Map {
-        &self.guard
-    }
-}
-
-impl Deref for MapRefMut {
-    type Target = Map;
-
-    fn deref(&self) -> &Map {
-        &self.guard
-    }
-}
-
-impl DerefMut for MapRefMut {
-    fn deref_mut(&mut self) -> &mut Map {
-        &mut self.guard
-    }
-}

+ 214 - 36
aya/src/maps/mod.rs

@@ -4,22 +4,25 @@
 //! used to setup and share data with eBPF programs. When you call
 //! used to setup and share data with eBPF programs. When you call
 //! [`Bpf::load_file`](crate::Bpf::load_file) or
 //! [`Bpf::load_file`](crate::Bpf::load_file) or
 //! [`Bpf::load`](crate::Bpf::load), all the maps defined in the eBPF code get
 //! [`Bpf::load`](crate::Bpf::load), all the maps defined in the eBPF code get
-//! initialized and can then be accessed using [`Bpf::map`](crate::Bpf::map) and
-//! [`Bpf::map_mut`](crate::Bpf::map_mut).
+//! initialized and can then be accessed using [`Bpf::map`](crate::Bpf::map),
+//! [`Bpf::map_mut`](crate::Bpf::map_mut), [`Bpf::take_map`](crate::Bpf::map)
+//! or [`Bpf::map_mut`](crate::Bpf::take_map).
 //!
 //!
 //! # Typed maps
 //! # Typed maps
 //!
 //!
 //! The eBPF API includes many map types each supporting different operations.
 //! The eBPF API includes many map types each supporting different operations.
-//! [`Bpf::map`](crate::Bpf::map) and [`Bpf::map_mut`](crate::Bpf::map_mut) always return the
-//! opaque [`MapRef`] and [`MapRefMut`] types respectively. Those two types can be converted to
-//! *typed maps* using the [`TryFrom`](std::convert::TryFrom) trait. For example:
+//! [`Bpf::map`](crate::Bpf::map), [`Bpf::map_mut`](crate::Bpf::map_mut), and
+//! [`Bpf::map_mut`](crate::Bpf::take_map) always return the
+//! opaque [`&Map`], [`&mut Map`], and [`Map`] types respectively. Those three types can be converted to
+//! *typed maps* using the [`TryFrom`](std::convert::TryFrom) or [`TryInto`](std::convert::TryInto)
+//! trait. For example:
 //!
 //!
 //! ```no_run
 //! ```no_run
 //! # let mut bpf = aya::Bpf::load(&[])?;
 //! # let mut bpf = aya::Bpf::load(&[])?;
 //! use aya::maps::SockMap;
 //! use aya::maps::SockMap;
 //! use aya::programs::SkMsg;
 //! use aya::programs::SkMsg;
 //!
 //!
-//! let intercept_egress = SockMap::try_from(bpf.map_mut("INTERCEPT_EGRESS")?)?;
+//! let intercept_egress: SockMap<_> = bpf.take_map("INTERCEPT_EGRESS")?.try_into()?;
 //! let prog: &mut SkMsg = bpf.program_mut("intercept_egress_packet").unwrap().try_into()?;
 //! let prog: &mut SkMsg = bpf.program_mut("intercept_egress_packet").unwrap().try_into()?;
 //! prog.load()?;
 //! prog.load()?;
 //! prog.attach(&intercept_egress)?;
 //! prog.attach(&intercept_egress)?;
@@ -32,6 +35,7 @@
 //! versa. Because of that, all map values must be plain old data and therefore
 //! versa. Because of that, all map values must be plain old data and therefore
 //! implement the [Pod] trait.
 //! implement the [Pod] trait.
 use std::{
 use std::{
+    convert::{AsMut, AsRef},
     ffi::CString,
     ffi::CString,
     fmt, io,
     fmt, io,
     marker::PhantomData,
     marker::PhantomData,
@@ -58,8 +62,6 @@ use crate::{
     PinningType, Pod,
     PinningType, Pod,
 };
 };
 
 
-mod map_lock;
-
 pub mod array;
 pub mod array;
 pub mod bloom_filter;
 pub mod bloom_filter;
 pub mod hash_map;
 pub mod hash_map;
@@ -71,8 +73,11 @@ pub mod stack;
 pub mod stack_trace;
 pub mod stack_trace;
 
 
 pub use array::{Array, PerCpuArray, ProgramArray};
 pub use array::{Array, PerCpuArray, ProgramArray};
+pub use bloom_filter::BloomFilter;
 pub use hash_map::{HashMap, PerCpuHashMap};
 pub use hash_map::{HashMap, PerCpuHashMap};
-pub use map_lock::*;
+pub use lpm_trie::LpmTrie;
+#[cfg(any(feature = "async", doc))]
+pub use perf::AsyncPerfEventArray;
 pub use perf::PerfEventArray;
 pub use perf::PerfEventArray;
 pub use queue::Queue;
 pub use queue::Queue;
 pub use sock::{SockHash, SockMap};
 pub use sock::{SockHash, SockMap};
@@ -174,20 +179,6 @@ pub enum MapError {
         io_error: io::Error,
         io_error: io::Error,
     },
     },
 
 
-    /// Map is borrowed mutably
-    #[error("map `{name}` is borrowed mutably")]
-    BorrowError {
-        /// Map name
-        name: String,
-    },
-
-    /// Map is already borrowed
-    #[error("map `{name}` is already borrowed")]
-    BorrowMutError {
-        /// Map name
-        name: String,
-    },
-
     /// Could not pin map by name
     /// Could not pin map by name
     #[error("map `{name:?}` requested pinning by name. pinning failed")]
     #[error("map `{name:?}` requested pinning by name. pinning failed")]
     PinError {
     PinError {
@@ -197,6 +188,10 @@ pub enum MapError {
         #[source]
         #[source]
         error: PinError,
         error: PinError,
     },
     },
+
+    /// The map is not of the expected type.
+    #[error("unexpected map type")]
+    UnexpectedMapType,
 }
 }
 
 
 /// A map file descriptor.
 /// A map file descriptor.
@@ -243,11 +238,181 @@ fn maybe_warn_rlimit() {
     }
     }
 }
 }
 
 
+/// eBPF map types.
+#[derive(Debug)]
+pub enum Map {
+    /// A ['Array`] map
+    Array(MapData),
+    /// A [`PerCpuArray`] map
+    PerCpuArray(MapData),
+    /// A [`ProgramArray`] map
+    ProgramArray(MapData),
+    /// A [`HashMap`] map
+    HashMap(MapData),
+    /// A ['PerCpuHashMap'] map
+    PerCpuHashMap(MapData),
+    /// A [`PerfEventArray`] map
+    PerfEventArray(MapData),
+    /// A [`SockMap`] map
+    SockMap(MapData),
+    /// A [`SockHash`] map
+    SockHash(MapData),
+    /// A [`BloomFilter`] map
+    BloomFilter(MapData),
+    /// A [`LpmTrie`] map
+    LpmTrie(MapData),
+    /// A [`Stack`] map
+    Stack(MapData),
+    /// A [`StackTrace`] map
+    StackTraceMap(MapData),
+    /// A [`Queue`] map
+    Queue(MapData),
+}
+
+macro_rules! impl_try_from_map {
+    ($($tx:ident from Map::$ty:ident),+ $(,)?) => {
+        $(
+            impl<'a> TryFrom<&'a Map> for $tx<&'a MapData> {
+                type Error = MapError;
+
+                fn try_from(map: &'a Map) -> Result<$tx<&'a MapData>, MapError> {
+                    match map {
+                        Map::$ty(m) => {
+                            $tx::<&'a MapData>::new(m)
+                        },
+                        _ => Err(MapError::UnexpectedMapType),
+                    }
+                }
+            }
+
+            impl<'a,> TryFrom<&'a mut Map> for $tx<&'a mut MapData> {
+                type Error = MapError;
+
+                fn try_from(map: &'a mut Map) -> Result<$tx<&'a mut MapData>, MapError> {
+                    match map {
+                        Map::$ty(m) => {
+                            $tx::<&'a mut MapData>::new(m)
+                        },
+                        _ => Err(MapError::UnexpectedMapType),
+                    }
+                }
+            }
+
+            impl TryFrom<Map> for $tx<MapData> {
+                type Error = MapError;
+
+                fn try_from(map: Map) -> Result<$tx<MapData>, MapError> {
+                    match map {
+                        Map::$ty(m) => {
+                            $tx::<MapData>::new(m)
+                        },
+                        _ => Err(MapError::UnexpectedMapType),
+                    }
+                }
+            }
+       )+
+   }
+}
+
+impl_try_from_map!(
+    ProgramArray from Map::ProgramArray,
+    SockMap from Map::SockMap,
+    PerfEventArray from Map::PerfEventArray,
+    StackTraceMap from Map::StackTraceMap,
+);
+
+#[cfg(feature = "async")]
+#[cfg_attr(docsrs, doc(cfg(feature = "async")))]
+impl_try_from_map!(
+    AsyncPerfEventArray from Map::PerfEventArray,
+);
+
+macro_rules! impl_try_from_map_generic_key_or_value {
+    ($($ty:ident),+ $(,)?) => {
+        $(
+            impl<'a, V:Pod> TryFrom<&'a Map> for $ty<&'a MapData, V> {
+                type Error = MapError;
+
+                fn try_from(map: &'a Map) -> Result<$ty<&'a MapData , V>, MapError> {
+                    match map {
+                        Map::$ty(m) => {
+                            $ty::<&'a MapData,V>::new(m)
+                        },
+                        _ => Err(MapError::UnexpectedMapType),
+                    }
+                }
+            }
+
+            impl<'a,V: Pod> TryFrom<&'a mut Map> for $ty<&'a mut MapData, V> {
+                type Error = MapError;
+
+                fn try_from(map: &'a mut Map) -> Result<$ty<&'a mut MapData, V>, MapError> {
+                    match map {
+                        Map::$ty(m) => {
+                            $ty::<&'a mut MapData,V>::new(m)
+                        },
+                        _ => Err(MapError::UnexpectedMapType),
+                    }
+                }
+            }
+
+            impl<V: Pod> TryFrom<Map> for $ty<MapData, V> {
+                type Error = MapError;
+
+                fn try_from(map: Map) -> Result<$ty<MapData, V>, MapError> {
+                    match map {
+                        Map::$ty(m) => {
+                            $ty::<MapData,V>::new(m)
+                        },
+                        _ => Err(MapError::UnexpectedMapType),
+                    }
+                }
+            }
+       )+
+   }
+}
+
+impl_try_from_map_generic_key_or_value!(Array, PerCpuArray, SockHash, BloomFilter, Queue, Stack,);
+
+macro_rules! impl_try_from_map_generic_key_and_value {
+    ($($ty:ident),+ $(,)?) => {
+        $(
+            impl<'a, V: Pod, K: Pod> TryFrom<&'a Map> for $ty<&'a MapData, V, K> {
+                type Error = MapError;
+
+                fn try_from(map: &'a Map) -> Result<$ty<&'a MapData,V,K>, MapError> {
+                    match map {
+                        Map::$ty(m) => {
+                            $ty::<&'a MapData,V,K>::new(m)
+                        },
+                        _ => Err(MapError::UnexpectedMapType),
+                    }
+                }
+            }
+
+            impl<'a,V: Pod,K: Pod> TryFrom<&'a mut Map> for $ty<&'a mut MapData, V, K> {
+                type Error = MapError;
+
+                fn try_from(map: &'a mut Map) -> Result<$ty<&'a mut MapData, V, K>, MapError> {
+                    match map {
+                        Map::$ty(m) => {
+                            $ty::<&'a mut MapData,V,K>::new(m)
+                        },
+                        _ => Err(MapError::UnexpectedMapType),
+                }
+            }
+            }
+       )+
+   }
+}
+
+impl_try_from_map_generic_key_and_value!(HashMap, PerCpuHashMap, LpmTrie);
+
 /// A generic handle to a BPF map.
 /// A generic handle to a BPF map.
 ///
 ///
 /// You should never need to use this unless you're implementing a new map type.
 /// You should never need to use this unless you're implementing a new map type.
-#[derive(Debug)]
-pub struct Map {
+#[derive(Debug, Clone)]
+pub struct MapData {
     pub(crate) obj: obj::Map,
     pub(crate) obj: obj::Map,
     pub(crate) fd: Option<RawFd>,
     pub(crate) fd: Option<RawFd>,
     pub(crate) btf_fd: Option<RawFd>,
     pub(crate) btf_fd: Option<RawFd>,
@@ -255,7 +420,19 @@ pub struct Map {
     pub pinned: bool,
     pub pinned: bool,
 }
 }
 
 
-impl Map {
+impl AsRef<MapData> for MapData {
+    fn as_ref(&self) -> &MapData {
+        self
+    }
+}
+
+impl AsMut<MapData> for MapData {
+    fn as_mut(&mut self) -> &mut MapData {
+        self
+    }
+}
+
+impl MapData {
     /// Creates a new map with the provided `name`
     /// Creates a new map with the provided `name`
     pub fn create(&mut self, name: &str) -> Result<RawFd, MapError> {
     pub fn create(&mut self, name: &str) -> Result<RawFd, MapError> {
         if self.fd.is_some() {
         if self.fd.is_some() {
@@ -303,7 +480,7 @@ impl Map {
     }
     }
 
 
     /// Loads a map from a pinned path in bpffs.
     /// Loads a map from a pinned path in bpffs.
-    pub fn from_pin<P: AsRef<Path>>(path: P) -> Result<Map, MapError> {
+    pub fn from_pin<P: AsRef<Path>>(path: P) -> Result<MapData, MapError> {
         let path_string =
         let path_string =
             CString::new(path.as_ref().to_string_lossy().into_owned()).map_err(|e| {
             CString::new(path.as_ref().to_string_lossy().into_owned()).map_err(|e| {
                 MapError::PinError {
                 MapError::PinError {
@@ -324,7 +501,7 @@ impl Map {
             io_error,
             io_error,
         })?;
         })?;
 
 
-        Ok(Map {
+        Ok(MapData {
             obj: parse_map_info(info, PinningType::ByName),
             obj: parse_map_info(info, PinningType::ByName),
             fd: Some(fd),
             fd: Some(fd),
             btf_fd: None,
             btf_fd: None,
@@ -337,13 +514,13 @@ impl Map {
     /// If loading from a BPF Filesystem (bpffs) you should use [`Map::from_pin`].
     /// If loading from a BPF Filesystem (bpffs) you should use [`Map::from_pin`].
     /// This API is intended for cases where you have received a valid BPF FD from some other means.
     /// This API is intended for cases where you have received a valid BPF FD from some other means.
     /// For example, you received an FD over Unix Domain Socket.
     /// For example, you received an FD over Unix Domain Socket.
-    pub fn from_fd(fd: RawFd) -> Result<Map, MapError> {
+    pub fn from_fd(fd: RawFd) -> Result<MapData, MapError> {
         let info = bpf_map_get_info_by_fd(fd).map_err(|io_error| MapError::SyscallError {
         let info = bpf_map_get_info_by_fd(fd).map_err(|io_error| MapError::SyscallError {
             call: "BPF_OBJ_GET".to_owned(),
             call: "BPF_OBJ_GET".to_owned(),
             io_error,
             io_error,
         })?;
         })?;
 
 
-        Ok(Map {
+        Ok(MapData {
             obj: parse_map_info(info, PinningType::None),
             obj: parse_map_info(info, PinningType::None),
             fd: Some(fd),
             fd: Some(fd),
             btf_fd: None,
             btf_fd: None,
@@ -389,7 +566,7 @@ impl Map {
     }
     }
 }
 }
 
 
-impl Drop for Map {
+impl Drop for MapData {
     fn drop(&mut self) {
     fn drop(&mut self) {
         // TODO: Replace this with an OwnedFd once that is stabilized.
         // TODO: Replace this with an OwnedFd once that is stabilized.
         if let Some(fd) = self.fd.take() {
         if let Some(fd) = self.fd.take() {
@@ -401,7 +578,7 @@ impl Drop for Map {
 /// An iterable map
 /// An iterable map
 pub trait IterableMap<K: Pod, V> {
 pub trait IterableMap<K: Pod, V> {
     /// Get a generic map handle
     /// Get a generic map handle
-    fn map(&self) -> &Map;
+    fn map(&self) -> &MapData;
 
 
     /// Get the value for the provided `key`
     /// Get the value for the provided `key`
     fn get(&self, key: &K) -> Result<V, MapError>;
     fn get(&self, key: &K) -> Result<V, MapError>;
@@ -409,13 +586,13 @@ pub trait IterableMap<K: Pod, V> {
 
 
 /// Iterator returned by `map.keys()`.
 /// Iterator returned by `map.keys()`.
 pub struct MapKeys<'coll, K: Pod> {
 pub struct MapKeys<'coll, K: Pod> {
-    map: &'coll Map,
+    map: &'coll MapData,
     err: bool,
     err: bool,
     key: Option<K>,
     key: Option<K>,
 }
 }
 
 
 impl<'coll, K: Pod> MapKeys<'coll, K> {
 impl<'coll, K: Pod> MapKeys<'coll, K> {
-    fn new(map: &'coll Map) -> MapKeys<'coll, K> {
+    fn new(map: &'coll MapData) -> MapKeys<'coll, K> {
         MapKeys {
         MapKeys {
             map,
             map,
             err: false,
             err: false,
@@ -643,6 +820,7 @@ mod tests {
     use crate::{
     use crate::{
         bpf_map_def,
         bpf_map_def,
         generated::{bpf_cmd, bpf_map_type::BPF_MAP_TYPE_HASH},
         generated::{bpf_cmd, bpf_map_type::BPF_MAP_TYPE_HASH},
+        maps::MapData,
         obj::MapKind,
         obj::MapKind,
         sys::{override_syscall, Syscall},
         sys::{override_syscall, Syscall},
     };
     };
@@ -665,8 +843,8 @@ mod tests {
         })
         })
     }
     }
 
 
-    fn new_map() -> Map {
-        Map {
+    fn new_map() -> MapData {
+        MapData {
             obj: new_obj_map(),
             obj: new_obj_map(),
             fd: None,
             fd: None,
             pinned: false,
             pinned: false,

+ 11 - 19
aya/src/maps/perf/async_perf_event_array.rs

@@ -1,6 +1,6 @@
 use bytes::BytesMut;
 use bytes::BytesMut;
 use std::{
 use std::{
-    ops::DerefMut,
+    convert::AsMut,
     os::unix::prelude::{AsRawFd, RawFd},
     os::unix::prelude::{AsRawFd, RawFd},
 };
 };
 
 
@@ -12,7 +12,7 @@ use tokio::io::unix::AsyncFd;
 
 
 use crate::maps::{
 use crate::maps::{
     perf::{Events, PerfBufferError, PerfEventArray, PerfEventArrayBuffer},
     perf::{Events, PerfBufferError, PerfEventArray, PerfEventArrayBuffer},
-    Map, MapError, MapRefMut,
+    MapData, MapError,
 };
 };
 
 
 /// A `Future` based map that can be used to receive events from eBPF programs using the linux
 /// A `Future` based map that can be used to receive events from eBPF programs using the linux
@@ -45,7 +45,7 @@ use crate::maps::{
 /// # }
 /// # }
 /// # #[cfg(feature = "async_tokio")]
 /// # #[cfg(feature = "async_tokio")]
 /// # async fn try_main() -> Result<(), Error> {
 /// # async fn try_main() -> Result<(), Error> {
-/// # let bpf = aya::Bpf::load(&[])?;
+/// # let mut bpf = aya::Bpf::load(&[])?;
 /// use aya::maps::perf::{AsyncPerfEventArray, PerfBufferError};
 /// use aya::maps::perf::{AsyncPerfEventArray, PerfBufferError};
 /// use aya::util::online_cpus;
 /// use aya::util::online_cpus;
 /// use futures::future;
 /// use futures::future;
@@ -53,7 +53,7 @@ use crate::maps::{
 /// use tokio::task; // or async_std::task
 /// use tokio::task; // or async_std::task
 ///
 ///
 /// // try to convert the PERF_ARRAY map to an AsyncPerfEventArray
 /// // try to convert the PERF_ARRAY map to an AsyncPerfEventArray
-/// let mut perf_array = AsyncPerfEventArray::try_from(bpf.map_mut("PERF_ARRAY")?)?;
+/// let mut perf_array: AsyncPerfEventArray<_> =bpf.take_map("PERF_ARRAY")?.try_into()?;
 ///
 ///
 /// for cpu_id in online_cpus()? {
 /// for cpu_id in online_cpus()? {
 ///     // open a separate perf buffer for each cpu
 ///     // open a separate perf buffer for each cpu
@@ -85,11 +85,11 @@ use crate::maps::{
 /// # }
 /// # }
 /// ```
 /// ```
 #[doc(alias = "BPF_MAP_TYPE_PERF_EVENT_ARRAY")]
 #[doc(alias = "BPF_MAP_TYPE_PERF_EVENT_ARRAY")]
-pub struct AsyncPerfEventArray<T: DerefMut<Target = Map>> {
+pub struct AsyncPerfEventArray<T> {
     perf_map: PerfEventArray<T>,
     perf_map: PerfEventArray<T>,
 }
 }
 
 
-impl<T: DerefMut<Target = Map>> AsyncPerfEventArray<T> {
+impl<T: AsMut<MapData> + AsRef<MapData>> AsyncPerfEventArray<T> {
     /// Opens the perf buffer at the given index.
     /// Opens the perf buffer at the given index.
     ///
     ///
     /// The returned buffer will receive all the events eBPF programs send at the given index.
     /// The returned buffer will receive all the events eBPF programs send at the given index.
@@ -112,8 +112,8 @@ impl<T: DerefMut<Target = Map>> AsyncPerfEventArray<T> {
     }
     }
 }
 }
 
 
-impl<T: DerefMut<Target = Map>> AsyncPerfEventArray<T> {
-    fn new(map: T) -> Result<AsyncPerfEventArray<T>, MapError> {
+impl<T: AsRef<MapData>> AsyncPerfEventArray<T> {
+    pub(crate) fn new(map: T) -> Result<AsyncPerfEventArray<T>, MapError> {
         Ok(AsyncPerfEventArray {
         Ok(AsyncPerfEventArray {
             perf_map: PerfEventArray::new(map)?,
             perf_map: PerfEventArray::new(map)?,
         })
         })
@@ -127,7 +127,7 @@ impl<T: DerefMut<Target = Map>> AsyncPerfEventArray<T> {
 ///
 ///
 /// See the [`AsyncPerfEventArray` documentation](AsyncPerfEventArray) for an overview of how to
 /// See the [`AsyncPerfEventArray` documentation](AsyncPerfEventArray) for an overview of how to
 /// use perf buffers.
 /// use perf buffers.
-pub struct AsyncPerfEventArrayBuffer<T: DerefMut<Target = Map>> {
+pub struct AsyncPerfEventArrayBuffer<T> {
     buf: PerfEventArrayBuffer<T>,
     buf: PerfEventArrayBuffer<T>,
 
 
     #[cfg(feature = "async_tokio")]
     #[cfg(feature = "async_tokio")]
@@ -138,7 +138,7 @@ pub struct AsyncPerfEventArrayBuffer<T: DerefMut<Target = Map>> {
 }
 }
 
 
 #[cfg(any(feature = "async_tokio"))]
 #[cfg(any(feature = "async_tokio"))]
-impl<T: DerefMut<Target = Map>> AsyncPerfEventArrayBuffer<T> {
+impl<T: AsMut<MapData> + AsRef<MapData>> AsyncPerfEventArrayBuffer<T> {
     /// Reads events from the buffer.
     /// Reads events from the buffer.
     ///
     ///
     /// This method reads events into the provided slice of buffers, filling
     /// This method reads events into the provided slice of buffers, filling
@@ -168,7 +168,7 @@ impl<T: DerefMut<Target = Map>> AsyncPerfEventArrayBuffer<T> {
 }
 }
 
 
 #[cfg(all(not(feature = "async_tokio"), feature = "async_std"))]
 #[cfg(all(not(feature = "async_tokio"), feature = "async_std"))]
-impl<T: DerefMut<Target = Map>> AsyncPerfEventArrayBuffer<T> {
+impl<T: AsMut<MapData> + AsRef<MapData>> AsyncPerfEventArrayBuffer<T> {
     /// Reads events from the buffer.
     /// Reads events from the buffer.
     ///
     ///
     /// This method reads events into the provided slice of buffers, filling
     /// This method reads events into the provided slice of buffers, filling
@@ -195,11 +195,3 @@ impl<T: DerefMut<Target = Map>> AsyncPerfEventArrayBuffer<T> {
         }
         }
     }
     }
 }
 }
-
-impl TryFrom<MapRefMut> for AsyncPerfEventArray<MapRefMut> {
-    type Error = MapError;
-
-    fn try_from(a: MapRefMut) -> Result<AsyncPerfEventArray<MapRefMut>, MapError> {
-        AsyncPerfEventArray::new(a)
-    }
-}

+ 19 - 28
aya/src/maps/perf/perf_event_array.rs

@@ -2,7 +2,8 @@
 //!
 //!
 //! [`perf`]: https://perf.wiki.kernel.org/index.php/Main_Page.
 //! [`perf`]: https://perf.wiki.kernel.org/index.php/Main_Page.
 use std::{
 use std::{
-    ops::DerefMut,
+    convert::AsMut,
+    ops::Deref,
     os::unix::io::{AsRawFd, RawFd},
     os::unix::io::{AsRawFd, RawFd},
     sync::Arc,
     sync::Arc,
 };
 };
@@ -10,10 +11,9 @@ use std::{
 use bytes::BytesMut;
 use bytes::BytesMut;
 
 
 use crate::{
 use crate::{
-    generated::bpf_map_type::BPF_MAP_TYPE_PERF_EVENT_ARRAY,
     maps::{
     maps::{
         perf::{Events, PerfBuffer, PerfBufferError},
         perf::{Events, PerfBuffer, PerfBufferError},
-        Map, MapError, MapRefMut,
+        MapData, MapError,
     },
     },
     sys::bpf_map_update_elem,
     sys::bpf_map_update_elem,
     util::page_size,
     util::page_size,
@@ -26,12 +26,12 @@ use crate::{
 ///
 ///
 /// See the [`PerfEventArray` documentation](PerfEventArray) for an overview of how to use
 /// See the [`PerfEventArray` documentation](PerfEventArray) for an overview of how to use
 /// perf buffers.
 /// perf buffers.
-pub struct PerfEventArrayBuffer<T: DerefMut<Target = Map>> {
+pub struct PerfEventArrayBuffer<T> {
     _map: Arc<T>,
     _map: Arc<T>,
     buf: PerfBuffer,
     buf: PerfBuffer,
 }
 }
 
 
-impl<T: DerefMut<Target = Map>> PerfEventArrayBuffer<T> {
+impl<T: AsMut<MapData> + AsRef<MapData>> PerfEventArrayBuffer<T> {
     /// Returns true if the buffer contains events that haven't been read.
     /// Returns true if the buffer contains events that haven't been read.
     pub fn readable(&self) -> bool {
     pub fn readable(&self) -> bool {
         self.buf.readable()
         self.buf.readable()
@@ -55,7 +55,7 @@ impl<T: DerefMut<Target = Map>> PerfEventArrayBuffer<T> {
     }
     }
 }
 }
 
 
-impl<T: DerefMut<Target = Map>> AsRawFd for PerfEventArrayBuffer<T> {
+impl<T: AsMut<MapData> + AsRef<MapData>> AsRawFd for PerfEventArrayBuffer<T> {
     fn as_raw_fd(&self) -> RawFd {
     fn as_raw_fd(&self) -> RawFd {
         self.buf.as_raw_fd()
         self.buf.as_raw_fd()
     }
     }
@@ -83,15 +83,15 @@ impl<T: DerefMut<Target = Map>> AsRawFd for PerfEventArrayBuffer<T> {
 ///
 ///
 /// ```no_run
 /// ```no_run
 /// # use aya::maps::perf::PerfEventArrayBuffer;
 /// # use aya::maps::perf::PerfEventArrayBuffer;
-/// # use aya::maps::Map;
-/// # use std::ops::DerefMut;
+/// # use aya::maps::MapData;
+/// # use std::convert::AsMut;
 /// # struct Poll<T> { _t: std::marker::PhantomData<T> };
 /// # struct Poll<T> { _t: std::marker::PhantomData<T> };
-/// # impl<T: DerefMut<Target=Map>> Poll<T> {
+/// # impl<T: AsMut<MapData>> Poll<T> {
 /// #    fn poll_readable(&self) -> &mut [PerfEventArrayBuffer<T>] {
 /// #    fn poll_readable(&self) -> &mut [PerfEventArrayBuffer<T>] {
 /// #        &mut []
 /// #        &mut []
 /// #    }
 /// #    }
 /// # }
 /// # }
-/// # fn poll_buffers<T: DerefMut<Target=Map>>(bufs: Vec<PerfEventArrayBuffer<T>>) -> Poll<T> {
+/// # fn poll_buffers<T: AsMut<MapData>>(bufs: Vec<PerfEventArrayBuffer<T>>) -> Poll<T> {
 /// #    Poll { _t: std::marker::PhantomData }
 /// #    Poll { _t: std::marker::PhantomData }
 /// # }
 /// # }
 /// # #[derive(thiserror::Error, Debug)]
 /// # #[derive(thiserror::Error, Debug)]
@@ -105,12 +105,12 @@ impl<T: DerefMut<Target = Map>> AsRawFd for PerfEventArrayBuffer<T> {
 /// #    #[error(transparent)]
 /// #    #[error(transparent)]
 /// #    PerfBuf(#[from] aya::maps::perf::PerfBufferError),
 /// #    PerfBuf(#[from] aya::maps::perf::PerfBufferError),
 /// # }
 /// # }
-/// # let bpf = aya::Bpf::load(&[])?;
+/// # let mut bpf = aya::Bpf::load(&[])?;
 /// use aya::maps::PerfEventArray;
 /// use aya::maps::PerfEventArray;
 /// use aya::util::online_cpus;
 /// use aya::util::online_cpus;
 /// use bytes::BytesMut;
 /// use bytes::BytesMut;
 ///
 ///
-/// let mut perf_array = PerfEventArray::try_from(bpf.map_mut("EVENTS")?)?;
+/// let mut perf_array: PerfEventArray<_> = bpf.map_mut("EVENTS")?.try_into()?;
 ///
 ///
 /// // eBPF programs are going to write to the EVENTS perf array, using the id of the CPU they're
 /// // eBPF programs are going to write to the EVENTS perf array, using the id of the CPU they're
 /// // running on as the array index.
 /// // running on as the array index.
@@ -155,25 +155,23 @@ impl<T: DerefMut<Target = Map>> AsRawFd for PerfEventArrayBuffer<T> {
 /// [tokio]: https://docs.rs/tokio
 /// [tokio]: https://docs.rs/tokio
 /// [async-std]: https://docs.rs/async-std
 /// [async-std]: https://docs.rs/async-std
 #[doc(alias = "BPF_MAP_TYPE_PERF_EVENT_ARRAY")]
 #[doc(alias = "BPF_MAP_TYPE_PERF_EVENT_ARRAY")]
-pub struct PerfEventArray<T: DerefMut<Target = Map>> {
+pub struct PerfEventArray<T> {
     map: Arc<T>,
     map: Arc<T>,
     page_size: usize,
     page_size: usize,
 }
 }
 
 
-impl<T: DerefMut<Target = Map>> PerfEventArray<T> {
+impl<T: AsRef<MapData>> PerfEventArray<T> {
     pub(crate) fn new(map: T) -> Result<PerfEventArray<T>, MapError> {
     pub(crate) fn new(map: T) -> Result<PerfEventArray<T>, MapError> {
-        let map_type = map.obj.map_type();
-        if map_type != BPF_MAP_TYPE_PERF_EVENT_ARRAY as u32 {
-            return Err(MapError::InvalidMapType { map_type });
-        }
-        let _fd = map.fd_or_err()?;
+        let _fd = map.as_ref().fd_or_err()?;
 
 
         Ok(PerfEventArray {
         Ok(PerfEventArray {
             map: Arc::new(map),
             map: Arc::new(map),
             page_size: page_size(),
             page_size: page_size(),
         })
         })
     }
     }
+}
 
 
+impl<T: AsMut<MapData> + AsRef<MapData>> PerfEventArray<T> {
     /// Opens the perf buffer at the given index.
     /// Opens the perf buffer at the given index.
     ///
     ///
     /// The returned buffer will receive all the events eBPF programs send at the given index.
     /// The returned buffer will receive all the events eBPF programs send at the given index.
@@ -185,7 +183,8 @@ impl<T: DerefMut<Target = Map>> PerfEventArray<T> {
         // FIXME: keep track of open buffers
         // FIXME: keep track of open buffers
 
 
         // this cannot fail as new() checks that the fd is open
         // this cannot fail as new() checks that the fd is open
-        let map_fd = self.map.fd_or_err().unwrap();
+        let map_data: &MapData = self.map.deref().as_ref();
+        let map_fd = map_data.fd_or_err().unwrap();
         let buf = PerfBuffer::open(index, self.page_size, page_count.unwrap_or(2))?;
         let buf = PerfBuffer::open(index, self.page_size, page_count.unwrap_or(2))?;
         bpf_map_update_elem(map_fd, Some(&index), &buf.as_raw_fd(), 0)
         bpf_map_update_elem(map_fd, Some(&index), &buf.as_raw_fd(), 0)
             .map_err(|(_, io_error)| io_error)?;
             .map_err(|(_, io_error)| io_error)?;
@@ -196,11 +195,3 @@ impl<T: DerefMut<Target = Map>> PerfEventArray<T> {
         })
         })
     }
     }
 }
 }
-
-impl TryFrom<MapRefMut> for PerfEventArray<MapRefMut> {
-    type Error = MapError;
-
-    fn try_from(a: MapRefMut) -> Result<PerfEventArray<MapRefMut>, MapError> {
-        PerfEventArray::new(a)
-    }
-}

+ 15 - 35
aya/src/maps/queue.rs

@@ -1,13 +1,12 @@
 //! A FIFO queue.
 //! A FIFO queue.
 use std::{
 use std::{
+    convert::{AsMut, AsRef},
     marker::PhantomData,
     marker::PhantomData,
     mem,
     mem,
-    ops::{Deref, DerefMut},
 };
 };
 
 
 use crate::{
 use crate::{
-    generated::bpf_map_type::BPF_MAP_TYPE_QUEUE,
-    maps::{Map, MapError, MapRef, MapRefMut},
+    maps::{MapData, MapError},
     sys::{bpf_map_lookup_and_delete_elem, bpf_map_push_elem},
     sys::{bpf_map_lookup_and_delete_elem, bpf_map_push_elem},
     Pod,
     Pod,
 };
 };
@@ -20,39 +19,36 @@ use crate::{
 ///
 ///
 /// # Examples
 /// # Examples
 /// ```no_run
 /// ```no_run
-/// # let bpf = aya::Bpf::load(&[])?;
+/// # let mut bpf = aya::Bpf::load(&[])?;
 /// use aya::maps::Queue;
 /// use aya::maps::Queue;
 ///
 ///
-/// let mut queue = Queue::try_from(bpf.map_mut("ARRAY")?)?;
+/// let mut queue: Queue<_, u32> = bpf.map_mut("ARRAY")?.try_into()?;
 /// queue.push(42, 0)?;
 /// queue.push(42, 0)?;
 /// queue.push(43, 0)?;
 /// queue.push(43, 0)?;
 /// assert_eq!(queue.pop(0)?, 42);
 /// assert_eq!(queue.pop(0)?, 42);
 /// # Ok::<(), aya::BpfError>(())
 /// # Ok::<(), aya::BpfError>(())
 /// ```
 /// ```
 #[doc(alias = "BPF_MAP_TYPE_QUEUE")]
 #[doc(alias = "BPF_MAP_TYPE_QUEUE")]
-pub struct Queue<T: Deref<Target = Map>, V: Pod> {
+pub struct Queue<T, V: Pod> {
     inner: T,
     inner: T,
     _v: PhantomData<V>,
     _v: PhantomData<V>,
 }
 }
 
 
-impl<T: Deref<Target = Map>, V: Pod> Queue<T, V> {
-    fn new(map: T) -> Result<Queue<T, V>, MapError> {
-        let map_type = map.obj.map_type();
-        if map_type != BPF_MAP_TYPE_QUEUE as u32 {
-            return Err(MapError::InvalidMapType { map_type });
-        }
+impl<T: AsRef<MapData>, V: Pod> Queue<T, V> {
+    pub(crate) fn new(map: T) -> Result<Queue<T, V>, MapError> {
+        let data = map.as_ref();
         let expected = 0;
         let expected = 0;
-        let size = map.obj.key_size() as usize;
+        let size = data.obj.key_size() as usize;
         if size != expected {
         if size != expected {
             return Err(MapError::InvalidKeySize { size, expected });
             return Err(MapError::InvalidKeySize { size, expected });
         }
         }
 
 
         let expected = mem::size_of::<V>();
         let expected = mem::size_of::<V>();
-        let size = map.obj.value_size() as usize;
+        let size = data.obj.value_size() as usize;
         if size != expected {
         if size != expected {
             return Err(MapError::InvalidValueSize { size, expected });
             return Err(MapError::InvalidValueSize { size, expected });
         }
         }
-        let _fd = map.fd_or_err()?;
+        let _fd = data.fd_or_err()?;
 
 
         Ok(Queue {
         Ok(Queue {
             inner: map,
             inner: map,
@@ -64,11 +60,11 @@ impl<T: Deref<Target = Map>, V: Pod> Queue<T, V> {
     ///
     ///
     /// This corresponds to the value of `bpf_map_def::max_entries` on the eBPF side.
     /// This corresponds to the value of `bpf_map_def::max_entries` on the eBPF side.
     pub fn capacity(&self) -> u32 {
     pub fn capacity(&self) -> u32 {
-        self.inner.obj.max_entries()
+        self.inner.as_ref().obj.max_entries()
     }
     }
 }
 }
 
 
-impl<T: Deref<Target = Map> + DerefMut<Target = Map>, V: Pod> Queue<T, V> {
+impl<T: AsMut<MapData>, V: Pod> Queue<T, V> {
     /// Removes the first element and returns it.
     /// Removes the first element and returns it.
     ///
     ///
     /// # Errors
     /// # Errors
@@ -76,7 +72,7 @@ impl<T: Deref<Target = Map> + DerefMut<Target = Map>, V: Pod> Queue<T, V> {
     /// Returns [`MapError::ElementNotFound`] if the queue is empty, [`MapError::SyscallError`]
     /// Returns [`MapError::ElementNotFound`] if the queue is empty, [`MapError::SyscallError`]
     /// if `bpf_map_lookup_and_delete_elem` fails.
     /// if `bpf_map_lookup_and_delete_elem` fails.
     pub fn pop(&mut self, flags: u64) -> Result<V, MapError> {
     pub fn pop(&mut self, flags: u64) -> Result<V, MapError> {
-        let fd = self.inner.fd_or_err()?;
+        let fd = self.inner.as_mut().fd_or_err()?;
 
 
         let value = bpf_map_lookup_and_delete_elem::<u32, _>(fd, None, flags).map_err(
         let value = bpf_map_lookup_and_delete_elem::<u32, _>(fd, None, flags).map_err(
             |(_, io_error)| MapError::SyscallError {
             |(_, io_error)| MapError::SyscallError {
@@ -93,7 +89,7 @@ impl<T: Deref<Target = Map> + DerefMut<Target = Map>, V: Pod> Queue<T, V> {
     ///
     ///
     /// [`MapError::SyscallError`] if `bpf_map_update_elem` fails.
     /// [`MapError::SyscallError`] if `bpf_map_update_elem` fails.
     pub fn push(&mut self, value: V, flags: u64) -> Result<(), MapError> {
     pub fn push(&mut self, value: V, flags: u64) -> Result<(), MapError> {
-        let fd = self.inner.fd_or_err()?;
+        let fd = self.inner.as_mut().fd_or_err()?;
         bpf_map_push_elem(fd, &value, flags).map_err(|(_, io_error)| MapError::SyscallError {
         bpf_map_push_elem(fd, &value, flags).map_err(|(_, io_error)| MapError::SyscallError {
             call: "bpf_map_push_elem".to_owned(),
             call: "bpf_map_push_elem".to_owned(),
             io_error,
             io_error,
@@ -101,19 +97,3 @@ impl<T: Deref<Target = Map> + DerefMut<Target = Map>, V: Pod> Queue<T, V> {
         Ok(())
         Ok(())
     }
     }
 }
 }
-
-impl<V: Pod> TryFrom<MapRef> for Queue<MapRef, V> {
-    type Error = MapError;
-
-    fn try_from(a: MapRef) -> Result<Queue<MapRef, V>, MapError> {
-        Queue::new(a)
-    }
-}
-
-impl<V: Pod> TryFrom<MapRefMut> for Queue<MapRefMut, V> {
-    type Error = MapError;
-
-    fn try_from(a: MapRefMut) -> Result<Queue<MapRefMut, V>, MapError> {
-        Queue::new(a)
-    }
-}

+ 18 - 42
aya/src/maps/sock/sock_hash.rs

@@ -1,14 +1,11 @@
 use std::{
 use std::{
+    convert::{AsMut, AsRef},
     marker::PhantomData,
     marker::PhantomData,
-    ops::{Deref, DerefMut},
     os::unix::io::{AsRawFd, RawFd},
     os::unix::io::{AsRawFd, RawFd},
 };
 };
 
 
 use crate::{
 use crate::{
-    generated::bpf_map_type::BPF_MAP_TYPE_SOCKHASH,
-    maps::{
-        hash_map, sock::SocketMap, IterableMap, Map, MapError, MapIter, MapKeys, MapRef, MapRefMut,
-    },
+    maps::{hash_map, sock::SocketMap, IterableMap, MapData, MapError, MapIter, MapKeys},
     sys::bpf_map_lookup_elem,
     sys::bpf_map_lookup_elem,
     Pod,
     Pod,
 };
 };
@@ -47,7 +44,7 @@ use crate::{
 /// use aya::maps::SockHash;
 /// use aya::maps::SockHash;
 /// use aya::programs::SkMsg;
 /// use aya::programs::SkMsg;
 ///
 ///
-/// let mut intercept_egress = SockHash::try_from(bpf.map_mut("INTERCEPT_EGRESS")?)?;
+/// let mut intercept_egress: SockHash<_, u32> = bpf.take_map("INTERCEPT_EGRESS")?.try_into()?;
 /// let prog: &mut SkMsg = bpf.program_mut("intercept_egress_packet").unwrap().try_into()?;
 /// let prog: &mut SkMsg = bpf.program_mut("intercept_egress_packet").unwrap().try_into()?;
 /// prog.load()?;
 /// prog.load()?;
 /// prog.attach(&intercept_egress)?;
 /// prog.attach(&intercept_egress)?;
@@ -60,21 +57,16 @@ use crate::{
 /// # Ok::<(), Error>(())
 /// # Ok::<(), Error>(())
 /// ```
 /// ```
 #[doc(alias = "BPF_MAP_TYPE_SOCKHASH")]
 #[doc(alias = "BPF_MAP_TYPE_SOCKHASH")]
-pub struct SockHash<T: Deref<Target = Map>, K> {
+pub struct SockHash<T, K> {
     inner: T,
     inner: T,
     _k: PhantomData<K>,
     _k: PhantomData<K>,
 }
 }
 
 
-impl<T: Deref<Target = Map>, K: Pod> SockHash<T, K> {
+impl<T: AsRef<MapData>, K: Pod> SockHash<T, K> {
     pub(crate) fn new(map: T) -> Result<SockHash<T, K>, MapError> {
     pub(crate) fn new(map: T) -> Result<SockHash<T, K>, MapError> {
-        let map_type = map.obj.map_type();
-
-        // validate the map definition
-        if map_type != BPF_MAP_TYPE_SOCKHASH as u32 {
-            return Err(MapError::InvalidMapType { map_type });
-        }
-        hash_map::check_kv_size::<K, u32>(&map)?;
-        let _ = map.fd_or_err()?;
+        let data = map.as_ref();
+        hash_map::check_kv_size::<K, u32>(data)?;
+        let _ = data.fd_or_err()?;
 
 
         Ok(SockHash {
         Ok(SockHash {
             inner: map,
             inner: map,
@@ -84,7 +76,7 @@ impl<T: Deref<Target = Map>, K: Pod> SockHash<T, K> {
 
 
     /// Returns the fd of the socket stored at the given key.
     /// Returns the fd of the socket stored at the given key.
     pub fn get(&self, key: &K, flags: u64) -> Result<RawFd, MapError> {
     pub fn get(&self, key: &K, flags: u64) -> Result<RawFd, MapError> {
-        let fd = self.inner.deref().fd_or_err()?;
+        let fd = self.inner.as_ref().fd_or_err()?;
         let value = bpf_map_lookup_elem(fd, key, flags).map_err(|(_, io_error)| {
         let value = bpf_map_lookup_elem(fd, key, flags).map_err(|(_, io_error)| {
             MapError::SyscallError {
             MapError::SyscallError {
                 call: "bpf_map_lookup_elem".to_owned(),
                 call: "bpf_map_lookup_elem".to_owned(),
@@ -103,25 +95,25 @@ impl<T: Deref<Target = Map>, K: Pod> SockHash<T, K> {
     /// An iterator visiting all keys in arbitrary order. The iterator element
     /// An iterator visiting all keys in arbitrary order. The iterator element
     /// type is `Result<K, MapError>`.
     /// type is `Result<K, MapError>`.
     pub fn keys(&self) -> MapKeys<'_, K> {
     pub fn keys(&self) -> MapKeys<'_, K> {
-        MapKeys::new(&self.inner)
+        MapKeys::new(self.inner.as_ref())
     }
     }
 }
 }
 
 
-impl<T: DerefMut<Target = Map>, K: Pod> SockHash<T, K> {
+impl<T: AsMut<MapData>, K: Pod> SockHash<T, K> {
     /// Inserts a socket under the given key.
     /// Inserts a socket under the given key.
     pub fn insert<I: AsRawFd>(&mut self, key: K, value: I, flags: u64) -> Result<(), MapError> {
     pub fn insert<I: AsRawFd>(&mut self, key: K, value: I, flags: u64) -> Result<(), MapError> {
-        hash_map::insert(&mut self.inner, key, value.as_raw_fd(), flags)
+        hash_map::insert(self.inner.as_mut(), key, value.as_raw_fd(), flags)
     }
     }
 
 
     /// Removes a socket from the map.
     /// Removes a socket from the map.
     pub fn remove(&mut self, key: &K) -> Result<(), MapError> {
     pub fn remove(&mut self, key: &K) -> Result<(), MapError> {
-        hash_map::remove(&mut self.inner, key)
+        hash_map::remove(self.inner.as_mut(), key)
     }
     }
 }
 }
 
 
-impl<T: Deref<Target = Map>, K: Pod> IterableMap<K, RawFd> for SockHash<T, K> {
-    fn map(&self) -> &Map {
-        &self.inner
+impl<T: AsRef<MapData>, K: Pod> IterableMap<K, RawFd> for SockHash<T, K> {
+    fn map(&self) -> &MapData {
+        self.inner.as_ref()
     }
     }
 
 
     fn get(&self, key: &K) -> Result<RawFd, MapError> {
     fn get(&self, key: &K) -> Result<RawFd, MapError> {
@@ -129,24 +121,8 @@ impl<T: Deref<Target = Map>, K: Pod> IterableMap<K, RawFd> for SockHash<T, K> {
     }
     }
 }
 }
 
 
-impl<T: DerefMut<Target = Map>, K: Pod> SocketMap for SockHash<T, K> {
+impl<T: AsRef<MapData>, K: Pod> SocketMap for SockHash<T, K> {
     fn fd_or_err(&self) -> Result<RawFd, MapError> {
     fn fd_or_err(&self) -> Result<RawFd, MapError> {
-        self.inner.fd_or_err()
-    }
-}
-
-impl<K: Pod> TryFrom<MapRef> for SockHash<MapRef, K> {
-    type Error = MapError;
-
-    fn try_from(a: MapRef) -> Result<SockHash<MapRef, K>, MapError> {
-        SockHash::new(a)
-    }
-}
-
-impl<K: Pod> TryFrom<MapRefMut> for SockHash<MapRefMut, K> {
-    type Error = MapError;
-
-    fn try_from(a: MapRefMut) -> Result<SockHash<MapRefMut, K>, MapError> {
-        SockHash::new(a)
+        self.inner.as_ref().fd_or_err()
     }
     }
 }
 }

+ 18 - 38
aya/src/maps/sock/sock_map.rs

@@ -1,14 +1,13 @@
 //! An array of eBPF program file descriptors used as a jump table.
 //! An array of eBPF program file descriptors used as a jump table.
 
 
 use std::{
 use std::{
+    convert::{AsMut, AsRef},
     mem,
     mem,
-    ops::{Deref, DerefMut},
     os::unix::{io::AsRawFd, prelude::RawFd},
     os::unix::{io::AsRawFd, prelude::RawFd},
 };
 };
 
 
 use crate::{
 use crate::{
-    generated::bpf_map_type::BPF_MAP_TYPE_SOCKMAP,
-    maps::{sock::SocketMap, Map, MapError, MapKeys, MapRef, MapRefMut},
+    maps::{sock::SocketMap, MapData, MapError, MapKeys},
     sys::{bpf_map_delete_elem, bpf_map_update_elem},
     sys::{bpf_map_delete_elem, bpf_map_update_elem},
 };
 };
 
 
@@ -32,35 +31,32 @@ use crate::{
 /// use aya::maps::SockMap;
 /// use aya::maps::SockMap;
 /// use aya::programs::SkSkb;
 /// use aya::programs::SkSkb;
 ///
 ///
-/// let intercept_ingress = SockMap::try_from(bpf.map_mut("INTERCEPT_INGRESS")?)?;
+/// let intercept_ingress: SockMap<_> = bpf.take_map("INTERCEPT_INGRESS")?.try_into()?;
 /// let prog: &mut SkSkb = bpf.program_mut("intercept_ingress_packet").unwrap().try_into()?;
 /// let prog: &mut SkSkb = bpf.program_mut("intercept_ingress_packet").unwrap().try_into()?;
 /// prog.load()?;
 /// prog.load()?;
 /// prog.attach(&intercept_ingress)?;
 /// prog.attach(&intercept_ingress)?;
 /// # Ok::<(), aya::BpfError>(())
 /// # Ok::<(), aya::BpfError>(())
 /// ```
 /// ```
 #[doc(alias = "BPF_MAP_TYPE_SOCKMAP")]
 #[doc(alias = "BPF_MAP_TYPE_SOCKMAP")]
-pub struct SockMap<T: Deref<Target = Map>> {
+pub struct SockMap<T: AsRef<MapData>> {
     pub(crate) inner: T,
     pub(crate) inner: T,
 }
 }
 
 
-impl<T: Deref<Target = Map>> SockMap<T> {
-    fn new(map: T) -> Result<SockMap<T>, MapError> {
-        let map_type = map.obj.map_type();
-        if map_type != BPF_MAP_TYPE_SOCKMAP as u32 {
-            return Err(MapError::InvalidMapType { map_type });
-        }
+impl<T: AsRef<MapData>> SockMap<T> {
+    pub(crate) fn new(map: T) -> Result<SockMap<T>, MapError> {
+        let data = map.as_ref();
         let expected = mem::size_of::<u32>();
         let expected = mem::size_of::<u32>();
-        let size = map.obj.key_size() as usize;
+        let size = data.obj.key_size() as usize;
         if size != expected {
         if size != expected {
             return Err(MapError::InvalidKeySize { size, expected });
             return Err(MapError::InvalidKeySize { size, expected });
         }
         }
 
 
         let expected = mem::size_of::<RawFd>();
         let expected = mem::size_of::<RawFd>();
-        let size = map.obj.value_size() as usize;
+        let size = data.obj.value_size() as usize;
         if size != expected {
         if size != expected {
             return Err(MapError::InvalidValueSize { size, expected });
             return Err(MapError::InvalidValueSize { size, expected });
         }
         }
-        let _fd = map.fd_or_err()?;
+        let _fd = data.fd_or_err()?;
 
 
         Ok(SockMap { inner: map })
         Ok(SockMap { inner: map })
     }
     }
@@ -68,12 +64,12 @@ impl<T: Deref<Target = Map>> SockMap<T> {
     /// An iterator over the indices of the array that point to a program. The iterator item type
     /// An iterator over the indices of the array that point to a program. The iterator item type
     /// is `Result<u32, MapError>`.
     /// is `Result<u32, MapError>`.
     pub fn indices(&self) -> MapKeys<'_, u32> {
     pub fn indices(&self) -> MapKeys<'_, u32> {
-        MapKeys::new(&self.inner)
+        MapKeys::new(self.inner.as_ref())
     }
     }
 
 
     fn check_bounds(&self, index: u32) -> Result<(), MapError> {
     fn check_bounds(&self, index: u32) -> Result<(), MapError> {
-        let max_entries = self.inner.obj.max_entries();
-        if index >= self.inner.obj.max_entries() {
+        let max_entries = self.inner.as_ref().obj.max_entries();
+        if index >= self.inner.as_ref().obj.max_entries() {
             Err(MapError::OutOfBounds { index, max_entries })
             Err(MapError::OutOfBounds { index, max_entries })
         } else {
         } else {
             Ok(())
             Ok(())
@@ -81,10 +77,10 @@ impl<T: Deref<Target = Map>> SockMap<T> {
     }
     }
 }
 }
 
 
-impl<T: Deref<Target = Map> + DerefMut<Target = Map>> SockMap<T> {
+impl<T: AsRef<MapData> + AsMut<MapData>> SockMap<T> {
     /// Stores a socket into the map.
     /// Stores a socket into the map.
     pub fn set<I: AsRawFd>(&mut self, index: u32, socket: &I, flags: u64) -> Result<(), MapError> {
     pub fn set<I: AsRawFd>(&mut self, index: u32, socket: &I, flags: u64) -> Result<(), MapError> {
-        let fd = self.inner.fd_or_err()?;
+        let fd = self.inner.as_ref().fd_or_err()?;
         self.check_bounds(index)?;
         self.check_bounds(index)?;
         bpf_map_update_elem(fd, Some(&index), &socket.as_raw_fd(), flags).map_err(
         bpf_map_update_elem(fd, Some(&index), &socket.as_raw_fd(), flags).map_err(
             |(_, io_error)| MapError::SyscallError {
             |(_, io_error)| MapError::SyscallError {
@@ -97,7 +93,7 @@ impl<T: Deref<Target = Map> + DerefMut<Target = Map>> SockMap<T> {
 
 
     /// Removes the socket stored at `index` from the map.
     /// Removes the socket stored at `index` from the map.
     pub fn clear_index(&mut self, index: &u32) -> Result<(), MapError> {
     pub fn clear_index(&mut self, index: &u32) -> Result<(), MapError> {
-        let fd = self.inner.fd_or_err()?;
+        let fd = self.inner.as_ref().fd_or_err()?;
         self.check_bounds(*index)?;
         self.check_bounds(*index)?;
         bpf_map_delete_elem(fd, index)
         bpf_map_delete_elem(fd, index)
             .map(|_| ())
             .map(|_| ())
@@ -108,24 +104,8 @@ impl<T: Deref<Target = Map> + DerefMut<Target = Map>> SockMap<T> {
     }
     }
 }
 }
 
 
-impl<T: Deref<Target = Map> + DerefMut<Target = Map>> SocketMap for SockMap<T> {
+impl<T: AsRef<MapData> + AsMut<MapData>> SocketMap for SockMap<T> {
     fn fd_or_err(&self) -> Result<RawFd, MapError> {
     fn fd_or_err(&self) -> Result<RawFd, MapError> {
-        self.inner.fd_or_err()
-    }
-}
-
-impl TryFrom<MapRef> for SockMap<MapRef> {
-    type Error = MapError;
-
-    fn try_from(a: MapRef) -> Result<SockMap<MapRef>, MapError> {
-        SockMap::new(a)
-    }
-}
-
-impl TryFrom<MapRefMut> for SockMap<MapRefMut> {
-    type Error = MapError;
-
-    fn try_from(a: MapRefMut) -> Result<SockMap<MapRefMut>, MapError> {
-        SockMap::new(a)
+        self.inner.as_ref().fd_or_err()
     }
     }
 }
 }

+ 15 - 35
aya/src/maps/stack.rs

@@ -1,13 +1,12 @@
 //! A LIFO stack.
 //! A LIFO stack.
 use std::{
 use std::{
+    convert::{AsMut, AsRef},
     marker::PhantomData,
     marker::PhantomData,
     mem,
     mem,
-    ops::{Deref, DerefMut},
 };
 };
 
 
 use crate::{
 use crate::{
-    generated::bpf_map_type::BPF_MAP_TYPE_STACK,
-    maps::{Map, MapError, MapRef, MapRefMut},
+    maps::{MapData, MapError},
     sys::{bpf_map_lookup_and_delete_elem, bpf_map_update_elem},
     sys::{bpf_map_lookup_and_delete_elem, bpf_map_update_elem},
     Pod,
     Pod,
 };
 };
@@ -20,39 +19,36 @@ use crate::{
 ///
 ///
 /// # Examples
 /// # Examples
 /// ```no_run
 /// ```no_run
-/// # let bpf = aya::Bpf::load(&[])?;
+/// # let mut bpf = aya::Bpf::load(&[])?;
 /// use aya::maps::Stack;
 /// use aya::maps::Stack;
 ///
 ///
-/// let mut stack = Stack::try_from(bpf.map_mut("STACK")?)?;
+/// let mut stack: Stack<_, u32> = bpf.map_mut("STACK")?.try_into()?;
 /// stack.push(42, 0)?;
 /// stack.push(42, 0)?;
 /// stack.push(43, 0)?;
 /// stack.push(43, 0)?;
 /// assert_eq!(stack.pop(0)?, 43);
 /// assert_eq!(stack.pop(0)?, 43);
 /// # Ok::<(), aya::BpfError>(())
 /// # Ok::<(), aya::BpfError>(())
 /// ```
 /// ```
 #[doc(alias = "BPF_MAP_TYPE_STACK")]
 #[doc(alias = "BPF_MAP_TYPE_STACK")]
-pub struct Stack<T: Deref<Target = Map>, V: Pod> {
+pub struct Stack<T, V: Pod> {
     inner: T,
     inner: T,
     _v: PhantomData<V>,
     _v: PhantomData<V>,
 }
 }
 
 
-impl<T: Deref<Target = Map>, V: Pod> Stack<T, V> {
-    fn new(map: T) -> Result<Stack<T, V>, MapError> {
-        let map_type = map.obj.map_type();
-        if map_type != BPF_MAP_TYPE_STACK as u32 {
-            return Err(MapError::InvalidMapType { map_type });
-        }
+impl<T: AsRef<MapData>, V: Pod> Stack<T, V> {
+    pub(crate) fn new(map: T) -> Result<Stack<T, V>, MapError> {
+        let data = map.as_ref();
         let expected = 0;
         let expected = 0;
-        let size = map.obj.key_size() as usize;
+        let size = data.obj.key_size() as usize;
         if size != expected {
         if size != expected {
             return Err(MapError::InvalidKeySize { size, expected });
             return Err(MapError::InvalidKeySize { size, expected });
         }
         }
 
 
         let expected = mem::size_of::<V>();
         let expected = mem::size_of::<V>();
-        let size = map.obj.value_size() as usize;
+        let size = data.obj.value_size() as usize;
         if size != expected {
         if size != expected {
             return Err(MapError::InvalidValueSize { size, expected });
             return Err(MapError::InvalidValueSize { size, expected });
         }
         }
-        let _fd = map.fd_or_err()?;
+        let _fd = data.fd_or_err()?;
 
 
         Ok(Stack {
         Ok(Stack {
             inner: map,
             inner: map,
@@ -64,11 +60,11 @@ impl<T: Deref<Target = Map>, V: Pod> Stack<T, V> {
     ///
     ///
     /// This corresponds to the value of `bpf_map_def::max_entries` on the eBPF side.
     /// This corresponds to the value of `bpf_map_def::max_entries` on the eBPF side.
     pub fn capacity(&self) -> u32 {
     pub fn capacity(&self) -> u32 {
-        self.inner.obj.max_entries()
+        self.inner.as_ref().obj.max_entries()
     }
     }
 }
 }
 
 
-impl<T: Deref<Target = Map> + DerefMut<Target = Map>, V: Pod> Stack<T, V> {
+impl<T: AsMut<MapData>, V: Pod> Stack<T, V> {
     /// Removes the last element and returns it.
     /// Removes the last element and returns it.
     ///
     ///
     /// # Errors
     /// # Errors
@@ -76,7 +72,7 @@ impl<T: Deref<Target = Map> + DerefMut<Target = Map>, V: Pod> Stack<T, V> {
     /// Returns [`MapError::ElementNotFound`] if the stack is empty, [`MapError::SyscallError`]
     /// Returns [`MapError::ElementNotFound`] if the stack is empty, [`MapError::SyscallError`]
     /// if `bpf_map_lookup_and_delete_elem` fails.
     /// if `bpf_map_lookup_and_delete_elem` fails.
     pub fn pop(&mut self, flags: u64) -> Result<V, MapError> {
     pub fn pop(&mut self, flags: u64) -> Result<V, MapError> {
-        let fd = self.inner.fd_or_err()?;
+        let fd = self.inner.as_mut().fd_or_err()?;
 
 
         let value = bpf_map_lookup_and_delete_elem::<u32, _>(fd, None, flags).map_err(
         let value = bpf_map_lookup_and_delete_elem::<u32, _>(fd, None, flags).map_err(
             |(_, io_error)| MapError::SyscallError {
             |(_, io_error)| MapError::SyscallError {
@@ -93,7 +89,7 @@ impl<T: Deref<Target = Map> + DerefMut<Target = Map>, V: Pod> Stack<T, V> {
     ///
     ///
     /// [`MapError::SyscallError`] if `bpf_map_update_elem` fails.
     /// [`MapError::SyscallError`] if `bpf_map_update_elem` fails.
     pub fn push(&mut self, value: V, flags: u64) -> Result<(), MapError> {
     pub fn push(&mut self, value: V, flags: u64) -> Result<(), MapError> {
-        let fd = self.inner.fd_or_err()?;
+        let fd = self.inner.as_mut().fd_or_err()?;
         bpf_map_update_elem(fd, None::<&u32>, &value, flags).map_err(|(_, io_error)| {
         bpf_map_update_elem(fd, None::<&u32>, &value, flags).map_err(|(_, io_error)| {
             MapError::SyscallError {
             MapError::SyscallError {
                 call: "bpf_map_update_elem".to_owned(),
                 call: "bpf_map_update_elem".to_owned(),
@@ -103,19 +99,3 @@ impl<T: Deref<Target = Map> + DerefMut<Target = Map>, V: Pod> Stack<T, V> {
         Ok(())
         Ok(())
     }
     }
 }
 }
-
-impl<V: Pod> TryFrom<MapRef> for Stack<MapRef, V> {
-    type Error = MapError;
-
-    fn try_from(a: MapRef) -> Result<Stack<MapRef, V>, MapError> {
-        Stack::new(a)
-    }
-}
-
-impl<V: Pod> TryFrom<MapRefMut> for Stack<MapRefMut, V> {
-    type Error = MapError;
-
-    fn try_from(a: MapRefMut) -> Result<Stack<MapRefMut, V>, MapError> {
-        Stack::new(a)
-    }
-}

+ 14 - 34
aya/src/maps/stack_trace.rs

@@ -1,11 +1,10 @@
 //! A hash map of kernel or user space stack traces.
 //! A hash map of kernel or user space stack traces.
 //!
 //!
 //! See [`StackTraceMap`] for documentation and examples.
 //! See [`StackTraceMap`] for documentation and examples.
-use std::{collections::BTreeMap, fs, io, mem, ops::Deref, path::Path, str::FromStr};
+use std::{collections::BTreeMap, convert::AsRef, fs, io, mem, path::Path, str::FromStr};
 
 
 use crate::{
 use crate::{
-    generated::bpf_map_type::BPF_MAP_TYPE_STACK_TRACE,
-    maps::{IterableMap, Map, MapError, MapIter, MapKeys, MapRef, MapRefMut},
+    maps::{IterableMap, MapData, MapError, MapIter, MapKeys},
     sys::bpf_map_lookup_elem_ptr,
     sys::bpf_map_lookup_elem_ptr,
 };
 };
 
 
@@ -68,14 +67,11 @@ pub struct StackTraceMap<T> {
     max_stack_depth: usize,
     max_stack_depth: usize,
 }
 }
 
 
-impl<T: Deref<Target = Map>> StackTraceMap<T> {
-    fn new(map: T) -> Result<StackTraceMap<T>, MapError> {
-        let map_type = map.obj.map_type();
-        if map_type != BPF_MAP_TYPE_STACK_TRACE as u32 {
-            return Err(MapError::InvalidMapType { map_type });
-        }
+impl<T: AsRef<MapData>> StackTraceMap<T> {
+    pub(crate) fn new(map: T) -> Result<StackTraceMap<T>, MapError> {
+        let data = map.as_ref();
         let expected = mem::size_of::<u32>();
         let expected = mem::size_of::<u32>();
-        let size = map.obj.key_size() as usize;
+        let size = data.obj.key_size() as usize;
         if size != expected {
         if size != expected {
             return Err(MapError::InvalidKeySize { size, expected });
             return Err(MapError::InvalidKeySize { size, expected });
         }
         }
@@ -87,11 +83,11 @@ impl<T: Deref<Target = Map>> StackTraceMap<T> {
                     io_error,
                     io_error,
                 }
                 }
             })?;
             })?;
-        let size = map.obj.value_size() as usize;
+        let size = data.obj.value_size() as usize;
         if size > max_stack_depth * mem::size_of::<u64>() {
         if size > max_stack_depth * mem::size_of::<u64>() {
             return Err(MapError::InvalidValueSize { size, expected });
             return Err(MapError::InvalidValueSize { size, expected });
         }
         }
-        let _fd = map.fd_or_err()?;
+        let _fd = data.fd_or_err()?;
 
 
         Ok(StackTraceMap {
         Ok(StackTraceMap {
             inner: map,
             inner: map,
@@ -106,7 +102,7 @@ impl<T: Deref<Target = Map>> StackTraceMap<T> {
     /// Returns [`MapError::KeyNotFound`] if there is no stack trace with the
     /// Returns [`MapError::KeyNotFound`] if there is no stack trace with the
     /// given `stack_id`, or [`MapError::SyscallError`] if `bpf_map_lookup_elem` fails.
     /// given `stack_id`, or [`MapError::SyscallError`] if `bpf_map_lookup_elem` fails.
     pub fn get(&self, stack_id: &u32, flags: u64) -> Result<StackTrace, MapError> {
     pub fn get(&self, stack_id: &u32, flags: u64) -> Result<StackTrace, MapError> {
-        let fd = self.inner.fd_or_err()?;
+        let fd = self.inner.as_ref().fd_or_err()?;
 
 
         let mut frames = vec![0; self.max_stack_depth];
         let mut frames = vec![0; self.max_stack_depth];
         bpf_map_lookup_elem_ptr(fd, Some(stack_id), frames.as_mut_ptr(), flags)
         bpf_map_lookup_elem_ptr(fd, Some(stack_id), frames.as_mut_ptr(), flags)
@@ -140,13 +136,13 @@ impl<T: Deref<Target = Map>> StackTraceMap<T> {
     /// An iterator visiting all the stack_ids in arbitrary order. The iterator element
     /// An iterator visiting all the stack_ids in arbitrary order. The iterator element
     /// type is `Result<u32, MapError>`.
     /// type is `Result<u32, MapError>`.
     pub fn stack_ids(&self) -> MapKeys<'_, u32> {
     pub fn stack_ids(&self) -> MapKeys<'_, u32> {
-        MapKeys::new(&self.inner)
+        MapKeys::new(self.inner.as_ref())
     }
     }
 }
 }
 
 
-impl<T: Deref<Target = Map>> IterableMap<u32, StackTrace> for StackTraceMap<T> {
-    fn map(&self) -> &Map {
-        &self.inner
+impl<T: AsRef<MapData>> IterableMap<u32, StackTrace> for StackTraceMap<T> {
+    fn map(&self) -> &MapData {
+        self.inner.as_ref()
     }
     }
 
 
     fn get(&self, index: &u32) -> Result<StackTrace, MapError> {
     fn get(&self, index: &u32) -> Result<StackTrace, MapError> {
@@ -154,23 +150,7 @@ impl<T: Deref<Target = Map>> IterableMap<u32, StackTrace> for StackTraceMap<T> {
     }
     }
 }
 }
 
 
-impl TryFrom<MapRef> for StackTraceMap<MapRef> {
-    type Error = MapError;
-
-    fn try_from(a: MapRef) -> Result<StackTraceMap<MapRef>, MapError> {
-        StackTraceMap::new(a)
-    }
-}
-
-impl TryFrom<MapRefMut> for StackTraceMap<MapRefMut> {
-    type Error = MapError;
-
-    fn try_from(a: MapRefMut) -> Result<StackTraceMap<MapRefMut>, MapError> {
-        StackTraceMap::new(a)
-    }
-}
-
-impl<'a, T: Deref<Target = Map>> IntoIterator for &'a StackTraceMap<T> {
+impl<'a, T: AsRef<MapData>> IntoIterator for &'a StackTraceMap<T> {
     type Item = Result<(u32, StackTrace), MapError>;
     type Item = Result<(u32, StackTrace), MapError>;
     type IntoIter = MapIter<'a, u32, StackTrace, StackTraceMap<T>>;
     type IntoIter = MapIter<'a, u32, StackTrace, StackTraceMap<T>>;
 
 

+ 9 - 8
aya/src/obj/relocation.rs

@@ -9,7 +9,7 @@ use crate::{
         bpf_insn, BPF_CALL, BPF_JMP, BPF_K, BPF_PSEUDO_CALL, BPF_PSEUDO_FUNC, BPF_PSEUDO_MAP_FD,
         bpf_insn, BPF_CALL, BPF_JMP, BPF_K, BPF_PSEUDO_CALL, BPF_PSEUDO_FUNC, BPF_PSEUDO_MAP_FD,
         BPF_PSEUDO_MAP_VALUE,
         BPF_PSEUDO_MAP_VALUE,
     },
     },
-    maps::Map,
+    maps::MapData,
     obj::{Function, Object, Program},
     obj::{Function, Object, Program},
     BpfError,
     BpfError,
 };
 };
@@ -62,7 +62,7 @@ pub(crate) struct Symbol {
 }
 }
 
 
 impl Object {
 impl Object {
-    pub fn relocate_maps(&mut self, maps: &HashMap<String, Map>) -> Result<(), BpfError> {
+    pub fn relocate_maps(&mut self, maps: &HashMap<String, MapData>) -> Result<(), BpfError> {
         let maps_by_section = maps
         let maps_by_section = maps
             .iter()
             .iter()
             .map(|(name, map)| (map.obj.section_index(), (name.as_str(), map)))
             .map(|(name, map)| (map.obj.section_index(), (name.as_str(), map)))
@@ -122,8 +122,8 @@ impl Object {
 fn relocate_maps<'a, I: Iterator<Item = &'a Relocation>>(
 fn relocate_maps<'a, I: Iterator<Item = &'a Relocation>>(
     fun: &mut Function,
     fun: &mut Function,
     relocations: I,
     relocations: I,
-    maps_by_section: &HashMap<usize, (&str, &Map)>,
-    maps_by_symbol: &HashMap<usize, (&str, &Map)>,
+    maps_by_section: &HashMap<usize, (&str, &MapData)>,
+    maps_by_symbol: &HashMap<usize, (&str, &MapData)>,
     symbol_table: &HashMap<usize, Symbol>,
     symbol_table: &HashMap<usize, Symbol>,
     text_section_index: Option<usize>,
     text_section_index: Option<usize>,
 ) -> Result<(), RelocationError> {
 ) -> Result<(), RelocationError> {
@@ -438,6 +438,7 @@ fn insn_is_call(ins: &bpf_insn) -> bool {
 mod test {
 mod test {
     use crate::{
     use crate::{
         bpf_map_def,
         bpf_map_def,
+        maps::MapData,
         obj::{self, BtfMap, LegacyMap, MapKind},
         obj::{self, BtfMap, LegacyMap, MapKind},
         BtfMapDef,
         BtfMapDef,
     };
     };
@@ -460,8 +461,8 @@ mod test {
         unsafe { std::ptr::read_unaligned(bytes.as_ptr() as *const _) }
         unsafe { std::ptr::read_unaligned(bytes.as_ptr() as *const _) }
     }
     }
 
 
-    fn fake_legacy_map(fd: i32, symbol_index: usize) -> Map {
-        Map {
+    fn fake_legacy_map(fd: i32, symbol_index: usize) -> MapData {
+        MapData {
             obj: obj::Map::Legacy(LegacyMap {
             obj: obj::Map::Legacy(LegacyMap {
                 def: bpf_map_def {
                 def: bpf_map_def {
                     ..Default::default()
                     ..Default::default()
@@ -477,8 +478,8 @@ mod test {
         }
         }
     }
     }
 
 
-    fn fake_btf_map(fd: i32, symbol_index: usize) -> Map {
-        Map {
+    fn fake_btf_map(fd: i32, symbol_index: usize) -> MapData {
+        MapData {
             obj: obj::Map::Btf(BtfMap {
             obj: obj::Map::Btf(BtfMap {
                 def: BtfMapDef {
                 def: BtfMapDef {
                     ..Default::default()
                     ..Default::default()

+ 1 - 1
aya/src/programs/sk_msg.rs

@@ -40,7 +40,7 @@ use crate::{
 /// use aya::maps::SockHash;
 /// use aya::maps::SockHash;
 /// use aya::programs::SkMsg;
 /// use aya::programs::SkMsg;
 ///
 ///
-/// let mut intercept_egress = SockHash::try_from(bpf.map_mut("INTERCEPT_EGRESS")?)?;
+/// let mut intercept_egress: SockHash<_, u32> = bpf.take_map("INTERCEPT_EGRESS")?.try_into()?;
 /// let prog: &mut SkMsg = bpf.program_mut("intercept_egress_packet").unwrap().try_into()?;
 /// let prog: &mut SkMsg = bpf.program_mut("intercept_egress_packet").unwrap().try_into()?;
 /// prog.load()?;
 /// prog.load()?;
 /// prog.attach(&intercept_egress)?;
 /// prog.attach(&intercept_egress)?;

+ 1 - 1
aya/src/programs/sk_skb.rs

@@ -38,7 +38,7 @@ pub enum SkSkbKind {
 /// use aya::maps::SockMap;
 /// use aya::maps::SockMap;
 /// use aya::programs::SkSkb;
 /// use aya::programs::SkSkb;
 ///
 ///
-/// let intercept_ingress = SockMap::try_from(bpf.map_mut("INTERCEPT_INGRESS")?)?;
+/// let intercept_ingress: SockMap<_> = bpf.take_map("INTERCEPT_INGRESS")?.try_into()?;
 /// let prog: &mut SkSkb = bpf.program_mut("intercept_ingress_packet").unwrap().try_into()?;
 /// let prog: &mut SkSkb = bpf.program_mut("intercept_ingress_packet").unwrap().try_into()?;
 /// prog.load()?;
 /// prog.load()?;
 /// prog.attach(&intercept_ingress)?;
 /// prog.attach(&intercept_ingress)?;

+ 3 - 3
test/integration-test/src/tests/load.rs

@@ -2,7 +2,7 @@ use std::{process::Command, thread, time};
 
 
 use aya::{
 use aya::{
     include_bytes_aligned,
     include_bytes_aligned,
-    maps::{Array, MapRefMut},
+    maps::Array,
     programs::{
     programs::{
         links::{FdLink, PinnedLink},
         links::{FdLink, PinnedLink},
         TracePoint, Xdp, XdpFlags,
         TracePoint, Xdp, XdpFlags,
@@ -36,8 +36,8 @@ fn multiple_btf_maps() -> anyhow::Result<()> {
         include_bytes_aligned!("../../../../target/bpfel-unknown-none/debug/multimap-btf.bpf.o");
         include_bytes_aligned!("../../../../target/bpfel-unknown-none/debug/multimap-btf.bpf.o");
     let mut bpf = Bpf::load(bytes)?;
     let mut bpf = Bpf::load(bytes)?;
 
 
-    let map_1: Array<MapRefMut, u64> = Array::try_from(bpf.map_mut("map_1")?)?;
-    let map_2: Array<MapRefMut, u64> = Array::try_from(bpf.map_mut("map_2")?)?;
+    let map_1: Array<_, u64> = bpf.take_map("map_1")?.try_into()?;
+    let map_2: Array<_, u64> = bpf.take_map("map_2")?.try_into()?;
 
 
     let prog: &mut TracePoint = bpf.program_mut("tracepoint").unwrap().try_into().unwrap();
     let prog: &mut TracePoint = bpf.program_mut("tracepoint").unwrap().try_into().unwrap();
     prog.load().unwrap();
     prog.load().unwrap();