summaryrefslogtreecommitdiff
path: root/fs/file.c
diff options
context:
space:
mode:
authorMark Brown <broonie@kernel.org>2023-08-18 22:46:19 +0100
committerMark Brown <broonie@kernel.org>2023-08-18 22:46:19 +0100
commitab4724302feedcd33633fd409667a8ee0016f13d (patch)
tree245c7082ca66780da02df0b7cedc91a5090b795f /fs/file.c
parent46f53bde6e69edf8a2e0943babb3f160b30ee436 (diff)
parentef75e767167a8f30c7690bc4689dba76329ee06e (diff)
Add cs42l43 PC focused SoundWire CODEC
Merge series from Charles Keepax <ckeepax@opensource.cirrus.com>: This patch chain adds support for the Cirrus Logic cs42l43 PC focused SoundWire CODEC.
Diffstat (limited to 'fs/file.c')
-rw-r--r--fs/file.c18
1 files changed, 17 insertions, 1 deletions
diff --git a/fs/file.c b/fs/file.c
index 35c62b54c9d6..3fd003a8604f 100644
--- a/fs/file.c
+++ b/fs/file.c
@@ -1036,12 +1036,28 @@ unsigned long __fdget_raw(unsigned int fd)
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 || file->f_op->iterate_shared);
+}
+
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);
}