# git rev-parse -q --verify 0cc3b0ec23ce4c69e1e890ed2b8d2fa932b14aad^{commit} 0cc3b0ec23ce4c69e1e890ed2b8d2fa932b14aad already have revision, skipping fetch # git checkout -q -f -B kisskb 0cc3b0ec23ce4c69e1e890ed2b8d2fa932b14aad # git clean -qxdf # git log -1 commit 0cc3b0ec23ce4c69e1e890ed2b8d2fa932b14aad Author: Linus Torvalds Date: Sun Aug 27 12:12:25 2017 -0700 Clarify (and fix) MAX_LFS_FILESIZE macros We have a MAX_LFS_FILESIZE macro that is meant to be filled in by filesystems (and other IO targets) that know they are 64-bit clean and don't have any 32-bit limits in their IO path. It turns out that our 32-bit value for that limit was bogus. On 32-bit, the VM layer is limited by the page cache to only 32-bit index values, but our logic for that was confusing and actually wrong. We used to define that value to (((loff_t)PAGE_SIZE << (BITS_PER_LONG-1))-1) which is actually odd in several ways: it limits the index to 31 bits, and then it limits files so that they can't have data in that last byte of a page that has the highest 31-bit index (ie page index 0x7fffffff). Neither of those limitations make sense. The index is actually the full 32 bit unsigned value, and we can use that whole full page. So the maximum size of the file would logically be "PAGE_SIZE << BITS_PER_LONG". However, we do wan tto avoid the maximum index, because we have code that iterates over the page indexes, and we don't want that code to overflow. So the maximum size of a file on a 32-bit host should actually be one page less than the full 32-bit index. So the actual limit is ULONG_MAX << PAGE_SHIFT. That means that we will not actually be using the page of that last index (ULONG_MAX), but we can grow a file up to that limit. The wrong value of MAX_LFS_FILESIZE actually caused problems for Doug Nazar, who was still using a 32-bit host, but with a 9.7TB 2 x RAID5 volume. It turns out that our old MAX_LFS_FILESIZE was 8TiB (well, one byte less), but the actual true VM limit is one page less than 16TiB. This was invisible until commit c2a9737f45e2 ("vfs,mm: fix a dead loop in truncate_inode_pages_range()"), which started applying that MAX_LFS_FILESIZE limit to block devices too. NOTE! On 64-bit, the page index isn't a limiter at all, and the limit is actually just the offset type itself (loff_t), which is signed. But for clarity, on 64-bit, just use the maximum signed value, and don't make people have to count the number of 'f' characters in the hex constant. So just use LLONG_MAX for the 64-bit case. That was what the value had been before too, just written out as a hex constant. Fixes: c2a9737f45e2 ("vfs,mm: fix a dead loop in truncate_inode_pages_range()") Reported-and-tested-by: Doug Nazar Cc: Andreas Dilger Cc: Mark Fasheh Cc: Joel Becker Cc: Dave Kleikamp Cc: stable@kernel.org Signed-off-by: Linus Torvalds # < /opt/cross/kisskb/gcc-4.6.3-nolibc/um-x86_64-linux/bin/x86_64-linux-gcc --version # < git log --format=%s --max-count=1 0cc3b0ec23ce4c69e1e890ed2b8d2fa932b14aad # < make -j 48 ARCH=um O=/home/kisskb/slave/build/linus_um-defconfig_um-x86_64 CROSS_COMPILE=/opt/cross/kisskb/gcc-4.6.3-nolibc/um-x86_64-linux/bin/x86_64-linux- SUBARCH=x86_64 defconfig # make -j 48 ARCH=um O=/home/kisskb/slave/build/linus_um-defconfig_um-x86_64 CROSS_COMPILE=/opt/cross/kisskb/gcc-4.6.3-nolibc/um-x86_64-linux/bin/x86_64-linux- SUBARCH=x86_64 make[1]: Entering directory '/home/kisskb/slave/build/linus_um-defconfig_um-x86_64' GEN ./Makefile scripts/kconfig/conf --silentoldconfig arch/x86/um/Kconfig CHK include/generated/uapi/linux/version.h UPD include/generated/uapi/linux/version.h HOSTCC scripts/basic/bin2c CHK include/config/kernel.release GEN ./Makefile WRAP arch/um/include/generated/asm/barrier.h WRAP arch/um/include/generated/asm/current.h WRAP arch/um/include/generated/asm/device.h WRAP arch/um/include/generated/asm/exec.h WRAP arch/um/include/generated/asm/extable.h WRAP arch/um/include/generated/asm/ftrace.h WRAP arch/um/include/generated/asm/futex.h WRAP arch/um/include/generated/asm/hardirq.h WRAP arch/um/include/generated/asm/hw_irq.h WRAP arch/um/include/generated/asm/io.h WRAP arch/um/include/generated/asm/irq_regs.h WRAP arch/um/include/generated/asm/irq_work.h WRAP arch/um/include/generated/asm/kdebug.h WRAP arch/um/include/generated/asm/mcs_spinlock.h WRAP arch/um/include/generated/asm/clkdev.h WRAP arch/um/include/generated/asm/delay.h WRAP arch/um/include/generated/asm/bug.h WRAP arch/um/include/generated/asm/param.h WRAP arch/um/include/generated/asm/emergency-restart.h WRAP arch/um/include/generated/asm/mm-arch-hooks.h WRAP arch/um/include/generated/asm/pci.h WRAP arch/um/include/generated/asm/percpu.h WRAP arch/um/include/generated/asm/preempt.h WRAP arch/um/include/generated/asm/switch_to.h WRAP arch/um/include/generated/asm/topology.h WRAP arch/um/include/generated/asm/trace_clock.h WRAP arch/um/include/generated/asm/word-at-a-time.h WRAP arch/um/include/generated/asm/xor.h WRAP arch/um/include/generated/asm/kprobes.h UPD include/config/kernel.release Using /home/kisskb/slave/src as source for kernel CHK include/generated/utsrelease.h UPD include/generated/utsrelease.h HOSTCC scripts/kallsyms CC scripts/mod/empty.o HOSTCC scripts/mod/mk_elfconfig CC scripts/mod/devicetable-offsets.s CHK scripts/mod/devicetable-offsets.h UPD scripts/mod/devicetable-offsets.h MKELF scripts/mod/elfconfig.h HOSTCC scripts/mod/modpost.o HOSTCC scripts/mod/file2alias.o HOSTCC scripts/mod/sumversion.o SYSTBL arch/x86/entry/syscalls/../../include/generated/asm/syscalls_32.h SYSHDR arch/x86/entry/syscalls/../../include/generated/asm/unistd_32_ia32.h SYSHDR arch/x86/entry/syscalls/../../include/generated/asm/unistd_64_x32.h SYSTBL arch/x86/entry/syscalls/../../include/generated/asm/syscalls_64.h SYSHDR arch/x86/entry/syscalls/../../include/generated/uapi/asm/unistd_x32.h SYSHDR arch/x86/entry/syscalls/../../include/generated/uapi/asm/unistd_64.h SYSHDR arch/x86/entry/syscalls/../../include/generated/uapi/asm/unistd_32.h HOSTLD scripts/mod/modpost HOSTCC scripts/unifdef CC arch/x86/um/user-offsets.s In file included from /usr/include/features.h:374:0, from /usr/include/stdio.h:27, from /home/kisskb/slave/src/arch/x86/um/user-offsets.c:1: /opt/cross/gcc-4.6.3-nolibc/x86_64-linux/lib/gcc/x86_64-linux/4.6.3/../../../../x86_64-linux/include/sys/cdefs.h:385:27: fatal error: bits/wordsize.h: No such file or directory compilation terminated. /home/kisskb/slave/src/scripts/Makefile.build:154: recipe for target 'arch/x86/um/user-offsets.s' failed make[2]: *** [arch/x86/um/user-offsets.s] Error 1 arch/um/Makefile:154: recipe for target 'arch/x86/um/user-offsets.s' failed make[1]: *** [arch/x86/um/user-offsets.s] Error 2 make[1]: Leaving directory '/home/kisskb/slave/build/linus_um-defconfig_um-x86_64' Makefile:145: recipe for target 'sub-make' failed make: *** [sub-make] Error 2 Command 'make -j 48 ARCH=um O=/home/kisskb/slave/build/linus_um-defconfig_um-x86_64 CROSS_COMPILE=/opt/cross/kisskb/gcc-4.6.3-nolibc/um-x86_64-linux/bin/x86_64-linux- SUBARCH=x86_64 ' returned non-zero exit status 2 # rm -rf /home/kisskb/slave/build/linus_um-defconfig_um-x86_64 # Build took: 0:00:06.743680