From 4e4a913afdd0bdc3bcb53c7e076eef423fb60429 Mon Sep 17 00:00:00 2001 From: Kienan Stewart Date: Mon, 2 Dec 2024 16:15:40 +0000 Subject: [PATCH] Fix: lookup_fdget_rcu removed in Linux 6.13.0-rc1 See upstream commit 8fd3395ec9051a52828fcca2328cb50a69dea8ef: commit 8fd3395ec9051a52828fcca2328cb50a69dea8ef Author: Al Viro Date: Wed Jul 31 11:49:04 2024 -0400 get rid of ...lookup...fdget_rcu() family Once upon a time, predecessors of those used to do file lookup without bumping a refcount, provided that caller held rcu_read_lock() across the lookup and whatever it wanted to read from the struct file found. When struct file allocation switched to SLAB_TYPESAFE_BY_RCU, that stopped being feasible and these primitives started to bump the file refcount for lookup result, requiring the caller to call fput() afterwards. But that turned them pointless - e.g. rcu_read_lock(); file = lookup_fdget_rcu(fd); rcu_read_unlock(); is equivalent to file = fget_raw(fd); and all callers of lookup_fdget_rcu() are of that form. Similarly, task_lookup_fdget_rcu() calls can be replaced with calling fget_task(). task_lookup_next_fdget_rcu() doesn't have direct counterparts, but its callers would be happier if we replaced it with an analogue that deals with RCU internally. Reviewed-by: Christian Brauner Signed-off-by: Al Viro Change-Id: I98f1c617e8bd7ad9db7a9af2a1fa76c5eb26e8b8 Signed-off-by: Kienan Stewart Signed-off-by: Mathieu Desnoyers --- include/wrapper/fdtable.h | 9 ++++++++- include/wrapper/file_ref.h | 5 ++--- src/lttng-abi.c | 28 +++++++++++++++++++++------- 3 files changed, 31 insertions(+), 11 deletions(-) diff --git a/include/wrapper/fdtable.h b/include/wrapper/fdtable.h index bd03c08b..7807ab7f 100644 --- a/include/wrapper/fdtable.h +++ b/include/wrapper/fdtable.h @@ -9,10 +9,17 @@ #define _LTTNG_WRAPPER_FDTABLE_H #include +#include #include #include -#if (LTTNG_LINUX_VERSION_CODE >= LTTNG_KERNEL_VERSION(6,7,0)) +#if (LTTNG_LINUX_VERSION_CODE >= LTTNG_KERNEL_VERSION(6,13,0)) +static inline +struct file *lttng_lookup_fdget_rcu(unsigned int fd) +{ + return fget_raw(fd); +} +#elif (LTTNG_LINUX_VERSION_CODE >= LTTNG_KERNEL_VERSION(6,7,0)) static inline struct file *lttng_lookup_fdget_rcu(unsigned int fd) { diff --git a/include/wrapper/file_ref.h b/include/wrapper/file_ref.h index fd2b1238..b44ada09 100644 --- a/include/wrapper/file_ref.h +++ b/include/wrapper/file_ref.h @@ -18,10 +18,9 @@ bool lttng_file_ref_get(struct file *file) return file_ref_get(&file->f_ref); } -static inline +static inline __must_check bool lttng_file_ref_put(struct file *file) { - /* This is __must_check */ return file_ref_put(&file->f_ref); } @@ -33,7 +32,7 @@ bool lttng_file_ref_get(struct file *file) return true; } -static inline +static inline __must_check bool lttng_file_ref_put(struct file *file) { atomic_long_dec(&file->f_count); diff --git a/src/lttng-abi.c b/src/lttng-abi.c index da375760..cc1ff1f4 100644 --- a/src/lttng-abi.c +++ b/src/lttng-abi.c @@ -577,7 +577,9 @@ int lttng_abi_create_channel(struct file *session_file, return chan_fd; chan_error: - lttng_file_ref_put(session_file); + if (!lttng_file_ref_put(session_file)) { + ret = -EINVAL; + } refcount_error: fput(chan_file); file_error: @@ -2450,7 +2452,9 @@ int lttng_abi_open_event_notifier_group_stream(struct file *notif_file) return ret; fd_error: - lttng_file_ref_put(notif_file); + if (!lttng_file_ref_put(notif_file)) { + /* Don't change return code */ + } refcount_error: event_notifier_group->ops->priv->buffer_read_close(buf); return ret; @@ -2777,7 +2781,9 @@ int lttng_abi_create_event_recorder_enabler(struct file *channel_file, return event_fd; event_error: - lttng_file_ref_put(channel_file); + if (!lttng_file_ref_put(channel_file)) { + ret = -EINVAL; + } refcount_error: fput(event_file); file_error: @@ -2937,7 +2943,9 @@ int lttng_abi_create_event_counter_enabler(struct file *channel_file, return event_fd; event_error: - lttng_file_ref_put(channel_file); + if (!lttng_file_ref_put(channel_file)) { + /* Don't change return code */ + } refcount_error: fput(event_file); file_error: @@ -3190,7 +3198,9 @@ int lttng_abi_create_event_notifier(struct file *event_notifier_group_file, return event_notifier_fd; event_notifier_error: - lttng_file_ref_put(event_notifier_group_file); + if (!lttng_file_ref_put(event_notifier_group_file)) { + /* Don't change return code */ + } refcount_error: fput(event_notifier_file); file_error: @@ -3266,7 +3276,9 @@ long lttng_abi_session_create_counter( return counter_fd; create_error: - lttng_file_ref_put(session->priv->file); + if (!lttng_file_ref_put(session->priv->file)) { + /* Don't change return code */ + } refcount_error: fput(counter_file); file_error: @@ -3362,7 +3374,9 @@ long lttng_abi_event_notifier_group_create_error_counter( return counter_fd; create_error: - lttng_file_ref_put(event_notifier_group_file); + if (!lttng_file_ref_put(event_notifier_group_file)) { + /* Don't change return code */ + } refcount_error: fput(counter_file); file_error: -- 2.39.5