From 9fd02b465cfd3c26fb0cc9340d64ee019d2ba906 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 7 Aug 2023 09:57:28 +0200 Subject: [PATCH] 5.10-stable patches added patches: file-reinstate-f_pos-locking-optimization-for-regular-files.patch --- ...cking-optimization-for-regular-files.patch | 64 +++++++++++++++++++ queue-5.10/series | 1 + 2 files changed, 65 insertions(+) create mode 100644 queue-5.10/file-reinstate-f_pos-locking-optimization-for-regular-files.patch diff --git a/queue-5.10/file-reinstate-f_pos-locking-optimization-for-regular-files.patch b/queue-5.10/file-reinstate-f_pos-locking-optimization-for-regular-files.patch new file mode 100644 index 00000000000..c12c8fb9841 --- /dev/null +++ b/queue-5.10/file-reinstate-f_pos-locking-optimization-for-regular-files.patch @@ -0,0 +1,64 @@ +From 797964253d358cf8d705614dda394dbe30120223 Mon Sep 17 00:00:00 2001 +From: Linus Torvalds +Date: Thu, 3 Aug 2023 11:35:53 -0700 +Subject: file: reinstate f_pos locking optimization for regular files + +From: Linus Torvalds + +commit 797964253d358cf8d705614dda394dbe30120223 upstream. + +In commit 20ea1e7d13c1 ("file: always lock position for +FMODE_ATOMIC_POS") we ended up always taking the file pos lock, because +pidfd_getfd() could get a reference to the file even when it didn't have +an elevated file count due to threading of other sharing cases. + +But Mateusz Guzik reports that the extra locking is actually measurable, +so let's re-introduce the optimization, and only force the locking for +directory traversal. + +Directories need the lock for correctness reasons, while regular files +only need it for "POSIX semantics". Since pidfd_getfd() is about +debuggers etc special things that are _way_ outside of POSIX, we can +relax the rules for that case. + +Reported-by: Mateusz Guzik +Cc: Christian Brauner +Link: https://lore.kernel.org/linux-fsdevel/20230803095311.ijpvhx3fyrbkasul@f/ +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman +--- + fs/file.c | 18 +++++++++++++++++- + 1 file changed, 17 insertions(+), 1 deletion(-) + +--- a/fs/file.c ++++ b/fs/file.c +@@ -1007,12 +1007,28 @@ unsigned long __fdget_raw(unsigned int f + return __fget_light(fd, 0); + } + ++/* ++ * Try to avoid f_pos locking. We only need it if the ++ * file is marked for FMODE_ATOMIC_POS, and it can be ++ * accessed multiple ways. ++ * ++ * Always do it for directories, because pidfd_getfd() ++ * can make a file accessible even if it otherwise would ++ * not be, and for directories this is a correctness ++ * issue, not a "POSIX requirement". ++ */ ++static inline bool file_needs_f_pos_lock(struct file *file) ++{ ++ return (file->f_mode & FMODE_ATOMIC_POS) && ++ (file_count(file) > 1 || S_ISDIR(file_inode(file)->i_mode)); ++} ++ + unsigned long __fdget_pos(unsigned int fd) + { + unsigned long v = __fdget(fd); + struct file *file = (struct file *)(v & ~3); + +- if (file && (file->f_mode & FMODE_ATOMIC_POS)) { ++ if (file && file_needs_f_pos_lock(file)) { + v |= FDPUT_POS_UNLOCK; + mutex_lock(&file->f_pos_lock); + } diff --git a/queue-5.10/series b/queue-5.10/series index 37d3b13e5c0..aaa344e5c41 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -173,3 +173,4 @@ net-tap_open-set-sk_uid-from-current_fsuid.patch bpf-disable-preemption-in-bpf_event_output.patch open-make-resolve_cached-correctly-test-for-o_tmpfile.patch drm-ttm-check-null-pointer-before-accessing-when-swapping.patch +file-reinstate-f_pos-locking-optimization-for-regular-files.patch -- 2.47.3