Message ID | 20250304-work-pidfs-kill_on_last_close-v2-4-44fdacfaa7b7@kernel.org (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | pidfs: provide information after task has been reaped | expand |
On Tue, 2025-03-04 at 10:41 +0100, Christian Brauner wrote: > Signed-off-by: Christian Brauner <brauner@kernel.org> > --- > fs/pidfs.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 52 insertions(+) > > diff --git a/fs/pidfs.c b/fs/pidfs.c > index ecc0dd886714..eaecb0a947f0 100644 > --- a/fs/pidfs.c > +++ b/fs/pidfs.c > @@ -24,6 +24,27 @@ > #include "internal.h" > #include "mount.h" > > +static struct kmem_cache *pidfs_cachep __ro_after_init; > + > +/* > + * Stashes information that userspace needs to access even after the > + * process has been reaped. > + */ > +struct pidfs_exit_info { > + __u64 cgroupid; > + __u64 exit_code; This is changed to __s32 in the next patch. Might as well do that here. > +}; > + > +struct pidfs_inode { > + struct pidfs_exit_info exit_info; > + struct inode vfs_inode; > +}; > + > +static inline struct pidfs_inode *pidfs_i(struct inode *inode) > +{ > + return container_of(inode, struct pidfs_inode, vfs_inode); > +} > + > static struct rb_root pidfs_ino_tree = RB_ROOT; > > #if BITS_PER_LONG == 32 > @@ -492,9 +513,29 @@ static void pidfs_evict_inode(struct inode *inode) > put_pid(pid); > } > > +static struct inode *pidfs_alloc_inode(struct super_block *sb) > +{ > + struct pidfs_inode *pi; > + > + pi = alloc_inode_sb(sb, pidfs_cachep, GFP_KERNEL); > + if (!pi) > + return NULL; > + > + memset(&pi->exit_info, 0, sizeof(pi->exit_info)); > + > + return &pi->vfs_inode; > +} > + > +static void pidfs_free_inode(struct inode *inode) > +{ > + kmem_cache_free(pidfs_cachep, pidfs_i(inode)); > +} > + > static const struct super_operations pidfs_sops = { > + .alloc_inode = pidfs_alloc_inode, > .drop_inode = generic_delete_inode, > .evict_inode = pidfs_evict_inode, > + .free_inode = pidfs_free_inode, > .statfs = simple_statfs, > }; > > @@ -704,8 +745,19 @@ struct file *pidfs_alloc_file(struct pid *pid, unsigned int flags) > return pidfd_file; > } > > +static void pidfs_inode_init_once(void *data) > +{ > + struct pidfs_inode *pi = data; > + > + inode_init_once(&pi->vfs_inode); > +} > + > void __init pidfs_init(void) > { > + pidfs_cachep = kmem_cache_create("pidfs_cache", sizeof(struct pidfs_inode), 0, > + (SLAB_HWCACHE_ALIGN | SLAB_RECLAIM_ACCOUNT | > + SLAB_ACCOUNT | SLAB_PANIC), > + pidfs_inode_init_once); > pidfs_mnt = kern_mount(&pidfs_type); > if (IS_ERR(pidfs_mnt)) > panic("Failed to mount pidfs pseudo filesystem"); > Reviewed-by: Jeff Layton <jlayton@kernel.org>
diff --git a/fs/pidfs.c b/fs/pidfs.c index ecc0dd886714..eaecb0a947f0 100644 --- a/fs/pidfs.c +++ b/fs/pidfs.c @@ -24,6 +24,27 @@ #include "internal.h" #include "mount.h" +static struct kmem_cache *pidfs_cachep __ro_after_init; + +/* + * Stashes information that userspace needs to access even after the + * process has been reaped. + */ +struct pidfs_exit_info { + __u64 cgroupid; + __u64 exit_code; +}; + +struct pidfs_inode { + struct pidfs_exit_info exit_info; + struct inode vfs_inode; +}; + +static inline struct pidfs_inode *pidfs_i(struct inode *inode) +{ + return container_of(inode, struct pidfs_inode, vfs_inode); +} + static struct rb_root pidfs_ino_tree = RB_ROOT; #if BITS_PER_LONG == 32 @@ -492,9 +513,29 @@ static void pidfs_evict_inode(struct inode *inode) put_pid(pid); } +static struct inode *pidfs_alloc_inode(struct super_block *sb) +{ + struct pidfs_inode *pi; + + pi = alloc_inode_sb(sb, pidfs_cachep, GFP_KERNEL); + if (!pi) + return NULL; + + memset(&pi->exit_info, 0, sizeof(pi->exit_info)); + + return &pi->vfs_inode; +} + +static void pidfs_free_inode(struct inode *inode) +{ + kmem_cache_free(pidfs_cachep, pidfs_i(inode)); +} + static const struct super_operations pidfs_sops = { + .alloc_inode = pidfs_alloc_inode, .drop_inode = generic_delete_inode, .evict_inode = pidfs_evict_inode, + .free_inode = pidfs_free_inode, .statfs = simple_statfs, }; @@ -704,8 +745,19 @@ struct file *pidfs_alloc_file(struct pid *pid, unsigned int flags) return pidfd_file; } +static void pidfs_inode_init_once(void *data) +{ + struct pidfs_inode *pi = data; + + inode_init_once(&pi->vfs_inode); +} + void __init pidfs_init(void) { + pidfs_cachep = kmem_cache_create("pidfs_cache", sizeof(struct pidfs_inode), 0, + (SLAB_HWCACHE_ALIGN | SLAB_RECLAIM_ACCOUNT | + SLAB_ACCOUNT | SLAB_PANIC), + pidfs_inode_init_once); pidfs_mnt = kern_mount(&pidfs_type); if (IS_ERR(pidfs_mnt)) panic("Failed to mount pidfs pseudo filesystem");
Signed-off-by: Christian Brauner <brauner@kernel.org> --- fs/pidfs.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+)