# 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/fe-x86-64-core-i7-2017.05/bin/x86_64-linux-gcc --version # < /opt/cross/kisskb/fe-x86-64-core-i7-2017.05/bin/x86_64-linux-ld --version # < git log --format=%s --max-count=1 0be0ee71816b2b6725e2b4f32ad6726c9d729777 # < make -s -j 32 ARCH=um O=/kisskb/build/linus_um-allmodconfig_um-x86_64 CROSS_COMPILE=/opt/cross/kisskb/fe-x86-64-core-i7-2017.05/bin/x86_64-linux- SUBARCH=x86_64 allmodconfig # Added to kconfig CONFIG_STANDALONE=y # Added to kconfig CONFIG_KCOV=n # Added to kconfig CONFIG_GCC_PLUGINS=n # Added to kconfig CONFIG_GCC_PLUGIN_CYC_COMPLEXITY=n # Added to kconfig CONFIG_GCC_PLUGIN_SANCOV=n # Added to kconfig CONFIG_GCC_PLUGIN_LATENT_ENTROPY=n # Added to kconfig CONFIG_GCC_PLUGIN_STRUCTLEAK=n # Added to kconfig CONFIG_GCC_PLUGIN_RANDSTRUCT=n # Added to kconfig CONFIG_UML_NET=n # Added to kconfig CONFIG_UML_NET_ETHERTAP=n # Added to kconfig CONFIG_UML_NET_TUNTAP=n # Added to kconfig CONFIG_UML_NET_SLIP=n # Added to kconfig CONFIG_UML_NET_DAEMON=n # Added to kconfig CONFIG_UML_NET_VDE=n # Added to kconfig CONFIG_UML_NET_MCAST=n # Added to kconfig CONFIG_UML_NET_PCAP=n # Added to kconfig CONFIG_UML_NET_SLIRP=n # Added to kconfig CONFIG_GCOV_KERNEL=n # yes \n | make -s -j 32 ARCH=um O=/kisskb/build/linus_um-allmodconfig_um-x86_64 CROSS_COMPILE=/opt/cross/kisskb/fe-x86-64-core-i7-2017.05/bin/x86_64-linux- SUBARCH=x86_64 oldconfig yes: standard output: Broken pipe # make -s -j 32 ARCH=um O=/kisskb/build/linus_um-allmodconfig_um-x86_64 CROSS_COMPILE=/opt/cross/kisskb/fe-x86-64-core-i7-2017.05/bin/x86_64-linux- SUBARCH=x86_64 /kisskb/src/arch/um/os-Linux/signal.c: In function 'sig_handler_common': /kisskb/src/arch/um/os-Linux/signal.c:51:1: warning: the frame size of 2976 bytes is larger than 2048 bytes [-Wframe-larger-than=] } ^ /kisskb/src/arch/um/os-Linux/signal.c: In function 'timer_real_alarm_handler': /kisskb/src/arch/um/os-Linux/signal.c:95:1: warning: the frame size of 2960 bytes is larger than 2048 bytes [-Wframe-larger-than=] } ^ /kisskb/src/security/apparmor/policy_unpack.c: In function 'unpack_profile': /kisskb/src/security/apparmor/policy_unpack.c:523:9: warning: 'pos' may be used uninitialized in this function [-Wmaybe-uninitialized] str[pos] = ':'; ^ /kisskb/src/security/apparmor/policy_unpack.c:494:14: note: 'pos' was declared here int c, j, pos, size2 = unpack_strdup(e, &str, NULL); ^ /kisskb/src/lib/lz4/lz4hc_compress.c: In function 'LZ4HC_compress_generic': /kisskb/src/lib/lz4/lz4hc_compress.c:579:1: warning: the frame size of 2144 bytes is larger than 2048 bytes [-Wframe-larger-than=] } ^ /kisskb/src/drivers/misc/lkdtm/bugs.c: In function 'lkdtm_UNSET_SMEP': /kisskb/src/drivers/misc/lkdtm/bugs.c:284:8: error: implicit declaration of function 'native_read_cr4' [-Werror=implicit-function-declaration] cr4 = native_read_cr4(); ^ /kisskb/src/drivers/misc/lkdtm/bugs.c:286:13: error: 'X86_CR4_SMEP' undeclared (first use in this function) if ((cr4 & X86_CR4_SMEP) != X86_CR4_SMEP) { ^ /kisskb/src/drivers/misc/lkdtm/bugs.c:286:13: note: each undeclared identifier is reported only once for each function it appears in /kisskb/src/drivers/misc/lkdtm/bugs.c:293:2: error: implicit declaration of function 'native_write_cr4' [-Werror=implicit-function-declaration] native_write_cr4(cr4); ^ cc1: some warnings being treated as errors make[4]: *** [/kisskb/src/scripts/Makefile.build:265: drivers/misc/lkdtm/bugs.o] Error 1 make[3]: *** [/kisskb/src/scripts/Makefile.build:509: drivers/misc/lkdtm] Error 2 make[2]: *** [/kisskb/src/scripts/Makefile.build:509: drivers/misc] Error 2 make[2]: *** Waiting for unfinished jobs.... make[1]: *** [/kisskb/src/Makefile:1652: drivers] Error 2 make[1]: *** Waiting for unfinished jobs.... make: *** [Makefile:179: sub-make] Error 2 Command 'make -s -j 32 ARCH=um O=/kisskb/build/linus_um-allmodconfig_um-x86_64 CROSS_COMPILE=/opt/cross/kisskb/fe-x86-64-core-i7-2017.05/bin/x86_64-linux- SUBARCH=x86_64 ' returned non-zero exit status 2 # rm -rf /kisskb/build/linus_um-allmodconfig_um-x86_64 # Build took: 0:05:57.200369