[PATCH 1/3] file: add fd_except cleanup class

From: Andreas Gruenbacher

Date: Sun Jun 07 2026 - 12:43:48 EST


CLASS(fd_except, f)(fd, mask) allows to specify whether to accept or reject
O_PATH file descriptors by passing a mode value of 0 or FMODE_PATH rather than
using a specific cleanup class for each case (CLASS(fd, f)(fd) or CLASS(fd_raw,
f)(fd)).

Signed-off-by: Andreas Gruenbacher <agruenba@xxxxxxxxxx>
---
fs/file.c | 5 +++++
include/linux/file.h | 2 ++
2 files changed, 7 insertions(+)

diff --git a/fs/file.c b/fs/file.c
index 2c81c0b162d0..c34049b36e6f 100644
--- a/fs/file.c
+++ b/fs/file.c
@@ -1211,6 +1211,11 @@ struct fd fdget(unsigned int fd)
}
EXPORT_SYMBOL(fdget);

+struct fd fdget_except(unsigned int fd, fmode_t mask)
+{
+ return __fget_light(fd, mask);
+}
+
struct fd fdget_raw(unsigned int fd)
{
return __fget_light(fd, 0);
diff --git a/include/linux/file.h b/include/linux/file.h
index 27484b444d31..947765f064fe 100644
--- a/include/linux/file.h
+++ b/include/linux/file.h
@@ -70,6 +70,7 @@ extern struct file *fget_task_next(struct task_struct *task, unsigned int *fd);
extern void __f_unlock_pos(struct file *);

struct fd fdget(unsigned int fd);
+struct fd fdget_except(unsigned int fd, fmode_t mask);
struct fd fdget_raw(unsigned int fd);
struct fd fdget_pos(unsigned int fd);

@@ -81,6 +82,7 @@ static inline void fdput_pos(struct fd f)
}

DEFINE_CLASS(fd, struct fd, fdput(_T), fdget(fd), int fd)
+DEFINE_CLASS(fd_except, struct fd, fdput(_T), fdget_except(fd, mask), int fd, fmode_t mask)
DEFINE_CLASS(fd_raw, struct fd, fdput(_T), fdget_raw(fd), int fd)
DEFINE_CLASS(fd_pos, struct fd, fdput_pos(_T), fdget_pos(fd), int fd)

--
2.54.0