linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	stable@vger.kernel.org, Michael Kerrisk <mtk.manpages@gmail.com>,
	Yongzhi Pan <panyongzhi@gmail.com>,
	Jonathan Corbet <corbet@lwn.net>,
	David Vrabel <david.vrabel@citrix.com>,
	Juergen Gross <jgross@suse.com>,
	Miklos Szeredi <miklos@szeredi.hu>, Tejun Heo <tj@kernel.org>,
	Kirill Tkhai <ktkhai@virtuozzo.com>,
	Arnd Bergmann <arnd@arndb.de>, Christoph Hellwig <hch@lst.de>,
	Julia Lawall <Julia.Lawall@lip6.fr>,
	Nikolaus Rath <Nikolaus@rath.org>,
	Han-Wen Nienhuys <hanwen@google.com>,
	Kirill Smelkov <kirr@nexedi.com>,
	Linus Torvalds <torvalds@linux-foundation.org>,
	"Sasha Levin (Microsoft)" <sashal@kernel.org>
Subject: [PATCH 5.0 080/122] fs: stream_open - opener for stream-like files so that read and write can run simultaneously without deadlock
Date: Mon,  6 May 2019 16:32:18 +0200	[thread overview]
Message-ID: <20190506143102.005836007@linuxfoundation.org> (raw)
In-Reply-To: <20190506143054.670334917@linuxfoundation.org>

[ Upstream commit 10dce8af34226d90fa56746a934f8da5dcdba3df ]

Commit 9c225f2655e3 ("vfs: atomic f_pos accesses as per POSIX") added
locking for file.f_pos access and in particular made concurrent read and
write not possible - now both those functions take f_pos lock for the
whole run, and so if e.g. a read is blocked waiting for data, write will
deadlock waiting for that read to complete.

This caused regression for stream-like files where previously read and
write could run simultaneously, but after that patch could not do so
anymore. See e.g. commit 581d21a2d02a ("xenbus: fix deadlock on writes
to /proc/xen/xenbus") which fixes such regression for particular case of
/proc/xen/xenbus.

The patch that added f_pos lock in 2014 did so to guarantee POSIX thread
safety for read/write/lseek and added the locking to file descriptors of
all regular files. In 2014 that thread-safety problem was not new as it
was already discussed earlier in 2006.

However even though 2006'th version of Linus's patch was adding f_pos
locking "only for files that are marked seekable with FMODE_LSEEK (thus
avoiding the stream-like objects like pipes and sockets)", the 2014
version - the one that actually made it into the tree as 9c225f2655e3 -
is doing so irregardless of whether a file is seekable or not.

See

    https://lore.kernel.org/lkml/53022DB1.4070805@gmail.com/
    https://lwn.net/Articles/180387
    https://lwn.net/Articles/180396

for historic context.

The reason that it did so is, probably, that there are many files that
are marked non-seekable, but e.g. their read implementation actually
depends on knowing current position to correctly handle the read. Some
examples:

	kernel/power/user.c		snapshot_read
	fs/debugfs/file.c		u32_array_read
	fs/fuse/control.c		fuse_conn_waiting_read + ...
	drivers/hwmon/asus_atk0110.c	atk_debugfs_ggrp_read
	arch/s390/hypfs/inode.c		hypfs_read_iter
	...

Despite that, many nonseekable_open users implement read and write with
pure stream semantics - they don't depend on passed ppos at all. And for
those cases where read could wait for something inside, it creates a
situation similar to xenbus - the write could be never made to go until
read is done, and read is waiting for some, potentially external, event,
for potentially unbounded time -> deadlock.

Besides xenbus, there are 14 such places in the kernel that I've found
with semantic patch (see below):

	drivers/xen/evtchn.c:667:8-24: ERROR: evtchn_fops: .read() can deadlock .write()
	drivers/isdn/capi/capi.c:963:8-24: ERROR: capi_fops: .read() can deadlock .write()
	drivers/input/evdev.c:527:1-17: ERROR: evdev_fops: .read() can deadlock .write()
	drivers/char/pcmcia/cm4000_cs.c:1685:7-23: ERROR: cm4000_fops: .read() can deadlock .write()
	net/rfkill/core.c:1146:8-24: ERROR: rfkill_fops: .read() can deadlock .write()
	drivers/s390/char/fs3270.c:488:1-17: ERROR: fs3270_fops: .read() can deadlock .write()
	drivers/usb/misc/ldusb.c:310:1-17: ERROR: ld_usb_fops: .read() can deadlock .write()
	drivers/hid/uhid.c:635:1-17: ERROR: uhid_fops: .read() can deadlock .write()
	net/batman-adv/icmp_socket.c:80:1-17: ERROR: batadv_fops: .read() can deadlock .write()
	drivers/media/rc/lirc_dev.c:198:1-17: ERROR: lirc_fops: .read() can deadlock .write()
	drivers/leds/uleds.c:77:1-17: ERROR: uleds_fops: .read() can deadlock .write()
	drivers/input/misc/uinput.c:400:1-17: ERROR: uinput_fops: .read() can deadlock .write()
	drivers/infiniband/core/user_mad.c:985:7-23: ERROR: umad_fops: .read() can deadlock .write()
	drivers/gnss/core.c:45:1-17: ERROR: gnss_fops: .read() can deadlock .write()

In addition to the cases above another regression caused by f_pos
locking is that now FUSE filesystems that implement open with
FOPEN_NONSEEKABLE flag, can no longer implement bidirectional
stream-like files - for the same reason as above e.g. read can deadlock
write locking on file.f_pos in the kernel.

FUSE's FOPEN_NONSEEKABLE was added in 2008 in a7c1b990f715 ("fuse:
implement nonseekable open") to support OSSPD. OSSPD implements /dev/dsp
in userspace with FOPEN_NONSEEKABLE flag, with corresponding read and
write routines not depending on current position at all, and with both
read and write being potentially blocking operations:

