mirror of
https://github.com/linux-msm/laptops-kernel.git
synced 2026-08-13 14:19:53 -07:00
Merge tag 'fsnotify_for_v7.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs
Pull fsnotify updates from Jan Kara: - fanotify improvements for pidfd reporting - small cleanup in fanotify_error_event_equal * tag 'fsnotify_for_v7.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs: fanotify: allow reporting pidfds for reaped tasks fanotify: report thread pidfds for FAN_REPORT_TID fanotify: simplify fanotify_error_event_equal
This commit is contained in:
@@ -14,6 +14,7 @@
|
||||
#include <linux/sched/mm.h>
|
||||
#include <linux/statfs.h>
|
||||
#include <linux/stringhash.h>
|
||||
#include <linux/pidfs.h>
|
||||
|
||||
#include "fanotify.h"
|
||||
|
||||
@@ -120,10 +121,7 @@ static bool fanotify_error_event_equal(struct fanotify_error_event *fee1,
|
||||
struct fanotify_error_event *fee2)
|
||||
{
|
||||
/* Error events against the same file system are always merged. */
|
||||
if (!fanotify_fsid_equal(&fee1->fsid, &fee2->fsid))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
return fanotify_fsid_equal(&fee1->fsid, &fee2->fsid);
|
||||
}
|
||||
|
||||
static bool fanotify_should_merge(struct fanotify_event *old,
|
||||
@@ -842,6 +840,15 @@ static struct fanotify_event *fanotify_alloc_event(
|
||||
/* Whoever is interested in the event, pays for the allocation. */
|
||||
old_memcg = set_active_memcg(group->memcg);
|
||||
|
||||
if (FAN_GROUP_FLAG(group, FAN_REPORT_TID))
|
||||
pid = task_pid(current);
|
||||
else
|
||||
pid = task_tgid(current);
|
||||
|
||||
if (FAN_GROUP_FLAG(group, FAN_REPORT_PIDFD) &&
|
||||
pidfs_register_pid_gfp(pid, gfp))
|
||||
goto out;
|
||||
|
||||
if (fanotify_is_perm_event(mask)) {
|
||||
event = fanotify_alloc_perm_event(data, data_type, gfp);
|
||||
} else if (fanotify_is_error_event(mask)) {
|
||||
@@ -863,15 +870,10 @@ static struct fanotify_event *fanotify_alloc_event(
|
||||
if (!event)
|
||||
goto out;
|
||||
|
||||
if (FAN_GROUP_FLAG(group, FAN_REPORT_TID))
|
||||
pid = get_pid(task_pid(current));
|
||||
else
|
||||
pid = get_pid(task_tgid(current));
|
||||
|
||||
/* Mix event info, FAN_ONDIR flag and pid into event merge key */
|
||||
hash ^= hash_long((unsigned long)pid | ondir, FANOTIFY_EVENT_HASH_BITS);
|
||||
fanotify_init_event(event, hash, mask);
|
||||
event->pid = pid;
|
||||
event->pid = get_pid(pid);
|
||||
|
||||
out:
|
||||
set_active_memcg(old_memcg);
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <linux/memcontrol.h>
|
||||
#include <linux/statfs.h>
|
||||
#include <linux/exportfs.h>
|
||||
#include <linux/pidfd.h>
|
||||
|
||||
#include <asm/ioctls.h>
|
||||
|
||||
@@ -903,25 +904,13 @@ static ssize_t copy_event_to_user(struct fsnotify_group *group,
|
||||
metadata.fd = fd >= 0 ? fd : FAN_NOFD;
|
||||
|
||||
if (pidfd_mode) {
|
||||
/*
|
||||
* Complain if the FAN_REPORT_PIDFD and FAN_REPORT_TID mutual
|
||||
* exclusion is ever lifted. At the time of incoporating pidfd
|
||||
* support within fanotify, the pidfd API only supported the
|
||||
* creation of pidfds for thread-group leaders.
|
||||
*/
|
||||
WARN_ON_ONCE(FAN_GROUP_FLAG(group, FAN_REPORT_TID));
|
||||
unsigned int pidfd_flags = PIDFD_STALE;
|
||||
|
||||
/*
|
||||
* The PIDTYPE_TGID check for an event->pid is performed
|
||||
* preemptively in an attempt to catch out cases where the event
|
||||
* listener reads events after the event generating process has
|
||||
* already terminated. Depending on flag FAN_REPORT_FD_ERROR,
|
||||
* report either -ESRCH or FAN_NOPIDFD to the event listener in
|
||||
* those cases with all other pidfd creation errors reported as
|
||||
* the error code itself or as FAN_EPIDFD.
|
||||
*/
|
||||
if (metadata.pid && pid_has_task(event->pid, PIDTYPE_TGID))
|
||||
pidfd = pidfd_prepare(event->pid, 0, &pidfd_file);
|
||||
if (FAN_GROUP_FLAG(group, FAN_REPORT_TID))
|
||||
pidfd_flags |= PIDFD_THREAD;
|
||||
|
||||
if (metadata.pid)
|
||||
pidfd = pidfd_prepare(event->pid, pidfd_flags, &pidfd_file);
|
||||
|
||||
if (!FAN_GROUP_FLAG(group, FAN_REPORT_FD_ERROR) && pidfd < 0)
|
||||
pidfd = pidfd == -ESRCH ? FAN_NOPIDFD : FAN_EPIDFD;
|
||||
@@ -1628,14 +1617,6 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags)
|
||||
#endif
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* A pidfd can only be returned for a thread-group leader; thus
|
||||
* FAN_REPORT_PIDFD and FAN_REPORT_TID need to remain mutually
|
||||
* exclusive.
|
||||
*/
|
||||
if ((flags & FAN_REPORT_PIDFD) && (flags & FAN_REPORT_TID))
|
||||
return -EINVAL;
|
||||
|
||||
/* Don't allow mixing mnt events with inode events for now */
|
||||
if (flags & FAN_REPORT_MNT) {
|
||||
if (class != FAN_CLASS_NOTIF)
|
||||
|
||||
+6
-4
@@ -977,14 +977,16 @@ static void pidfs_put_data(void *data)
|
||||
}
|
||||
|
||||
/**
|
||||
* pidfs_register_pid - register a struct pid in pidfs
|
||||
* pidfs_register_pid_gfp - register a struct pid in pidfs with custom GFP
|
||||
* flags
|
||||
* @pid: pid to pin
|
||||
* @gfp: GFP flags for memory allocation
|
||||
*
|
||||
* Register a struct pid in pidfs.
|
||||
* Register a struct pid in pidfs with custom GFP flags.
|
||||
*
|
||||
* Return: On success zero, on error a negative error code is returned.
|
||||
*/
|
||||
int pidfs_register_pid(struct pid *pid)
|
||||
int pidfs_register_pid_gfp(struct pid *pid, gfp_t gfp)
|
||||
{
|
||||
struct pidfs_attr *new_attr __free(kfree) = NULL;
|
||||
struct pidfs_attr *attr;
|
||||
@@ -1000,7 +1002,7 @@ int pidfs_register_pid(struct pid *pid)
|
||||
if (attr)
|
||||
return 0;
|
||||
|
||||
new_attr = kmem_cache_zalloc(pidfs_attr_cachep, GFP_KERNEL);
|
||||
new_attr = kmem_cache_zalloc(pidfs_attr_cachep, gfp);
|
||||
if (!new_attr)
|
||||
return -ENOMEM;
|
||||
|
||||
|
||||
+17
-1
@@ -2,6 +2,8 @@
|
||||
#ifndef _LINUX_PID_FS_H
|
||||
#define _LINUX_PID_FS_H
|
||||
|
||||
#include <linux/gfp_types.h>
|
||||
|
||||
struct coredump_params;
|
||||
|
||||
struct file *pidfs_alloc_file(struct pid *pid, unsigned int flags);
|
||||
@@ -14,7 +16,21 @@ void pidfs_exit(struct task_struct *tsk);
|
||||
void pidfs_coredump(const struct coredump_params *cprm);
|
||||
#endif
|
||||
extern const struct dentry_operations pidfs_dentry_operations;
|
||||
int pidfs_register_pid(struct pid *pid);
|
||||
int pidfs_register_pid_gfp(struct pid *pid, gfp_t gfp);
|
||||
|
||||
/**
|
||||
* pidfs_register_pid - register a struct pid in pidfs
|
||||
* @pid: pid to pin
|
||||
*
|
||||
* Register a struct pid in pidfs.
|
||||
*
|
||||
* Return: On success zero, on error a negative error code is returned.
|
||||
*/
|
||||
static inline int pidfs_register_pid(struct pid *pid)
|
||||
{
|
||||
return pidfs_register_pid_gfp(pid, GFP_KERNEL);
|
||||
}
|
||||
|
||||
void pidfs_free_pid(struct pid *pid);
|
||||
|
||||
#endif /* _LINUX_PID_FS_H */
|
||||
|
||||
Reference in New Issue
Block a user