# git rev-parse -q --verify 0be0ee71816b2b6725e2b4f32ad6726c9d729777^{commit} 0be0ee71816b2b6725e2b4f32ad6726c9d729777 already have revision, skipping fetch # git checkout -q -f -B kisskb 0be0ee71816b2b6725e2b4f32ad6726c9d729777 # git clean -qxdf # < git log -1 # commit 0be0ee71816b2b6725e2b4f32ad6726c9d729777 # Author: Linus Torvalds # Date: Mon Nov 11 15:51:03 2019 -0800 # # vfs: properly and reliably lock f_pos in fdget_pos() # # fdget_pos() is used by file operations that will read and update f_pos: # things like "read()", "write()" and "lseek()" (but not, for example, # "pread()/pwrite" that get their file positions elsewhere). # # However, it had two separate escape clauses for this, because not # everybody wants or needs serialization of the file position. # # The first and most obvious case is the "file descriptor doesn't have a # position at all", ie a stream-like file. Except we didn't actually use # FMODE_STREAM, but instead used FMODE_ATOMIC_POS. The reason for that # was that FMODE_STREAM didn't exist back in the days, but also that we # didn't want to mark all the special cases, so we only marked the ones # that _required_ position atomicity according to POSIX - regular files # and directories. # # The case one was intentionally lazy, but now that we _do_ have # FMODE_STREAM we could and should just use it. With the change to use # FMODE_STREAM, there are no remaining uses for FMODE_ATOMIC_POS, and all # the code to set it is deleted. # # Any cases where we don't want the serialization because the driver (or # subsystem) doesn't use the file position should just be updated to do # "stream_open()". We've done that for all the obvious and common # situations, we may need a few more. Quoting Kirill Smelkov in the # original FMODE_STREAM thread (see link below for full email): # # "And I appreciate if people could help at least somehow with "getting # rid of mixed case entirely" (i.e. always lock f_pos_lock on # !FMODE_STREAM), because this transition starts to diverge from my # particular use-case too far. To me it makes sense to do that # transition as follows: # # - convert nonseekable_open -> stream_open via stream_open.cocci; # - audit other nonseekable_open calls and convert left users that # truly don't depend on position to stream_open; # - extend stream_open.cocci to analyze alloc_file_pseudo as well (this # will cover pipes and sockets), or maybe convert pipes and sockets # to FMODE_STREAM manually; # - extend stream_open.cocci to analyze file_operations that use # no_llseek or noop_llseek, but do not use nonseekable_open or # alloc_file_pseudo. This might find files that have stream semantic # but are opened differently; # - extend stream_open.cocci to analyze file_operations whose # .read/.write do not use ppos at all (independently of how file was # opened); # - ... # - after that remove FMODE_ATOMIC_POS and always take f_pos_lock if # !FMODE_STREAM; # - gather bug reports for deadlocked read/write and convert missed # cases to FMODE_STREAM, probably extending stream_open.cocci along # the road to catch similar cases # # i.e. always take f_pos_lock unless a file is explicitly marked as # being stream, and try to find and cover all files that are streams" # # We have not done the "extend stream_open.cocci to analyze # alloc_file_pseudo" as well, but the previous commit did manually handle # the case of pipes and sockets. # # The other case where we can avoid locking f_pos is the "this file # descriptor only has a single user and it is us, and thus there is no # need to lock it". # # The second test was correct, although a bit subtle and worth just # re-iterating here. There are two kinds of other sources of references # to the same file descriptor: file descriptors that have been explicitly # shared across fork() or with dup(), and file tables having elevated # reference counts due to threading (or explicit file sharing with # clone()). # # The first case would have incremented the file count explicitly, and in # the second case the previous __fdget() would have incremented it for us # and set the FDPUT_FPUT flag. # # But in both cases the file count would be greater than one, so the # "file_count(file) > 1" test catches both situations. Also note that if # file_count is 1, that also means that no other thread can have access to # the file table, so there also cannot be races with concurrent calls to # dup()/fork()/clone() that would increment the file count any other way. # # Link: https://lore.kernel.org/linux-fsdevel/20190413184404.GA13490@deco.navytux.spb.ru # Cc: Kirill Smelkov # Cc: Eic Dumazet # Cc: Al Viro # Cc: Alan Stern # Cc: Marco Elver # Cc: Andrea Parri # Cc: Paul McKenney # Signed-off-by: Linus Torvalds # < /opt/cross/kisskb/korg/gcc-8.1.0-nolibc/s390-linux/bin/s390-linux-gcc --version # < /opt/cross/kisskb/korg/gcc-8.1.0-nolibc/s390-linux/bin/s390-linux-ld --version # < git log --format=%s --max-count=1 0be0ee71816b2b6725e2b4f32ad6726c9d729777 # < make -s -j 120 ARCH=s390 O=/kisskb/build/linus_s390-allmodconfig_s390x-gcc8 CROSS_COMPILE=/opt/cross/kisskb/korg/gcc-8.1.0-nolibc/s390-linux/bin/s390-linux- allmodconfig # Added to kconfig CONFIG_BUILD_DOCSRC=n # Added to kconfig CONFIG_MODULE_SIG=n # Added to kconfig CONFIG_SAMPLES=n # yes \n | make -s -j 120 ARCH=s390 O=/kisskb/build/linus_s390-allmodconfig_s390x-gcc8 CROSS_COMPILE=/opt/cross/kisskb/korg/gcc-8.1.0-nolibc/s390-linux/bin/s390-linux- oldconfig yes: standard output: Broken pipe # make -s -j 120 ARCH=s390 O=/kisskb/build/linus_s390-allmodconfig_s390x-gcc8 CROSS_COMPILE=/opt/cross/kisskb/korg/gcc-8.1.0-nolibc/s390-linux/bin/s390-linux- In file included from /kisskb/src/include/linux/kernel.h:15, from /kisskb/src/include/linux/list.h:9, from /kisskb/src/include/linux/wait.h:7, from /kisskb/src/include/linux/wait_bit.h:8, from /kisskb/src/include/linux/fs.h:6, from /kisskb/src/fs/ubifs/ubifs.h:16, from /kisskb/src/fs/ubifs/orphan.c:10: /kisskb/src/fs/ubifs/orphan.c: In function 'orphan_delete': /kisskb/src/fs/ubifs/debug.h:158:11: warning: format '%lu' expects argument of type 'long unsigned int', but argument 4 has type 'ino_t' {aka 'unsigned int'} [-Wformat=] pr_debug("UBIFS DBG " type " (pid %d): " fmt "\n", current->pid, \ ^~~~~~~~~~~~ /kisskb/src/include/linux/printk.h:288:21: note: in definition of macro 'pr_fmt' #define pr_fmt(fmt) fmt ^~~ /kisskb/src/include/linux/dynamic_debug.h:143:2: note: in expansion of macro '__dynamic_func_call' __dynamic_func_call(__UNIQUE_ID(ddebug), fmt, func, ##__VA_ARGS__) ^~~~~~~~~~~~~~~~~~~ /kisskb/src/include/linux/dynamic_debug.h:153:2: note: in expansion of macro '_dynamic_func_call' _dynamic_func_call(fmt, __dynamic_pr_debug, \ ^~~~~~~~~~~~~~~~~~ /kisskb/src/include/linux/printk.h:336:2: note: in expansion of macro 'dynamic_pr_debug' dynamic_pr_debug(fmt, ##__VA_ARGS__) ^~~~~~~~~~~~~~~~ /kisskb/src/fs/ubifs/debug.h:158:2: note: in expansion of macro 'pr_debug' pr_debug("UBIFS DBG " type " (pid %d): " fmt "\n", current->pid, \ ^~~~~~~~ /kisskb/src/fs/ubifs/debug.h:170:29: note: in expansion of macro 'ubifs_dbg_msg' #define dbg_gen(fmt, ...) ubifs_dbg_msg("gen", fmt, ##__VA_ARGS__) ^~~~~~~~~~~~~ /kisskb/src/fs/ubifs/orphan.c:132:3: note: in expansion of macro 'dbg_gen' dbg_gen("deleted twice ino %lu", orph->inum); ^~~~~~~ /kisskb/src/fs/ubifs/orphan.c:132:32: note: format string is defined here dbg_gen("deleted twice ino %lu", orph->inum); ~~^ %u In file included from /kisskb/src/include/linux/kernel.h:15, from /kisskb/src/include/linux/list.h:9, from /kisskb/src/include/linux/wait.h:7, from /kisskb/src/include/linux/wait_bit.h:8, from /kisskb/src/include/linux/fs.h:6, from /kisskb/src/fs/ubifs/ubifs.h:16, from /kisskb/src/fs/ubifs/orphan.c:10: /kisskb/src/fs/ubifs/debug.h:158:11: warning: format '%lu' expects argument of type 'long unsigned int', but argument 4 has type 'ino_t' {aka 'unsigned int'} [-Wformat=] pr_debug("UBIFS DBG " type " (pid %d): " fmt "\n", current->pid, \ ^~~~~~~~~~~~ /kisskb/src/include/linux/printk.h:288:21: note: in definition of macro 'pr_fmt' #define pr_fmt(fmt) fmt ^~~ /kisskb/src/include/linux/dynamic_debug.h:143:2: note: in expansion of macro '__dynamic_func_call' __dynamic_func_call(__UNIQUE_ID(ddebug), fmt, func, ##__VA_ARGS__) ^~~~~~~~~~~~~~~~~~~ /kisskb/src/include/linux/dynamic_debug.h:153:2: note: in expansion of macro '_dynamic_func_call' _dynamic_func_call(fmt, __dynamic_pr_debug, \ ^~~~~~~~~~~~~~~~~~ /kisskb/src/include/linux/printk.h:336:2: note: in expansion of macro 'dynamic_pr_debug' dynamic_pr_debug(fmt, ##__VA_ARGS__) ^~~~~~~~~~~~~~~~ /kisskb/src/fs/ubifs/debug.h:158:2: note: in expansion of macro 'pr_debug' pr_debug("UBIFS DBG " type " (pid %d): " fmt "\n", current->pid, \ ^~~~~~~~ /kisskb/src/fs/ubifs/debug.h:170:29: note: in expansion of macro 'ubifs_dbg_msg' #define dbg_gen(fmt, ...) ubifs_dbg_msg("gen", fmt, ##__VA_ARGS__) ^~~~~~~~~~~~~ /kisskb/src/fs/ubifs/orphan.c:140:3: note: in expansion of macro 'dbg_gen' dbg_gen("delete later ino %lu", orph->inum); ^~~~~~~ /kisskb/src/fs/ubifs/orphan.c:140:31: note: format string is defined here dbg_gen("delete later ino %lu", orph->inum); ~~^ %u /kisskb/src/lib/test_kasan.c: In function 'kasan_alloca_oob_left': /kisskb/src/lib/test_kasan.c:527:1: warning: 'kasan_alloca_oob_left' uses dynamic stack allocation } ^ /kisskb/src/lib/test_kasan.c: In function 'kasan_alloca_oob_right': /kisskb/src/lib/test_kasan.c:537:1: warning: 'kasan_alloca_oob_right' uses dynamic stack allocation } ^ /kisskb/src/drivers/input/joystick/analog.c:160:2: warning: #warning Precise timer not defined for this architecture. [-Wcpp] #warning Precise timer not defined for this architecture. ^~~~~~~ In file included from /kisskb/src/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c:40: /kisskb/src/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c: In function 'mvpp2_setup_bm_pool': /kisskb/src/drivers/net/ethernet/marvell/mvpp2/mvpp2.h:634:2: warning: overflow in conversion from 'long unsigned int' to 'int' changes value from '18446744073709551584' to '-32' [-Woverflow] ((total_size) - NET_SKB_PAD - MVPP2_SKB_SHINFO_SIZE) ^ /kisskb/src/drivers/net/ethernet/marvell/mvpp2/mvpp2.h:699:33: note: in expansion of macro 'MVPP2_RX_MAX_PKT_SIZE' #define MVPP2_BM_SHORT_PKT_SIZE MVPP2_RX_MAX_PKT_SIZE(MVPP2_BM_SHORT_FRAME_SIZE) ^~~~~~~~~~~~~~~~~~~~~ /kisskb/src/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c:577:41: note: in expansion of macro 'MVPP2_BM_SHORT_PKT_SIZE' mvpp2_pools[MVPP2_BM_SHORT].pkt_size = MVPP2_BM_SHORT_PKT_SIZE; ^~~~~~~~~~~~~~~~~~~~~~~ Completed OK # rm -rf /kisskb/build/linus_s390-allmodconfig_s390x-gcc8 # Build took: 0:09:20.458639