On Thu, Jul 09, 2020 at 12:12:37PM +0200, KP Singh wrote: > From: KP Singh <kpsingh@xxxxxxxxxx> > > 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 <kpsingh@xxxxxxxxxx> [ ... ] > +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? > + 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; > +} > + [ ... ] > +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, > +}; > +