Re: [PATCH bpf-next v4 2/4] bpf: Implement bpf_local_storage for inodes
From: KP Singh <hidden>
Date: 2020-07-15 22:59:16
Also in:
bpf, lkml
On 15-Jul 14:57, Martin KaFai Lau wrote:
On Thu, Jul 09, 2020 at 12:12:37PM +0200, KP Singh wrote:quoted
From: KP Singh <redacted> Similar to bpf_local_storage for sockets, add local storage for inodes. The life-cycle of storage is managed with the life-cycle of the inode. i.e. the storage is destroyed along with the owning inode. The BPF LSM allocates an __rcu pointer to the bpf_local_storage in the security blob which are now stackable and can co-exist with other LSMs. Signed-off-by: KP Singh <redacted>[ ... ]quoted
+static void *bpf_inode_storage_lookup_elem(struct bpf_map *map, void *key) +{ + struct bpf_local_storage_data *sdata; + struct inode *inode; + int err = -EINVAL; + + if (key) { + inode = *(struct inode **)(key);The bpf_inode_storage_lookup_elem() here and the (update|delete)_elem() below are called from the userspace syscall. How the userspace may provide this key?
I realized this when I replied about the _fd_ name in the sk helpers. I am going to mark them as unsupported for now for inodes. We could, probably and separately, use a combination of the device and inode number as a key from userspace. - KP
quoted
+ sdata = inode_storage_lookup(inode, map, true); + return sdata ? sdata->data : NULL; + } + + return ERR_PTR(err); +} + +static int bpf_inode_storage_update_elem(struct bpf_map *map, void *key, + void *value, u64 map_flags) +{ + struct bpf_local_storage_data *sdata; + struct inode *inode; + int err = -EINVAL; + + if (key) { + inode = *(struct inode **)(key); + sdata = map->ops->map_local_storage_update(inode, map, value, + map_flags); + return PTR_ERR_OR_ZERO(sdata); + } + return err; +} + +static int inode_storage_delete(struct inode *inode, struct bpf_map *map) +{ + struct bpf_local_storage_data *sdata; + + sdata = inode_storage_lookup(inode, map, false); + if (!sdata) + return -ENOENT; + + bpf_selem_unlink_map_elem(SELEM(sdata)); + + return 0; +} + +static int bpf_inode_storage_delete_elem(struct bpf_map *map, void *key) +{ + struct inode *inode; + int err = -EINVAL; + + if (key) { + inode = *(struct inode **)(key); + err = inode_storage_delete(inode, map); + } + + return err; +} +[ ... ]quoted
+static int inode_storage_map_btf_id; +const struct bpf_map_ops inode_storage_map_ops = { + .map_alloc_check = bpf_local_storage_map_alloc_check, + .map_alloc = inode_storage_map_alloc, + .map_free = inode_storage_map_free, + .map_get_next_key = notsupp_get_next_key, + .map_lookup_elem = bpf_inode_storage_lookup_elem, + .map_update_elem = bpf_inode_storage_update_elem, + .map_delete_elem = bpf_inode_storage_delete_elem, + .map_check_btf = bpf_local_storage_map_check_btf, + .map_btf_name = "bpf_local_storage_map", + .map_btf_id = &inode_storage_map_btf_id, + .map_local_storage_alloc = inode_storage_alloc, + .map_selem_alloc = inode_selem_alloc, + .map_local_storage_update = inode_storage_update, + .map_local_storage_unlink = unlink_inode_storage, +}; +