See

    https://github.com/libfuse/osspd
    https://lwn.net/Articles/308445

    https://github.com/libfuse/osspd/blob/14a9cff0/osspd.c#L1406
    https://github.com/libfuse/osspd/blob/14a9cff0/osspd.c#L1438-L1477
    https://github.com/libfuse/osspd/blob/14a9cff0/osspd.c#L1479-L1510

Corresponding libfuse example/test also describes FOPEN_NONSEEKABLE as
"somewhat pipe-like files ..." with read handler not using offset.
However that test implements only read without write and cannot exercise
the deadlock scenario:

    https://github.com/libfuse/libfuse/blob/fuse-3.4.2-3-ga1bff7d/example/poll.c#L124-L131
    https://github.com/libfuse/libfuse/blob/fuse-3.4.2-3-ga1bff7d/example/poll.c#L146-L163
    https://github.com/libfuse/libfuse/blob/fuse-3.4.2-3-ga1bff7d/example/poll.c#L209-L216

I've actually hit the read vs write deadlock for real while implementing
my FUSE filesystem where there is /head/watch file, for which open
creates separate bidirectional socket-like stream in between filesystem
and its user with both read and write being later performed
simultaneously. And there it is semantically not easy to split the
stream into two separate read-only and write-only channels:

    https://lab.nexedi.com/kirr/wendelin.core/blob/f13aa600/wcfs/wcfs.go#L88-169

Let's fix this regression. The plan is:

1. We can't change nonseekable_open to include &~FMODE_ATOMIC_POS -
   doing so would break many in-kernel nonseekable_open users which
   actually use ppos in read/write handlers.

2. Add stream_open() to kernel to open stream-like non-seekable file
   descriptors. Read and write on such file descriptors would never use
   nor change ppos. And with that property on stream-like files read and
   write will be running without taking f_pos lock - i.e. read and write
   could be running simultaneously.

3. With semantic patch search and convert to stream_open all in-kernel
   nonseekable_open users for which read and write actually do not
   depend on ppos and where there is no other methods in file_operations
   which assume @offset access.

4. Add FOPEN_STREAM to fs/fuse/ and open in-kernel file-descriptors via
   steam_open if that bit is present in filesystem open reply.

   It was tempting to change fs/fuse/ open handler to use stream_open
   instead of nonseekable_open on just FOPEN_NONSEEKABLE flags, but
   grepping through Debian codesearch shows users of FOPEN_NONSEEKABLE,
   and in particular GVFS which actually uses offset in its read and
   write handlers

	https://codesearch.debian.net/search?q=-%3Enonseekable+%3D
	https://gitlab.gnome.org/GNOME/gvfs/blob/1.40.0-6-gcbc54396/client/gvfsfusedaemon.c#L1080
	https://gitlab.gnome.org/GNOME/gvfs/blob/1.40.0-6-gcbc54396/client/gvfsfusedaemon.c#L1247-1346
	https://gitlab.gnome.org/GNOME/gvfs/blob/1.40.0-6-gcbc54396/client/gvfsfusedaemon.c#L1399-1481

   so if we would do such a change it will break a real user.

5. Add stream_open and FOPEN_STREAM handling to stable kernels starting
   from v3.14+ (the kernel where 9c225f2655 first appeared).

   This will allow to patch OSSPD and other FUSE filesystems that
   provide stream-like files to return FOPEN_STREAM | FOPEN_NONSEEKABLE
   in their open handler and this way avoid the deadlock on all kernel
   versions. This should work because fs/fuse/ ignores unknown open
   flags returned from a filesystem and so passing FOPEN_STREAM to a
   kernel that is not aware of this flag cannot hurt. In turn the kernel
   that is not aware of FOPEN_STREAM will be < v3.14 where just
   FOPEN_NONSEEKABLE is sufficient to implement streams without read vs
   write deadlock.

This patch adds stream_open, converts /proc/xen/xenbus to it and adds
semantic patch to automatically locate in-kernel places that are either
required to be converted due to read vs write deadlock, or that are just
safe to be converted because read and write do not use ppos and there
are no other funky methods in file_operations.

Regarding semantic patch I've verified each generated change manually -
that it is correct to convert - and each other nonseekable_open instance
left - that it is either not correct to convert there, or that it is not
converted due to current stream_open.cocci limitations.

The script also does not convert files that should be valid to convert,
but that currently have .llseek = noop_llseek or generic_file_llseek for
unknown reason despite file being opened with nonseekable_open (e.g.
drivers/input/mousedev.c)

Cc: Michael Kerrisk <mtk.manpages@gmail.com>
Cc: Yongzhi Pan <panyongzhi@gmail.com>
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: David Vrabel <david.vrabel@citrix.com>
Cc: Juergen Gross <jgross@suse.com>
Cc: Miklos Szeredi <miklos@szeredi.hu>
Cc: Tejun Heo <tj@kernel.org>
Cc: Kirill Tkhai <ktkhai@virtuozzo.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Julia Lawall <Julia.Lawall@lip6.fr>
Cc: Nikolaus Rath <Nikolaus@rath.org>
Cc: Han-Wen Nienhuys <hanwen@google.com>
Signed-off-by: Kirill Smelkov <kirr@nexedi.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Sasha Levin (Microsoft) <sashal@kernel.org>
---
 drivers/xen/xenbus/xenbus_dev_frontend.c |   4 +-
 fs/open.c                                |  18 ++
 fs/read_write.c                          |   5 +-
 include/linux/fs.h                       |   4 +
 scripts/coccinelle/api/stream_open.cocci | 363 +++++++++++++++++++++++
 5 files changed, 389 insertions(+), 5 deletions(-)
 create mode 100644 scripts/coccinelle/api/stream_open.cocci

