FAILED: patch "[PATCH] fscontext: do not consume log entries when returning" failed to apply to 5.4-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 5.4-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-5.4.y
git checkout FETCH_HEAD
git cherry-pick -x 72d271a7baa7062cb27e774ac37c5459c6d20e22
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2025101537-visor-thank-7800@gregkh' --subject-prefix 'PATCH 5.4.y' HEAD^..
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 72d271a7baa7062cb27e774ac37c5459c6d20e22 Mon Sep 17 00:00:00 2001
From: Aleksa Sarai <[email protected]>
Date: Thu, 7 Aug 2025 03:55:23 +1000
Subject: [PATCH] fscontext: do not consume log entries when returning
-EMSGSIZE
Userspace generally expects APIs that return -EMSGSIZE to allow for them to adjust their buffer size and retry the operation. However, the fscontext log would previously clear the message even in the -EMSGSIZE case.
Given that it is very cheap for us to check whether the buffer is too small before we remove the message from the ring buffer, let's just do that instead. While we're at it, refactor some fscontext_read() into a separate helper to make the ring buffer logic a bit easier to read.
fs/fsopen.c +38 -32
@@ -18,50 +18,56 @@#include "internal.h" #include "mount.h" +static inline const char *fetch_message_locked (struct fc_log *log,size_t len, +bool *need_free) +{ +const char *p; +int index; + +if (unlikely (log->head == log->tail)) +return ERR_PTR (-ENODATA ); + + index = log->tail & (ARRAY_SIZE (log->buffer) -1 ); + p = log->buffer[index]; +if (unlikely (strlen (p) > len)) +return ERR_PTR (-EMSGSIZE ); + + log->buffer[index] =NULL ; + *need_free = log->need_free & (1 << index); + log->need_free &= ~(1 << index); + log->tail++; + +return p; +} +/* * Allow the user to read back any error, warning or informational messages. +* Only one message is returned for each read(2) call. */ static ssize_t fscontext_read (struct file *file,char __user *_buf,size_t len,loff_t *pos) {struct fs_context *fc = file->private_data; -struct fc_log *log = fc->log.log; -unsigned int logsize =ARRAY_SIZE (log->buffer); -ssize_t ret; -char *p; +ssize_t err; + const char *p __free(kfree) = NULL, *message;bool need_free; -int index, n; +int n; - ret =mutex_lock_interruptible (&fc->uapi_mutex); -if (ret <0 ) -return ret; - -if (log->head == log->tail) { -mutex_unlock (&fc->uapi_mutex); -return -ENODATA ; - } - - index = log->tail & (logsize -1 ); - p = log->buffer[index]; - need_free = log->need_free & (1 << index); - log->buffer[index] =NULL ; - log->need_free &= ~(1 << index); - log->tail++; + err =mutex_lock_interruptible (&fc->uapi_mutex); +if (err <0 ) +return err; + message =fetch_message_locked (fc->log.log, len, &need_free);mutex_unlock (&fc->uapi_mutex); +if (IS_ERR (message)) +return PTR_ERR (message); - ret = -EMSGSIZE ; - n =strlen (p); -if (n > len) - goto err_free; - ret = -EFAULT ; -if (copy_to_user (_buf, p, n) !=0 ) - goto err_free; - ret = n; - -err_free:if (need_free) -kfree (p); -return ret; + p = message; + + n =strlen (message); +if (copy_to_user (_buf, message, n)) +return -EFAULT ; +return n; }static int fscontext_release (struct inode *inode,struct file *file)