ignatenkobrain / rpms / kernel

Forked from rpms/kernel 4 years ago
Clone
e293be
commit 0cc3b0ec23ce4c69e1e890ed2b8d2fa932b14aad
e293be
Author: Linus Torvalds <torvalds@linux-foundation.org>
e293be
Date:   Sun Aug 27 12:12:25 2017 -0700
e293be
e293be
    Clarify (and fix) MAX_LFS_FILESIZE macros
e293be
    
e293be
    We have a MAX_LFS_FILESIZE macro that is meant to be filled in by
e293be
    filesystems (and other IO targets) that know they are 64-bit clean and
e293be
    don't have any 32-bit limits in their IO path.
e293be
    
e293be
    It turns out that our 32-bit value for that limit was bogus.  On 32-bit,
e293be
    the VM layer is limited by the page cache to only 32-bit index values,
e293be
    but our logic for that was confusing and actually wrong.  We used to
e293be
    define that value to
e293be
    
e293be
    	(((loff_t)PAGE_SIZE << (BITS_PER_LONG-1))-1)
e293be
    
e293be
    which is actually odd in several ways: it limits the index to 31 bits,
e293be
    and then it limits files so that they can't have data in that last byte
e293be
    of a page that has the highest 31-bit index (ie page index 0x7fffffff).
e293be
    
e293be
    Neither of those limitations make sense.  The index is actually the full
e293be
    32 bit unsigned value, and we can use that whole full page.  So the
e293be
    maximum size of the file would logically be "PAGE_SIZE << BITS_PER_LONG".
e293be
    
e293be
    However, we do wan tto avoid the maximum index, because we have code
e293be
    that iterates over the page indexes, and we don't want that code to
e293be
    overflow.  So the maximum size of a file on a 32-bit host should
e293be
    actually be one page less than the full 32-bit index.
e293be
    
e293be
    So the actual limit is ULONG_MAX << PAGE_SHIFT.  That means that we will
e293be
    not actually be using the page of that last index (ULONG_MAX), but we
e293be
    can grow a file up to that limit.
e293be
    
e293be
    The wrong value of MAX_LFS_FILESIZE actually caused problems for Doug
e293be
    Nazar, who was still using a 32-bit host, but with a 9.7TB 2 x RAID5
e293be
    volume.  It turns out that our old MAX_LFS_FILESIZE was 8TiB (well, one
e293be
    byte less), but the actual true VM limit is one page less than 16TiB.
e293be
    
e293be
    This was invisible until commit c2a9737f45e2 ("vfs,mm: fix a dead loop
e293be
    in truncate_inode_pages_range()"), which started applying that
e293be
    MAX_LFS_FILESIZE limit to block devices too.
e293be
    
e293be
    NOTE! On 64-bit, the page index isn't a limiter at all, and the limit is
e293be
    actually just the offset type itself (loff_t), which is signed.  But for
e293be
    clarity, on 64-bit, just use the maximum signed value, and don't make
e293be
    people have to count the number of 'f' characters in the hex constant.
e293be
    
e293be
    So just use LLONG_MAX for the 64-bit case.  That was what the value had
e293be
    been before too, just written out as a hex constant.
e293be
    
e293be
    Fixes: c2a9737f45e2 ("vfs,mm: fix a dead loop in truncate_inode_pages_range()")
e293be
    Reported-and-tested-by: Doug Nazar <nazard@nazar.ca>
e293be
    Cc: Andreas Dilger <adilger@dilger.ca>
e293be
    Cc: Mark Fasheh <mfasheh@versity.com>
e293be
    Cc: Joel Becker <jlbec@evilplan.org>
e293be
    Cc: Dave Kleikamp <shaggy@kernel.org>
e293be
    Cc: stable@kernel.org
e293be
    Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
e293be
e293be
Ported to kernel-3.10.0-862.el7 by T.Kabe
e293be
diff -up ./include/linux/fs.h.pcs ./include/linux/fs.h
e293be
--- ./include/linux/fs.h.pcs	2018-04-18 14:53:21.000000000 +0900
e293be
+++ ./include/linux/fs.h	2018-04-18 14:55:36.000000000 +0900
e293be
@@ -989,9 +989,9 @@ static inline int file_check_writeable(s
e293be
 /* Page cache limit. The filesystems should put that into their s_maxbytes 
e293be
    limits, otherwise bad things can happen in VM. */ 
e293be
 #if BITS_PER_LONG==32
e293be
-#define MAX_LFS_FILESIZE	(((loff_t)PAGE_CACHE_SIZE << (BITS_PER_LONG-1))-1) 
e293be
+#define MAX_LFS_FILESIZE	((loff_t)ULONG_MAX << PAGE_SHIFT)
e293be
 #elif BITS_PER_LONG==64
e293be
-#define MAX_LFS_FILESIZE 	((loff_t)0x7fffffffffffffffLL)
e293be
+#define MAX_LFS_FILESIZE 	((loff_t)LLONG_MAX)
e293be
 #endif
e293be
 
e293be
 #define FL_POSIX	1