diff --git a/drivers/xen/xenbus/xenbus_dev_frontend.c b/drivers/xen/xenbus/xenbus_dev_frontend.c
index c3e201025ef0..0782ff3c2273 100644
--- a/drivers/xen/xenbus/xenbus_dev_frontend.c
+++ b/drivers/xen/xenbus/xenbus_dev_frontend.c
@@ -622,9 +622,7 @@ static int xenbus_file_open(struct inode *inode, struct file *filp)
 	if (xen_store_evtchn == 0)
 		return -ENOENT;
 
-	nonseekable_open(inode, filp);
-
-	filp->f_mode &= ~FMODE_ATOMIC_POS; /* cdev-style semantics */
+	stream_open(inode, filp);
 
 	u = kzalloc(sizeof(*u), GFP_KERNEL);
 	if (u == NULL)
diff --git a/fs/open.c b/fs/open.c
index f1c2f855fd43..a00350018a47 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -1215,3 +1215,21 @@ int nonseekable_open(struct inode *inode, struct file *filp)
 }
 
 EXPORT_SYMBOL(nonseekable_open);
+
+/*
+ * stream_open is used by subsystems that want stream-like file descriptors.
+ * Such file descriptors are not seekable and don't have notion of position
+ * (file.f_pos is always 0). Contrary to file descriptors of other regular
+ * files, .read() and .write() can run simultaneously.
+ *
+ * stream_open never fails and is marked to return int so that it could be
+ * directly used as file_operations.open .
+ */
+int stream_open(struct inode *inode, struct file *filp)
+{
+	filp->f_mode &= ~(FMODE_LSEEK | FMODE_PREAD | FMODE_PWRITE | FMODE_ATOMIC_POS);
+	filp->f_mode |= FMODE_STREAM;
+	return 0;
+}
+
+EXPORT_SYMBOL(stream_open);
diff --git a/fs/read_write.c b/fs/read_write.c
index 27b69b85d49f..3d3194e32201 100644
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -560,12 +560,13 @@ ssize_t vfs_write(struct file *file, const char __user *buf, size_t count, loff_
 
 static inline loff_t file_pos_read(struct file *file)
 {
-	return file->f_pos;
+	return file->f_mode & FMODE_STREAM ? 0 : file->f_pos;
 }
 
 static inline void file_pos_write(struct file *file, loff_t pos)
 {
-	file->f_pos = pos;
+	if ((file->f_mode & FMODE_STREAM) == 0)
+		file->f_pos = pos;
 }
 
 ssize_t ksys_read(unsigned int fd, char __user *buf, size_t count)
diff --git a/include/linux/fs.h b/include/linux/fs.h
index fd423fec8d83..09ce2646c78a 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -153,6 +153,9 @@ typedef int (dio_iodone_t)(struct kiocb *iocb, loff_t offset,
 #define FMODE_OPENED		((__force fmode_t)0x80000)
 #define FMODE_CREATED		((__force fmode_t)0x100000)
 
+/* File is stream-like */
+#define FMODE_STREAM		((__force fmode_t)0x200000)
+
 /* File was opened by fanotify and shouldn't generate fanotify events */
 #define FMODE_NONOTIFY		((__force fmode_t)0x4000000)
 
@@ -3074,6 +3077,7 @@ extern loff_t no_seek_end_llseek_size(struct file *, loff_t, int, loff_t);
 extern loff_t no_seek_end_llseek(struct file *, loff_t, int);
 extern int generic_file_open(struct inode * inode, struct file * filp);
 extern int nonseekable_open(struct inode * inode, struct file * filp);
+extern int stream_open(struct inode * inode, struct file * filp);
 
 #ifdef CONFIG_BLOCK
 typedef void (dio_submit_t)(struct bio *bio, struct inode *inode,
diff --git a/scripts/coccinelle/api/stream_open.cocci b/scripts/coccinelle/api/stream_open.cocci
new file mode 100644
index 000000000000..350145da7669
--- /dev/null
+++ b/scripts/coccinelle/api/stream_open.cocci
@@ -0,0 +1,363 @@
+// SPDX-License-Identifier: GPL-2.0
+// Author: Kirill Smelkov (kirr@nexedi.com)
+//
+// Search for stream-like files that are using nonseekable_open and convert
+// them to stream_open. A stream-like file is a file that does not use ppos in
+// its read and write. Rationale for the conversion is to avoid deadlock in
+// between read and write.
+
+virtual report
+virtual patch
+virtual explain  // explain decisions in the patch (SPFLAGS="-D explain")
+
+// stream-like reader & writer - ones that do not depend on f_pos.
+@ stream_reader @
+identifier readstream, ppos;
+identifier f, buf, len;
+type loff_t;
+@@
+  ssize_t readstream(struct file *f, char *buf, size_t len, loff_t *ppos)
+  {
+    ... when != ppos
+  }
+
+@ stream_writer @
+identifier writestream, ppos;
+identifier f, buf, len;
+type loff_t;
+@@
+  ssize_t writestream(struct file *f, const char *buf, size_t len, loff_t *ppos)
+  {
+    ... when != ppos
+  }
+
+
+// a function that blocks
+@ blocks @
+identifier block_f;
+identifier wait_event =~ "^wait_event_.*";
+@@
+  block_f(...) {
+    ... when exists
+    wait_event(...)
+    ... when exists
+  }
+
+// stream_reader that can block inside.
+//
+// XXX wait_* can be called not directly from current function (e.g. func -> f -> g -> wait())
+// XXX currently reader_blocks supports only direct and 1-level indirect cases.
+@ reader_blocks_direct @
+identifier stream_reader.readstream;
+identifier wait_event =~ "^wait_event_.*";
+@@
+  readstream(...)
+  {
+    ... when exists
+    wait_event(...)
+    ... when exists
+  }
+
+@ reader_blocks_1 @
+identifier stream_reader.readstream;
+identifier blocks.block_f;
+@@
+  readstream(...)
+  {
+    ... when exists
+    block_f(...)
+    ... when exists
+  }
+
+@ reader_blocks depends on reader_blocks_direct || reader_blocks_1 @
+identifier stream_reader.readstream;
+@@
+  readstream(...) {
+    ...
+  }
+
+
+// file_operations + whether they have _any_ .read, .write, .llseek ... at all.
+//
+// XXX add support for file_operations xxx[N] = ...	(sound/core/pcm_native.c)
+@ fops0 @
+identifier fops;
+@@
+  struct file_operations fops = {
+    ...
+  };
+
+@ has_read @
+identifier fops0.fops;
+identifier read_f;
+@@
+  struct file_operations fops = {
+    .read = read_f,
+  };
+
+@ has_read_iter @
+identifier fops0.fops;
+identifier read_iter_f;
+@@
+  struct file_operations fops = {
+    .read_iter = read_iter_f,
+  };
+
+@ has_write @
+identifier fops0.fops;
+identifier write_f;
+@@
+  struct file_operations fops = {
+    .write = write_f,
+  };
+
+@ has_write_iter @
+identifier fops0.fops;
+identifier write_iter_f;
+@@
+  struct file_operations fops = {
+    .write_iter = write_iter_f,
+  };
+
+@ has_llseek @
+identifier fops0.fops;
+identifier llseek_f;
+@@
+  struct file_operations fops = {
+    .llseek = llseek_f,
+  };
+
+@ has_no_llseek @
+identifier fops0.fops;
+@@
+  struct file_operations fops = {
+    .llseek = no_llseek,
+  };
+
+@ has_mmap @
+identifier fops0.fops;
+identifier mmap_f;
+@@
+  struct file_operations fops = {
+    .mmap = mmap_f,
+  };
+
+@ has_copy_file_range @
+identifier fops0.fops;
+identifier copy_file_range_f;
+@@
+  struct file_operations fops = {
+    .copy_file_range = copy_file_range_f,
+  };
+
+@ has_remap_file_range @
+identifier fops0.fops;
+identifier remap_file_range_f;
+@@
+  struct file_operations fops = {
+    .remap_file_range = remap_file_range_f,
+  };
+
+@ has_splice_read @
+identifier fops0.fops;
+identifier splice_read_f;
+@@
+  struct file_operations fops = {
+    .splice_read = splice_read_f,
+  };
+
+@ has_splice_write @
+identifier fops0.fops;
+identifier splice_write_f;
+@@
+  struct file_operations fops = {
+    .splice_write = splice_write_f,
+  };
+
+
+// file_operations that is candidate for stream_open conversion - it does not
+// use mmap and other methods that assume @offset access to file.
+//
+// XXX for simplicity require no .{read/write}_iter and no .splice_{read/write} for now.
+// XXX maybe_steam.fops cannot be used in other rules - it gives "bad rule maybe_stream or bad variable fops".
+@ maybe_stream depends on (!has_llseek || has_no_llseek) && !has_mmap && !has_copy_file_range && !has_remap_file_range && !has_read_iter && !has_write_iter && !has_splice_read && !has_splice_write @
+identifier fops0.fops;
+@@
+  struct file_operations fops = {
+  };
+
+
+// ---- conversions ----
+
+// XXX .open = nonseekable_open -> .open = stream_open
+// XXX .open = func -> openfunc -> nonseekable_open
+
+// read & write
+//
+// if both are used in the same file_operations together with an opener -
+// under that conditions we can use stream_open instead of nonseekable_open.
+@ fops_rw depends on maybe_stream @
+identifier fops0.fops, openfunc;
+identifier stream_reader.readstream;
+identifier stream_writer.writestream;
+@@
+  struct file_operations fops = {
+      .open  = openfunc,
+      .read  = readstream,
+      .write = writestream,
+  };
+
+@ report_rw depends on report @
+identifier fops_rw.openfunc;
+position p1;
+@@
+  openfunc(...) {
+    <...
+     nonseekable_open@p1
+    ...>
+  }
+
+@ script:python depends on report && reader_blocks @
+fops << fops0.fops;
+p << report_rw.p1;
+@@
+coccilib.report.print_report(p[0],
+  "ERROR: %s: .read() can deadlock .write(); change nonseekable_open -> stream_open to fix." % (fops,))
+
+@ script:python depends on report && !reader_blocks @
+fops << fops0.fops;
+p << report_rw.p1;
+@@
+coccilib.report.print_report(p[0],
+  "WARNING: %s: .read() and .write() have stream semantic; safe to change nonseekable_open -> stream_open." % (fops,))
+
+
+@ explain_rw_deadlocked depends on explain && reader_blocks @
+identifier fops_rw.openfunc;
+@@
+  openfunc(...) {
+    <...
+-    nonseekable_open
++    nonseekable_open /* read & write (was deadlock) */
+    ...>
+  }
+
+
+@ explain_rw_nodeadlock depends on explain && !reader_blocks @
+identifier fops_rw.openfunc;
+@@
+  openfunc(...) {
+    <...
+-    nonseekable_open
++    nonseekable_open /* read & write (no direct deadlock) */
+    ...>
+  }
+
+@ patch_rw depends on patch @
+identifier fops_rw.openfunc;
+@@
+  openfunc(...) {
+    <...
+-   nonseekable_open
++   stream_open
+    ...>
+  }
+
+
+// read, but not write
+@ fops_r depends on maybe_stream && !has_write @
+identifier fops0.fops, openfunc;
+identifier stream_reader.readstream;
+@@
+  struct file_operations fops = {
+      .open  = openfunc,
+      .read  = readstream,
+  };
+
+@ report_r depends on report @
+identifier fops_r.openfunc;
+position p1;
+@@
+  openfunc(...) {
+    <...
+    nonseekable_open@p1
+    ...>
+  }
+
+@ script:python depends on report @
+fops << fops0.fops;
+p << report_r.p1;
+@@
+coccilib.report.print_report(p[0],
+  "WARNING: %s: .read() has stream semantic; safe to change nonseekable_open -> stream_open." % (fops,))
+
+@ explain_r depends on explain @
+identifier fops_r.openfunc;
+@@
+  openfunc(...) {
+    <...
+-   nonseekable_open
++   nonseekable_open /* read only */
+    ...>
+  }
+
+@ patch_r depends on patch @
+identifier fops_r.openfunc;
+@@
+  openfunc(...) {
+    <...
+-   nonseekable_open
++   stream_open
+    ...>
+  }
+
+
+// write, but not read
+@ fops_w depends on maybe_stream && !has_read @
+identifier fops0.fops, openfunc;
+identifier stream_writer.writestream;
+@@
+  struct file_operations fops = {
+      .open  = openfunc,
+      .write = writestream,
+  };
+
+@ report_w depends on report @
+identifier fops_w.openfunc;
+position p1;
+@@
+  openfunc(...) {
+    <...
+    nonseekable_open@p1
+    ...>
+  }
+
+@ script:python depends on report @
+fops << fops0.fops;
+p << report_w.p1;
+@@
+coccilib.report.print_report(p[0],
+  "WARNING: %s: .write() has stream semantic; safe to change nonseekable_open -> stream_open." % (fops,))
+
+@ explain_w depends on explain @
+identifier fops_w.openfunc;
+@@
+  openfunc(...) {
+    <...
+-   nonseekable_open
++   nonseekable_open /* write only */
+    ...>
+  }
+
+@ patch_w depends on patch @
+identifier fops_w.openfunc;
+@@
+  openfunc(...) {
+    <...
+-   nonseekable_open
++   stream_open
+    ...>
+  }
+
+
+// no read, no write - don't change anything
-- 
2.20.1




  parent reply	other threads:[~2019-05-06 14:37 UTC|newest]

Thread overview: 134+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-05-06 14:30 [PATCH 5.0 000/122] 5.0.14-stable review Greg Kroah-Hartman
2019-05-06 14:30 ` [PATCH 5.0 001/122] selftests/seccomp: Prepare for exclusive seccomp flags Greg Kroah-Hartman
2019-05-06 14:31 ` [PATCH 5.0 002/122] seccomp: Make NEW_LISTENER and TSYNC flags exclusive Greg Kroah-Hartman
2019-05-06 14:31 ` [PATCH 5.0 003/122] ARC: memset: fix build with L1_CACHE_SHIFT != 6 Greg Kroah-Hartman
2019-05-06 14:31 ` [PATCH 5.0 004/122] iwlwifi: fix driver operation for 5350 Greg Kroah-Hartman
2019-05-06 14:31 ` [PATCH 5.0 005/122] mwifiex: Make resume actually do something useful again on SDIO cards Greg Kroah-Hartman
2019-05-06 14:31 ` [PATCH 5.0 006/122] mtd: rawnand: marvell: Clean the controller state before each operation Greg Kroah-Hartman
2019-05-06 14:31 ` [PATCH 5.0 007/122] mac80211: dont attempt to rename ERR_PTR() debugfs dirs Greg Kroah-Hartman
2019-05-06 14:31 ` [PATCH 5.0 008/122] i2c: synquacer: fix enumeration of slave devices Greg Kroah-Hartman
2019-05-06 14:31 ` [PATCH 5.0 009/122] i2c: imx: correct the method of getting private data in notifier_call Greg Kroah-Hartman
2019-05-06 14:31 ` [PATCH 5.0 010/122] i2c: Prevent runtime suspend of adapter when Host Notify is required Greg Kroah-Hartman
2019-05-06 14:31 ` [PATCH 5.0 011/122] ALSA: hda/realtek - Add new Dell platform for headset mode Greg Kroah-Hartman
2019-05-06 14:31 ` [PATCH 5.0 012/122] ALSA: hda/realtek - Fixed Dell AIO speaker noise Greg Kroah-Hartman
2019-05-06 14:31 ` [PATCH 5.0 013/122] ALSA: hda/realtek - Apply the fixup for ASUS Q325UAR Greg Kroah-Hartman
2019-05-06 14:31 ` [PATCH 5.0 014/122] USB: yurex: Fix protection fault after device removal Greg Kroah-Hartman
2019-05-06 14:31 ` [PATCH 5.0 015/122] USB: w1 ds2490: Fix bug caused by improper use of altsetting array Greg Kroah-Hartman
2019-05-06 14:31 ` [PATCH 5.0 016/122] USB: dummy-hcd: Fix failure to give back unlinked URBs Greg Kroah-Hartman
2019-05-06 14:31 ` [PATCH 5.0 017/122] usb: usbip: fix isoc packet num validation in get_pipe Greg Kroah-Hartman
2019-05-06 14:31 ` [PATCH 5.0 018/122] USB: core: Fix unterminated string returned by usb_string() Greg Kroah-Hartman
2019-05-06 14:31 ` [PATCH 5.0 019/122] USB: core: Fix bug caused by duplicate interface PM usage counter Greg Kroah-Hartman
2019-05-06 14:31 ` [PATCH 5.0 020/122] KVM: lapic: Disable timer advancement if adaptive tuning goes haywire Greg Kroah-Hartman
2019-05-06 14:31 ` [PATCH 5.0 021/122] KVM: x86: Consider LAPIC TSC-Deadline timer expired if deadline too short Greg Kroah-Hartman
2019-05-06 14:31 ` [PATCH 5.0 022/122] KVM: lapic: Track lapic timer advance per vCPU Greg Kroah-Hartman
2019-05-06 14:31 ` [PATCH 5.0 023/122] KVM: lapic: Allow user to disable adaptive tuning of timer advancement Greg Kroah-Hartman
2019-05-06 14:31 ` [PATCH 5.0 024/122] KVM: lapic: Convert guest TSC to host time domain if necessary Greg Kroah-Hartman
2019-05-06 14:31 ` [PATCH 5.0 025/122] arm64: dts: rockchip: fix rk3328-roc-cc gmac2io tx/rx_delay Greg Kroah-Hartman
2019-05-06 14:31 ` [PATCH 5.0 026/122] HID: Increase maximum report size allowed by hid_field_extract() Greg Kroah-Hartman
2019-05-06 14:31 ` [PATCH 5.0 027/122] HID: logitech: check the return value of create_singlethread_workqueue Greg Kroah-Hartman
2019-05-06 14:31 ` [PATCH 5.0 028/122] HID: debug: fix race condition with between rdesc_show() and device removal Greg Kroah-Hartman
2019-05-06 14:31 ` [PATCH 5.0 029/122] rtc: cros-ec: Fail suspend/resume if wake IRQ cant be configured Greg Kroah-Hartman
2019-05-06 14:31 ` [PATCH 5.0 030/122] rtc: sh: Fix invalid alarm warning for non-enabled alarm Greg Kroah-Hartman
2019-05-06 14:31 ` [PATCH 5.0 031/122] ARM: OMAP2+: add missing of_node_put after of_device_is_available Greg Kroah-Hartman
2019-05-06 14:31 ` [PATCH 5.0 032/122] batman-adv: Reduce claim hash refcnt only for removed entry Greg Kroah-Hartman
2019-05-06 14:31 ` [PATCH 5.0 033/122] batman-adv: Reduce tt_local " Greg Kroah-Hartman
2019-05-06 14:31 ` [PATCH 5.0 034/122] batman-adv: Reduce tt_global " Greg Kroah-Hartman
2019-05-06 14:31 ` [PATCH 5.0 035/122] batman-adv: fix warning in function batadv_v_elp_get_throughput Greg Kroah-Hartman
2019-05-06 14:31 ` [PATCH 5.0 036/122] ARM: dts: rockchip: Fix gpu opp node names for rk3288 Greg Kroah-Hartman
2019-05-06 14:31 ` [PATCH 5.0 037/122] reset: meson-audio-arb: Fix missing .owner setting of reset_controller_dev Greg Kroah-Hartman
2019-05-06 14:31 ` [PATCH 5.0 038/122] ARM: dts: Fix dcan clkctrl clock for am3 Greg Kroah-Hartman
2019-05-06 14:31 ` [PATCH 5.0 039/122] i40e: fix i40e_ptp_adjtime when given a negative delta Greg Kroah-Hartman
2019-05-06 14:31 ` [PATCH 5.0 040/122] igb: Fix WARN_ONCE on runtime suspend Greg Kroah-Hartman
2019-05-06 14:31 ` [PATCH 5.0 041/122] ixgbe: fix mdio bus registration Greg Kroah-Hartman
2019-05-06 14:31 ` [PATCH 5.0 042/122] i40e: fix WoL support check Greg Kroah-Hartman
2019-05-06 14:31 ` [PATCH 5.0 043/122] riscv: fix accessing 8-byte variable from RV32 Greg Kroah-Hartman
2019-05-06 14:31 ` [PATCH 5.0 044/122] HID: quirks: Fix keyboard + touchpad on Lenovo Miix 630 Greg Kroah-Hartman
2019-05-06 14:31 ` [PATCH 5.0 045/122] net: hns3: fix compile error Greg Kroah-Hartman
2019-05-06 14:31 ` [PATCH 5.0 046/122] xdp: fix cpumap redirect SKB creation bug Greg Kroah-Hartman
2019-05-06 14:31 ` [PATCH 5.0 047/122] net/mlx5: E-Switch, Protect from invalid memory access in offload fdb table Greg Kroah-Hartman
2019-05-06 14:31 ` [PATCH 5.0 048/122] net/mlx5: E-Switch, Fix esw manager vport indication for more vport commands Greg Kroah-Hartman
2019-05-06 14:31 ` [PATCH 5.0 049/122] bonding: show full hw address in sysfs for slave entries Greg Kroah-Hartman
2019-05-06 14:31 ` [PATCH 5.0 050/122] net: stmmac: use correct DMA buffer size in the RX descriptor Greg Kroah-Hartman
2019-05-06 14:31 ` [PATCH 5.0 051/122] net: stmmac: ratelimit RX error logs Greg Kroah-Hartman
2019-05-06 14:31 ` [PATCH 5.0 052/122] net: stmmac: dont stop NAPI processing when dropping a packet Greg Kroah-Hartman
2019-05-06 14:31 ` [PATCH 5.0 053/122] net: stmmac: dont overwrite discard_frame status Greg Kroah-Hartman
2019-05-06 14:31 ` [PATCH 5.0 054/122] net: stmmac: fix dropping of multi-descriptor RX frames Greg Kroah-Hartman
2019-05-06 14:31 ` [PATCH 5.0 055/122] net: stmmac: dont log oversized frames Greg Kroah-Hartman
2019-05-06 14:31 ` [PATCH 5.0 056/122] jffs2: fix use-after-free on symlink traversal Greg Kroah-Hartman
2019-05-06 14:31 ` [PATCH 5.0 057/122] debugfs: " Greg Kroah-Hartman
2019-05-06 14:31 ` [PATCH 5.0 058/122] mfd: twl-core: Disable IRQ while suspended Greg Kroah-Hartman
2019-05-06 14:31 ` [PATCH 5.0 059/122] block: use blk_free_flush_queue() to free hctx->fq in blk_mq_init_hctx Greg Kroah-Hartman
2019-05-06 14:31 ` [PATCH 5.0 060/122] rtc: da9063: set uie_unsupported when relevant Greg Kroah-Hartman
2019-05-06 14:31 ` [PATCH 5.0 061/122] HID: input: add mapping for Assistant key Greg Kroah-Hartman
2019-05-06 14:32 ` [PATCH 5.0 062/122] vfio/pci: use correct format characters Greg Kroah-Hartman
2019-05-06 14:32 ` [PATCH 5.0 063/122] scsi: core: add new RDAC LENOVO/DE_Series device Greg Kroah-Hartman
2019-05-06 14:32 ` [PATCH 5.0 064/122] scsi: storvsc: Fix calculation of sub-channel count Greg Kroah-Hartman
2019-05-06 14:32 ` [PATCH 5.0 065/122] arm/mach-at91/pm : fix possible object reference leak Greg Kroah-Hartman
2019-05-06 14:32 ` [PATCH 5.0 066/122] blk-mq: do not reset plug->rq_count before the list is sorted Greg Kroah-Hartman
2019-05-06 14:32 ` [PATCH 5.0 067/122] arm64: fix wrong check of on_sdei_stack in nmi context Greg Kroah-Hartman
2019-05-06 14:32 ` [PATCH 5.0 068/122] net: hns: fix KASAN: use-after-free in hns_nic_net_xmit_hw() Greg Kroah-Hartman
2019-05-06 14:32 ` [PATCH 5.0 069/122] net: hns: Use NAPI_POLL_WEIGHT for hns driver Greg Kroah-Hartman
2019-05-06 14:32 ` [PATCH 5.0 070/122] net: hns: Fix probabilistic memory overwrite when HNS driver initialized Greg Kroah-Hartman
2019-05-06 14:32 ` [PATCH 5.0 071/122] net: hns: fix ICMP6 neighbor solicitation messages discard problem Greg Kroah-Hartman
2019-05-06 14:32 ` [PATCH 5.0 072/122] net: hns: Fix WARNING when remove HNS driver with SMMU enabled Greg Kroah-Hartman
2019-05-06 14:32 ` [PATCH 5.0 073/122] libcxgb: fix incorrect ppmax calculation Greg Kroah-Hartman
2019-05-06 14:32 ` [PATCH 5.0 074/122] KVM: SVM: prevent DBG_DECRYPT and DBG_ENCRYPT overflow Greg Kroah-Hartman
2019-05-06 14:32 ` [PATCH 5.0 075/122] kmemleak: powerpc: skip scanning holes in the .bss section Greg Kroah-Hartman
2019-05-06 14:32 ` [PATCH 5.0 076/122] hugetlbfs: fix memory leak for resv_map Greg Kroah-Hartman
2019-05-06 14:32 ` [PATCH 5.0 077/122] sh: fix multiple function definition build errors Greg Kroah-Hartman
2019-05-06 14:32 ` [PATCH 5.0 078/122] null_blk: prevent crash from bad home_node value Greg Kroah-Hartman
2019-05-06 14:32 ` [PATCH 5.0 079/122] xsysace: Fix error handling in ace_setup Greg Kroah-Hartman
2019-05-06 14:32 ` Greg Kroah-Hartman [this message]
2019-05-06 14:32 ` [PATCH 5.0 081/122] ARM: orion: dont use using 64-bit DMA masks Greg Kroah-Hartman
2019-05-06 14:32 ` [PATCH 5.0 082/122] ARM: iop: " Greg Kroah-Hartman
2019-05-06 14:32 ` [PATCH 5.0 083/122] perf/x86/amd: Update generic hardware cache events for Family 17h Greg Kroah-Hartman
2019-05-06 14:32 ` [PATCH 5.0 084/122] Bluetooth: btusb: request wake pin with NOAUTOEN Greg Kroah-Hartman
2019-05-06 14:32 ` [PATCH 5.0 085/122] Bluetooth: mediatek: fix up an error path to restore bdev->tx_state Greg Kroah-Hartman
2019-05-06 14:32 ` [PATCH 5.0 086/122] clk: qcom: Add missing freq for usb30_master_clk on 8998 Greg Kroah-Hartman
2019-05-06 14:32 ` [PATCH 5.0 087/122] usb: dwc3: Reset num_trbs after skipping Greg Kroah-Hartman
2019-05-06 14:32 ` [PATCH 5.0 088/122] staging: iio: adt7316: allow adt751x to use internal vref for all dacs Greg Kroah-Hartman
2019-05-06 14:32 ` [PATCH 5.0 089/122] staging: iio: adt7316: fix the dac read calculation Greg Kroah-Hartman
2019-05-06 14:32 ` [PATCH 5.0 090/122] staging: iio: adt7316: fix handling of dac high resolution option Greg Kroah-Hartman
2019-05-06 14:32 ` [PATCH 5.0 091/122] staging: iio: adt7316: fix the dac write calculation Greg Kroah-Hartman
2019-05-06 14:32 ` [PATCH 5.0 092/122] scsi: hisi_sas: Fix to only call scsi_get_prot_op() for non-NULL scsi_cmnd Greg Kroah-Hartman
2019-05-06 14:32 ` [PATCH 5.0 093/122] scsi: RDMA/srpt: Fix a credit leak for aborted commands Greg Kroah-Hartman
2019-05-06 14:32 ` [PATCH 5.0 094/122] ASoC: Intel: bytcr_rt5651: Revert "Fix DMIC map headsetmic mapping" Greg Kroah-Hartman
2019-05-06 14:32 ` [PATCH 5.0 095/122] ASoC: rsnd: gen: fix SSI9 4/5/6/7 busif related register address Greg Kroah-Hartman
2019-05-06 14:32 ` [PATCH 5.0 096/122] ASoC: sunxi: sun50i-codec-analog: Rename hpvcc regulator supply to cpvdd Greg Kroah-Hartman
2019-05-06 14:32 ` [PATCH 5.0 097/122] ASoC: wm_adsp: Correct handling of compressed streams that restart Greg Kroah-Hartman
2019-05-06 14:32 ` [PATCH 5.0 098/122] ASoC: dpcm: skip missing substream while applying symmetry Greg Kroah-Hartman
2019-05-06 14:32 ` [PATCH 5.0 099/122] ASoC: stm32: fix sai driver name initialisation Greg Kroah-Hartman
2019-05-06 14:32 ` [PATCH 5.0 100/122] KVM: VMX: Save RSI to an unused output in the vCPU-run asm blob Greg Kroah-Hartman
2019-05-06 14:32 ` [PATCH 5.0 101/122] KVM: nVMX: Remove a rogue "rax" clobber from nested_vmx_check_vmentry_hw() Greg Kroah-Hartman
2019-05-06 14:32 ` [PATCH 5.0 102/122] kvm: vmx: Fix typos in vmentry/vmexit control setting Greg Kroah-Hartman
2019-05-06 14:32 ` [PATCH 5.0 103/122] KVM: lapic: Check for in-kernel LAPIC before deferencing apic pointer Greg Kroah-Hartman
2019-05-06 14:32 ` [PATCH 5.0 104/122] platform/x86: intel_pmc_core: Fix PCH IP name Greg Kroah-Hartman
2019-05-06 14:32 ` [PATCH 5.0 105/122] platform/x86: intel_pmc_core: Handle CFL regmap properly Greg Kroah-Hartman
2019-05-06 14:32 ` [PATCH 5.0 106/122] IB/core: Unregister notifier before freeing MAD security Greg Kroah-Hartman
2019-05-06 14:32 ` [PATCH 5.0 107/122] IB/core: Fix potential memory leak while creating MAD agents Greg Kroah-Hartman
2019-05-06 14:32 ` [PATCH 5.0 108/122] IB/core: Destroy QP if XRC QP fails Greg Kroah-Hartman
2019-05-06 14:32 ` [PATCH 5.0 109/122] Input: snvs_pwrkey - initialize necessary driver data before enabling IRQ Greg Kroah-Hartman
2019-05-06 14:32 ` [PATCH 5.0 110/122] Input: stmfts - acknowledge that setting brightness is a blocking call Greg Kroah-Hartman
2019-05-06 14:32 ` [PATCH 5.0 111/122] gpio: mxc: add check to return defer probe if clock tree NOT ready Greg Kroah-Hartman
2019-05-06 14:32 ` [PATCH 5.0 112/122] selinux: avoid silent denials in permissive mode under RCU walk Greg Kroah-Hartman
2019-05-06 14:32 ` [PATCH 5.0 113/122] selinux: never allow relabeling on context mounts Greg Kroah-Hartman
2019-05-06 14:32 ` [PATCH 5.0 114/122] mac80211: Honor SW_CRYPTO_CONTROL for unicast keys in AP VLAN mode Greg Kroah-Hartman
2019-05-06 14:32 ` [PATCH 5.0 115/122] powerpc/mm/hash: Handle mmap_min_addr correctly in get_unmapped_area topdown search Greg Kroah-Hartman
2019-05-06 14:32 ` [PATCH 5.0 116/122] x86/mce: Improve error message when kernel cannot recover, p2 Greg Kroah-Hartman
2019-05-06 14:32 ` [PATCH 5.0 117/122] clk: x86: Add system specific quirk to mark clocks as critical Greg Kroah-Hartman
2019-05-06 14:32 ` [PATCH 5.0 118/122] x86/mm/KASLR: Fix the size of the direct mapping section Greg Kroah-Hartman
2019-05-06 14:32 ` [PATCH 5.0 119/122] x86/mm: Fix a crash with kmemleak_scan() Greg Kroah-Hartman
2019-05-06 14:32 ` [PATCH 5.0 120/122] x86/mm/tlb: Revert "x86/mm: Align TLB invalidation info" Greg Kroah-Hartman
2019-05-06 14:32 ` [PATCH 5.0 121/122] i2c: i2c-stm32f7: Fix SDADEL minimum formula Greg Kroah-Hartman
2019-05-06 14:33 ` [PATCH 5.0 122/122] media: v4l2: i2c: ov7670: Fix PLL bypass register values Greg Kroah-Hartman
2019-05-07  7:18 ` [PATCH 5.0 000/122] 5.0.14-stable review Naresh Kamboju
2019-05-07 13:04   ` Greg Kroah-Hartman
2019-05-07 12:45 ` Jon Hunter
2019-05-07 13:04   ` Greg Kroah-Hartman
2019-05-07 16:27 ` kernelci.org bot
2019-05-07 18:39 ` Guenter Roeck
2019-05-07 18:58   ` Greg Kroah-Hartman
2019-05-07 20:19 ` shuah
2019-05-08  6:36   ` Greg Kroah-Hartman
2019-05-08  0:56 ` Kelsey Skunberg
2019-05-08  6:36   ` Greg Kroah-Hartman

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190506143102.005836007@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=Julia.Lawall@lip6.fr \
    --cc=Nikolaus@rath.org \
    --cc=arnd@arndb.de \
    --cc=corbet@lwn.net \
    --cc=david.vrabel@citrix.com \
    --cc=hanwen@google.com \
    --cc=hch@lst.de \
    --cc=jgross@suse.com \
    --cc=kirr@nexedi.com \
    --cc=ktkhai@virtuozzo.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=miklos@szeredi.hu \
    --cc=mtk.manpages@gmail.com \
    --cc=panyongzhi@gmail.com \
    --cc=sashal@kernel.org \
    --cc=stable@vger.kernel.org \
    --cc=tj@kernel.org \
    --cc=torvalds@linux-foundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).