Re: [PATCH RFC 4/7] pidfs: support xattrs on pidfds

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Am Di., 17. Juni 2025 um 17:45 Uhr schrieb Christian Brauner
<brauner@xxxxxxxxxx>:
>
> Signed-off-by: Christian Brauner <brauner@xxxxxxxxxx>

Reviewed-by: Alexander Mikhalitsyn <aleksandr.mikhalitsyn@xxxxxxxxxxxxx>

> ---
>  fs/pidfs.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
>  1 file changed, 92 insertions(+), 2 deletions(-)
>
> diff --git a/fs/pidfs.c b/fs/pidfs.c
> index 1343bfc60e3f..b1968f628417 100644
> --- a/fs/pidfs.c
> +++ b/fs/pidfs.c
> @@ -21,6 +21,7 @@
>  #include <linux/utsname.h>
>  #include <net/net_namespace.h>
>  #include <linux/coredump.h>
> +#include <linux/xattr.h>
>
>  #include "internal.h"
>  #include "mount.h"
> @@ -40,6 +41,7 @@
>  #define PIDFS_PID_DEAD ERR_PTR(-ESRCH)
>
>  static struct kmem_cache *pidfs_cachep __ro_after_init;
> +static struct kmem_cache *pidfs_attrs_cachep __ro_after_init;
>
>  /*
>   * Stashes information that userspace needs to access even after the
> @@ -51,9 +53,14 @@ struct pidfs_exit_info {
>         __u32 coredump_mask;
>  };
>
> +struct pidfs_attrs {
> +       struct simple_xattrs xattrs;
> +};
> +
>  struct pidfs_inode {
>         struct pidfs_exit_info __pei;
>         struct pidfs_exit_info *exit_info;
> +       struct pidfs_attrs *attrs;
>         struct inode vfs_inode;
>  };
>
> @@ -672,15 +679,34 @@ static int pidfs_getattr(struct mnt_idmap *idmap, const struct path *path,
>         return anon_inode_getattr(idmap, path, stat, request_mask, query_flags);
>  }
>
> +static ssize_t pidfs_listxattr(struct dentry *dentry, char *buf, size_t size)
> +{
> +       struct inode *inode = d_inode(dentry);
> +       struct pidfs_attrs *attrs;
> +
> +       attrs = READ_ONCE(pidfs_i(inode)->attrs);
> +       if (!attrs)
> +               return -ENODATA;
> +
> +       return simple_xattr_list(inode, &attrs->xattrs, buf, size);
> +}
> +
>  static const struct inode_operations pidfs_inode_operations = {
> -       .getattr = pidfs_getattr,
> -       .setattr = pidfs_setattr,
> +       .getattr        = pidfs_getattr,
> +       .setattr        = pidfs_setattr,
> +       .listxattr      = pidfs_listxattr,
>  };
>
>  static void pidfs_evict_inode(struct inode *inode)
>  {
>         struct pid *pid = inode->i_private;
> +       struct pidfs_attrs *attrs;
>
> +       attrs = READ_ONCE(pidfs_i(inode)->attrs);
> +       if (attrs) {
> +               simple_xattrs_free(&attrs->xattrs, NULL);
> +               kmem_cache_free(pidfs_attrs_cachep, attrs);
> +       }
>         clear_inode(inode);
>         put_pid(pid);
>  }
> @@ -695,6 +721,7 @@ static struct inode *pidfs_alloc_inode(struct super_block *sb)
>
>         memset(&pi->__pei, 0, sizeof(pi->__pei));
>         pi->exit_info = NULL;
> +       pi->attrs = NULL;
>
>         return &pi->vfs_inode;
>  }
> @@ -951,6 +978,63 @@ static const struct stashed_operations pidfs_stashed_ops = {
>         .put_data       = pidfs_put_data,
>  };
>
> +static int pidfs_xattr_get(const struct xattr_handler *handler,
> +                          struct dentry *unused, struct inode *inode,
> +                          const char *suffix, void *value, size_t size)
> +{
> +       const char *name;
> +       struct pidfs_attrs *attrs;
> +
> +       attrs = READ_ONCE(pidfs_i(inode)->attrs);
> +       if (!attrs)
> +               return -ENODATA;
> +
> +       name = xattr_full_name(handler, suffix);
> +       return simple_xattr_get(&attrs->xattrs, name, value, size);
> +}
> +
> +static int pidfs_xattr_set(const struct xattr_handler *handler,
> +                          struct mnt_idmap *idmap, struct dentry *unused,
> +                          struct inode *inode, const char *suffix,
> +                          const void *value, size_t size, int flags)
> +{
> +       const char *name;
> +       struct pidfs_attrs *attrs;
> +       struct simple_xattr *old_xattr;
> +
> +       /* Make sure we're the only one here. */
> +       WARN_ON_ONCE(!inode_is_locked(inode));
> +
> +       attrs = READ_ONCE(pidfs_i(inode)->attrs);
> +       if (!attrs) {
> +               attrs = kmem_cache_zalloc(pidfs_attrs_cachep, GFP_KERNEL);
> +               if (!attrs)
> +                       return -ENOMEM;
> +
> +               simple_xattrs_init(&attrs->xattrs);
> +               smp_store_release(&pidfs_i(inode)->attrs, attrs);
> +       }
> +
> +       name = xattr_full_name(handler, suffix);
> +       old_xattr = simple_xattr_set(&attrs->xattrs, name, value, size, flags);
> +       if (IS_ERR(old_xattr))
> +               return PTR_ERR(old_xattr);
> +
> +       simple_xattr_free(old_xattr);
> +       return 0;
> +}
> +
> +static const struct xattr_handler pidfs_trusted_xattr_handler = {
> +       .prefix = XATTR_TRUSTED_PREFIX,
> +       .get    = pidfs_xattr_get,
> +       .set    = pidfs_xattr_set,
> +};
> +
> +static const struct xattr_handler *const pidfs_xattr_handlers[] = {
> +       &pidfs_trusted_xattr_handler,
> +       NULL
> +};
> +
>  static int pidfs_init_fs_context(struct fs_context *fc)
>  {
>         struct pseudo_fs_context *ctx;
> @@ -964,6 +1048,7 @@ static int pidfs_init_fs_context(struct fs_context *fc)
>         ctx->ops = &pidfs_sops;
>         ctx->eops = &pidfs_export_operations;
>         ctx->dops = &pidfs_dentry_operations;
> +       ctx->xattr = pidfs_xattr_handlers;
>         fc->s_fs_info = (void *)&pidfs_stashed_ops;
>         return 0;
>  }
> @@ -1073,6 +1158,11 @@ void __init pidfs_init(void)
>                                          (SLAB_HWCACHE_ALIGN | SLAB_RECLAIM_ACCOUNT |
>                                           SLAB_ACCOUNT | SLAB_PANIC),
>                                          pidfs_inode_init_once);
> +
> +       pidfs_attrs_cachep = kmem_cache_create("pidfs_attrs_cache",
> +                                              sizeof(struct pidfs_attrs), 0,
> +                                              SLAB_PANIC, NULL);

nit: WDYT about adding SLAB_ACCOUNT too?

> +
>         pidfs_mnt = kern_mount(&pidfs_type);
>         if (IS_ERR(pidfs_mnt))
>                 panic("Failed to mount pidfs pseudo filesystem");
>
> --
> 2.47.2
>




[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [NTFS 3]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [NTFS 3]     [Samba]     [Device Mapper]     [CEPH Development]

  Powered by Linux