linux/fs
Linus Torvalds 6551d5c56e pipe: make sure to wake up everybody when the last reader/writer closes
Andrei Vagin reported that commit 0ddad21d3e ("pipe: use exclusive
waits when reading or writing") broke one of the CRIU tests.  He even
has a trivial reproducer:

    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/wait.h>

    int main()
    {
            int p[2];
            pid_t p1, p2;
            int status;

            if (pipe(p) == -1)
                    return 1;

            p1 = fork();
            if (p1 == 0) {
                    close(p[1]);
                    read(p[0], &status, sizeof(status));
                    return 0;
            }
            p2 = fork();
            if (p2 == 0) {
                    close(p[1]);
                    read(p[0], &status, sizeof(status));
                    return 0;
            }
            sleep(1);
            close(p[1]);
            wait(&status);
            wait(&status);

            return 0;
    }

and the problem - once he points it out - is obvious.  We use these nice
exclusive waits, but when the last writer goes away, it then needs to
wake up _every_ reader (and conversely, the last reader disappearing
needs to wake every writer, of course).

In fact, when going through this, we had several small oddities around
how to wake things.  We did in fact wake every reader when we changed
the size of the pipe buffers.  But that's entirely pointless, since that
just acts as a possible source of new space - no new data to read.

And when we change the size of the buffer, we don't need to wake all
writers even when we add space - that case acts just as if somebody made
space by reading, and any writer that finds itself not filling it up
entirely will wake the next one.

On the other hand, on the exit path, we tried to limit the wakeups with
the proper poll keys etc, which is entirely pointless, because at that
point we obviously need to wake up everybody.  So don't do that: just
wake up everybody - but only do that if the counts changed to zero.

So fix those non-IO wakeups to be more proper: space change doesn't add
any new data, but it might make room for writers, so it wakes up a
writer.  And the actual changes to reader/writer counts should wake up
everybody, since everybody is affected (ie readers will all see EOF if
the writers have gone away, and writers will all get EPIPE if all
readers have gone away).

Fixes: 0ddad21d3e ("pipe: use exclusive waits when reading or writing")
Reported-and-tested-by: Andrei Vagin <avagin@gmail.com>
Cc: Josh Triplett <josh@joshtriplett.org>
Cc: Matthew Wilcox <willy@infradead.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2020-02-18 14:34:36 -08:00
..
9p
adfs fs/adfs: bigdir: Fix an error code in adfs_fplus_read() 2020-01-25 11:31:59 -05:00
affs affs: fix a memory leak in affs_remount 2019-11-18 14:26:43 +01:00
afs Merge branch 'merge.nfs-fs_parse.1' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2020-02-08 13:26:41 -08:00
autofs Merge branch 'next.autofs' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2019-12-05 17:11:48 -08:00
befs
bfs
btrfs for-5.6-rc1-tag 2020-02-17 13:26:30 -08:00
cachefiles cachefiles: drop direct usage of ->bmap method. 2020-02-03 08:05:56 -05:00
ceph ceph: noacl mount option is effectively ignored 2020-02-11 17:04:40 +01:00
cifs cifs: make sure we do not overflow the max EA buffer size 2020-02-14 11:10:24 -06:00
coda
configfs utimes: Clamp the timestamps in notify_change() 2019-12-08 19:10:50 -05:00
cramfs cramfs: switch to use of errofc() et.al. 2020-02-07 14:48:41 -05:00
crypto fscrypt: improve format of no-key names 2020-01-22 14:50:03 -08:00
debugfs Merge branch 'work.recursive_removal' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2020-02-05 05:09:46 +00:00
devpts
dlm dlm: use SO_SNDTIMEO_NEW instead of SO_SNDTIMEO_OLD 2019-12-18 18:07:31 +01:00
ecryptfs eCryptfs fixes for 5.6-rc3 2020-02-17 21:08:37 -08:00
efivarfs
efs
erofs erofs: clean up z_erofs_submit_queue() 2020-01-21 16:46:23 +08:00
exportfs race in exportfs_decode_fh() 2019-11-11 09:21:59 -05:00
ext2 dax fixes 5.6-rc1 2020-02-11 16:52:08 -08:00
ext4 Miscellaneous ext4 bug fixes (all stable fodder) 2020-02-16 11:12:06 -08:00
f2fs Merge branch 'work.misc' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2020-02-08 13:04:49 -08:00
fat Merge branch 'imm.timestamp' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2020-02-05 05:02:42 +00:00
freevxfs
fscache proc: convert everything to "struct proc_ops" 2020-02-04 03:05:26 +00:00
fuse Merge branch 'merge.nfs-fs_parse.1' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2020-02-08 13:26:41 -08:00
gfs2 Merge branch 'merge.nfs-fs_parse.1' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2020-02-08 13:26:41 -08:00
hfs hfs/hfsplus: use 64-bit inode timestamps 2019-12-18 18:07:32 +01:00
hfsplus hfs/hfsplus: use 64-bit inode timestamps 2019-12-18 18:07:32 +01:00
hostfs hostfs: pass 64-bit timestamps to/from user space 2019-12-18 18:07:32 +01:00
hpfs
hugetlbfs hugetlbfs: switch to use of invalfc() 2020-02-07 14:48:42 -05:00
iomap fs: Fix page_mkwrite off-by-one errors 2020-01-06 08:58:23 -08:00
isofs
jbd2 Miscellaneous ext4 bug fixes (all stable fodder) 2020-02-16 11:12:06 -08:00
jffs2 fs_parse: fold fs_parameter_desc/fs_parameter_spec 2020-02-07 14:48:37 -05:00
jfs Trivial cleanup for jfs 2020-02-05 05:28:20 +00:00
kernfs Merge branch 'imm.timestamp' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2020-02-05 05:02:42 +00:00
lockd proc: convert everything to "struct proc_ops" 2020-02-04 03:05:26 +00:00
minix
nfs NFSv4: Ensure the delegation cred is pinned when we call delegreturn 2020-02-13 16:23:02 -05:00
nfs_common
nfsd Highlights: 2020-02-07 17:50:21 -08:00
nilfs2
nls
notify fs: call fsnotify_sb_delete after evict_inodes 2019-12-18 00:03:01 -05:00
ntfs utimes: Clamp the timestamps in notify_change() 2019-12-08 19:10:50 -05:00
ocfs2 treewide: remove redundant IS_ERR() before error code check 2020-02-04 03:05:27 +00:00
omfs
openpromfs
orangefs help_next should increase position index 2020-02-04 15:22:04 -05:00
overlayfs ovl: fix lseek overflow on 32bit 2020-02-03 11:41:53 +01:00
proc Merge branch 'merge.nfs-fs_parse.1' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2020-02-08 13:26:41 -08:00
pstore pstore/ram: Regularize prz label allocation lifetime 2020-01-08 17:05:45 -08:00
qnx4
qnx6
quota \n 2020-01-30 15:37:41 -08:00
ramfs fs_parse: fold fs_parameter_desc/fs_parameter_spec 2020-02-07 14:48:37 -05:00
reiserfs Merge branch 'akpm' (patches from Andrew) 2020-01-31 12:16:36 -08:00
romfs
squashfs
sysfs treewide: remove redundant IS_ERR() before error code check 2020-02-04 03:05:27 +00:00
sysv
tracefs simple_recursive_removal(): kernel-side rm -rf for ramfs-style filesystems 2019-12-10 22:29:58 -05:00
ubifs Merge branch 'imm.timestamp' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2020-02-05 05:02:42 +00:00
udf udf: Clarify meaning of f_files in udf_statfs 2020-01-20 13:59:41 +01:00
ufs
unicode kbuild: rename hostprogs-y/always to hostprogs/always-y 2020-02-04 01:53:07 +09:00
vboxsf fs: Add VirtualBox guest shared folder (vboxsf) support 2020-02-08 17:34:58 -05:00
verity fs-verity: use u64_to_user_ptr() 2020-01-14 13:28:28 -08:00
xfs dax fixes 5.6-rc1 2020-02-11 16:52:08 -08:00
zonefs fs: New zonefs file system 2020-02-07 14:39:38 +09:00
aio.c aio: prevent potential eventfd recursion on poll 2020-02-03 17:27:47 -07:00
anon_inodes.c
attr.c utimes: Clamp the timestamps in notify_change() 2019-12-08 19:10:50 -05:00
bad_inode.c
binfmt_aout.c
binfmt_elf_fdpic.c y2038: elfcore: Use __kernel_old_timeval for process times 2019-11-15 14:38:29 +01:00
binfmt_elf.c fs/binfmt_elf.c: coredump: allow process with empty address space to coredump 2020-01-31 10:30:41 -08:00
binfmt_em86.c
binfmt_flat.c
binfmt_misc.c
binfmt_script.c
block_dev.c block: don't send uevent for empty disk when not invalidating 2019-12-02 18:49:30 -07:00
buffer.c smp: Remove allocation mask from on_each_cpu_cond.*() 2020-01-24 20:40:09 +01:00
char_dev.c chardev: Avoid potential use-after-free in 'chrdev_open()' 2020-01-06 20:10:26 +01:00
compat_binfmt_elf.c y2038: elfcore: Use __kernel_old_timeval for process times 2019-11-15 14:38:29 +01:00
compat.c
coredump.c pipe: use exclusive waits when reading or writing 2020-02-08 11:39:19 -08:00
d_path.c
dax.c dax: pass NOWAIT flag to iomap_apply 2020-02-05 20:34:32 -08:00
dcache.c Merge branch 'work.misc' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2019-12-08 11:08:28 -08:00
dcookies.c
direct-io.c fs/direct-io.c: include fs/internal.h for missing prototype 2020-01-04 13:55:09 -08:00
drop_caches.c fs: avoid softlockups in s_inodes iterators 2019-12-18 00:03:01 -05:00
eventfd.c eventfd: track eventfd_signal() recursion depth 2020-02-03 17:27:38 -07:00
eventpoll.c eventpoll: support non-blocking do_epoll_ctl() calls 2020-01-29 15:45:47 -07:00
exec.c Merge branch 'akpm' (patches from Andrew) 2020-01-31 12:16:36 -08:00
fcntl.c Merge branch 'work.misc' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2019-12-08 11:08:28 -08:00
fhandle.c
file_table.c
file.c threads-v5.6 2020-01-29 19:38:34 -08:00
filesystems.c fs_parser: remove fs_parameter_description name field 2020-02-07 14:48:36 -05:00
fs_context.c add prefix to fs_context->log 2020-02-07 14:48:35 -05:00
fs_parser.c turn fs_param_is_... into functions 2020-02-07 14:48:38 -05:00
fs_pin.c
fs_struct.c
fs_types.c
fs-writeback.c memcg: fix a crash in wb_workfn when a device disappears 2020-01-31 10:30:36 -08:00
fsopen.c add prefix to fs_context->log 2020-02-07 14:48:35 -05:00
inode.c Merge branch 'work.misc' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2020-02-08 13:04:49 -08:00
internal.h for-5.6/io_uring-vfs-2020-01-29 2020-01-29 18:53:37 -08:00
io_uring.c io_uring: prune request from overflow list on flush 2020-02-13 17:25:01 -07:00
io-wq.c io-wq: don't call kXalloc_node() with non-online node 2020-02-12 17:43:22 -07:00
io-wq.h io-wq: add io_wq_cancel_pid() to cancel based on a specific pid 2020-02-09 09:55:38 -07:00
ioctl.c compat-ioctl fix for v5.6 2020-02-08 13:44:41 -08:00
Kconfig fs: New zonefs file system 2020-02-09 15:51:46 -08:00
Kconfig.binfmt
libfs.c simple_recursive_removal(): kernel-side rm -rf for ramfs-style filesystems 2019-12-10 22:29:58 -05:00
locks.c locks: print unsigned ino in /proc/locks 2019-12-29 09:00:58 -05:00
Makefile fs: New zonefs file system 2020-02-09 15:51:46 -08:00
mbcache.c
mount.h
mpage.c fs: move guard_bio_eod() after bio_set_op_attrs 2020-01-09 08:16:12 -07:00
namei.c vfs: fix do_last() regression 2020-02-01 10:36:49 -08:00
namespace.c saner copy_mount_options() 2020-02-03 21:23:33 -05:00
no-block.c
nsfs.c Merge branch 'work.openat2' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2020-01-29 11:20:24 -08:00
open.c fs: make build_open_flags() available internally 2020-01-20 17:01:53 -07:00
pipe.c pipe: make sure to wake up everybody when the last reader/writer closes 2020-02-18 14:34:36 -08:00
pnode.c
pnode.h
posix_acl.c fs/posix_acl.c: fix kernel-doc warnings 2020-01-04 13:55:09 -08:00
proc_namespace.c
read_write.c overlayfs update for 5.6 2020-02-04 11:45:21 +00:00
readdir.c readdir: make user_access_begin() use the real access range 2020-01-23 10:15:28 -08:00
select.c y2038: syscalls: change remaining timeval to __kernel_old_timeval 2019-11-15 14:38:29 +01:00
seq_file.c
signalfd.c
splice.c pipe: use exclusive waits when reading or writing 2020-02-08 11:39:19 -08:00
stack.c sched/rt, fs: Use CONFIG_PREEMPTION 2019-12-08 14:37:36 +01:00
stat.c fs: make two stat prep helpers available 2020-01-20 17:03:54 -07:00
statfs.c
super.c fs: call fsnotify_sb_delete after evict_inodes 2019-12-18 00:03:01 -05:00
sync.c
timerfd.c timerfd: Make timerfd_settime() time namespace aware 2020-01-14 12:20:53 +01:00
userfaultfd.c Merge branch 'akpm' (patches from Andrew) 2019-12-01 20:36:41 -08:00
utimes.c utimes: Clamp the timestamps in notify_change() 2019-12-08 19:10:50 -05:00
xattr.c