Skip to content

Commit 59b1c2a

Browse files
committed
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
2 parents 6271f6e + 82c6dd2 commit 59b1c2a

4 files changed

Lines changed: 42 additions & 41 deletions

File tree

fs/notify/fanotify/fanotify.c

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <linux/sched/mm.h>
1515
#include <linux/statfs.h>
1616
#include <linux/stringhash.h>
17+
#include <linux/pidfs.h>
1718

1819
#include "fanotify.h"
1920

@@ -120,10 +121,7 @@ static bool fanotify_error_event_equal(struct fanotify_error_event *fee1,
120121
struct fanotify_error_event *fee2)
121122
{
122123
/* Error events against the same file system are always merged. */
123-
if (!fanotify_fsid_equal(&fee1->fsid, &fee2->fsid))
124-
return false;
125-
126-
return true;
124+
return fanotify_fsid_equal(&fee1->fsid, &fee2->fsid);
127125
}
128126

129127
static bool fanotify_should_merge(struct fanotify_event *old,
@@ -842,6 +840,15 @@ static struct fanotify_event *fanotify_alloc_event(
842840
/* Whoever is interested in the event, pays for the allocation. */
843841
old_memcg = set_active_memcg(group->memcg);
844842

843+
if (FAN_GROUP_FLAG(group, FAN_REPORT_TID))
844+
pid = task_pid(current);
845+
else
846+
pid = task_tgid(current);
847+
848+
if (FAN_GROUP_FLAG(group, FAN_REPORT_PIDFD) &&
849+
pidfs_register_pid_gfp(pid, gfp))
850+
goto out;
851+
845852
if (fanotify_is_perm_event(mask)) {
846853
event = fanotify_alloc_perm_event(data, data_type, gfp);
847854
} else if (fanotify_is_error_event(mask)) {
@@ -863,15 +870,10 @@ static struct fanotify_event *fanotify_alloc_event(
863870
if (!event)
864871
goto out;
865872

866-
if (FAN_GROUP_FLAG(group, FAN_REPORT_TID))
867-
pid = get_pid(task_pid(current));
868-
else
869-
pid = get_pid(task_tgid(current));
870-
871873
/* Mix event info, FAN_ONDIR flag and pid into event merge key */
872874
hash ^= hash_long((unsigned long)pid | ondir, FANOTIFY_EVENT_HASH_BITS);
873875
fanotify_init_event(event, hash, mask);
874-
event->pid = pid;
876+
event->pid = get_pid(pid);
875877

876878
out:
877879
set_active_memcg(old_memcg);

fs/notify/fanotify/fanotify_user.c

Lines changed: 7 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <linux/memcontrol.h>
2020
#include <linux/statfs.h>
2121
#include <linux/exportfs.h>
22+
#include <linux/pidfd.h>
2223

2324
#include <asm/ioctls.h>
2425

@@ -903,25 +904,13 @@ static ssize_t copy_event_to_user(struct fsnotify_group *group,
903904
metadata.fd = fd >= 0 ? fd : FAN_NOFD;
904905

905906
if (pidfd_mode) {
906-
/*
907-
* Complain if the FAN_REPORT_PIDFD and FAN_REPORT_TID mutual
908-
* exclusion is ever lifted. At the time of incoporating pidfd
909-
* support within fanotify, the pidfd API only supported the
910-
* creation of pidfds for thread-group leaders.
911-
*/
912-
WARN_ON_ONCE(FAN_GROUP_FLAG(group, FAN_REPORT_TID));
907+
unsigned int pidfd_flags = PIDFD_STALE;
913908

914-
/*
915-
* The PIDTYPE_TGID check for an event->pid is performed
916-
* preemptively in an attempt to catch out cases where the event
917-
* listener reads events after the event generating process has
918-
* already terminated. Depending on flag FAN_REPORT_FD_ERROR,
919-
* report either -ESRCH or FAN_NOPIDFD to the event listener in
920-
* those cases with all other pidfd creation errors reported as
921-
* the error code itself or as FAN_EPIDFD.
922-
*/
923-
if (metadata.pid && pid_has_task(event->pid, PIDTYPE_TGID))
924-
pidfd = pidfd_prepare(event->pid, 0, &pidfd_file);
909+
if (FAN_GROUP_FLAG(group, FAN_REPORT_TID))
910+
pidfd_flags |= PIDFD_THREAD;
911+
912+
if (metadata.pid)
913+
pidfd = pidfd_prepare(event->pid, pidfd_flags, &pidfd_file);
925914

926915
if (!FAN_GROUP_FLAG(group, FAN_REPORT_FD_ERROR) && pidfd < 0)
927916
pidfd = pidfd == -ESRCH ? FAN_NOPIDFD : FAN_EPIDFD;
@@ -1628,14 +1617,6 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags)
16281617
#endif
16291618
return -EINVAL;
16301619

1631-
/*
1632-
* A pidfd can only be returned for a thread-group leader; thus
1633-
* FAN_REPORT_PIDFD and FAN_REPORT_TID need to remain mutually
1634-
* exclusive.
1635-
*/
1636-
if ((flags & FAN_REPORT_PIDFD) && (flags & FAN_REPORT_TID))
1637-
return -EINVAL;
1638-
16391620
/* Don't allow mixing mnt events with inode events for now */
16401621
if (flags & FAN_REPORT_MNT) {
16411622
if (class != FAN_CLASS_NOTIF)

fs/pidfs.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -977,14 +977,16 @@ static void pidfs_put_data(void *data)
977977
}
978978

979979
/**
980-
* pidfs_register_pid - register a struct pid in pidfs
980+
* pidfs_register_pid_gfp - register a struct pid in pidfs with custom GFP
981+
* flags
981982
* @pid: pid to pin
983+
* @gfp: GFP flags for memory allocation
982984
*
983-
* Register a struct pid in pidfs.
985+
* Register a struct pid in pidfs with custom GFP flags.
984986
*
985987
* Return: On success zero, on error a negative error code is returned.
986988
*/
987-
int pidfs_register_pid(struct pid *pid)
989+
int pidfs_register_pid_gfp(struct pid *pid, gfp_t gfp)
988990
{
989991
struct pidfs_attr *new_attr __free(kfree) = NULL;
990992
struct pidfs_attr *attr;
@@ -1000,7 +1002,7 @@ int pidfs_register_pid(struct pid *pid)
10001002
if (attr)
10011003
return 0;
10021004

1003-
new_attr = kmem_cache_zalloc(pidfs_attr_cachep, GFP_KERNEL);
1005+
new_attr = kmem_cache_zalloc(pidfs_attr_cachep, gfp);
10041006
if (!new_attr)
10051007
return -ENOMEM;
10061008

include/linux/pidfs.h

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
#ifndef _LINUX_PID_FS_H
33
#define _LINUX_PID_FS_H
44

5+
#include <linux/gfp_types.h>
6+
57
struct coredump_params;
68

79
struct file *pidfs_alloc_file(struct pid *pid, unsigned int flags);
@@ -14,7 +16,21 @@ void pidfs_exit(struct task_struct *tsk);
1416
void pidfs_coredump(const struct coredump_params *cprm);
1517
#endif
1618
extern const struct dentry_operations pidfs_dentry_operations;
17-
int pidfs_register_pid(struct pid *pid);
19+
int pidfs_register_pid_gfp(struct pid *pid, gfp_t gfp);
20+
21+
/**
22+
* pidfs_register_pid - register a struct pid in pidfs
23+
* @pid: pid to pin
24+
*
25+
* Register a struct pid in pidfs.
26+
*
27+
* Return: On success zero, on error a negative error code is returned.
28+
*/
29+
static inline int pidfs_register_pid(struct pid *pid)
30+
{
31+
return pidfs_register_pid_gfp(pid, GFP_KERNEL);
32+
}
33+
1834
void pidfs_free_pid(struct pid *pid);
1935

2036
#endif /* _LINUX_PID_FS_H */

0 commit comments

Comments
 (0)